Xây dựng jar thực thi với maven?


122

Tôi đang cố gắng tạo một jar thực thi cho một dự án gia đình nhỏ được gọi là "logmanager" bằng maven, giống như sau:

Làm cách nào để tạo một JAR có thể thực thi với các phụ thuộc bằng Maven?

Tôi đã thêm đoạn mã được hiển thị ở đó vào pom.xml và chạy mvn assembly: assembly. Nó tạo ra hai tệp jar trong logmanager / target: logmanager-0.1.0.jar và logmanager-0.1.0-jar-with-dependencies.jar. Tôi gặp lỗi khi nhấp đúp vào bình đầu tiên:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Một lỗi hơi khác khi tôi bấm đúp vào jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Tôi đã sao chép và dán đường dẫn và tên lớp, đồng thời kiểm tra chính tả trong POM. Lớp chính của tôi khởi chạy tốt từ cấu hình khởi chạy nhật thực. Ai đó có thể giúp tôi tìm ra lý do tại sao tệp jar của tôi không chạy không? Ngoài ra, tại sao lại có hai cái lọ để bắt đầu? Hay noi tôi nêu bạn cân thêm thông tin.

Đây là đầy đủ pom.xml, để tham khảo:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>

Câu trả lời:


244

Trên thực tế, tôi nghĩ rằng câu trả lời được đưa ra trong câu hỏi bạn đề cập chỉ là sai ( CẬP NHẬT - 20101106: ai đó đã sửa nó, câu trả lời này đề cập đến phiên bản trước bản chỉnh sửa ) và điều này giải thích, ít nhất một phần, tại sao bạn gặp rắc rối.


Nó tạo ra hai tệp jar trong logmanager / target: logmanager-0.1.0.jar và logmanager-0.1.0-jar-with-dependencies.jar.

Cái đầu tiên là JAR của mô-đun logmanager được tạo ra trong packagegiai đoạn bởi jar:jar(vì mô-đun có kiểu đóng gói jar). Cái thứ hai là hợp ngữ được tạo bởi assembly:assemblyvà nên chứa các lớp từ mô-đun hiện tại và các phụ thuộc của nó (nếu bạn đã sử dụng bộ mô tả jar-with-dependencies).

Tôi gặp lỗi khi nhấp đúp vào bình đầu tiên:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

Nếu bạn đã áp dụng cấu hình đề xuất của liên kết được đăng dưới dạng tham chiếu, bạn đã định cấu hình plugin jar để tạo ra một cấu phần thực thi, giống như sau:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

Vì vậy, logmanager-0.1.0.jarthực sự là thực thi nhưng 1. đây không phải là điều bạn muốn (vì nó không có tất cả các phụ thuộc) và 2. nó không chứa com.gorkwobble.logmanager.LogManager(đây là lỗi đang nói, hãy kiểm tra nội dung của jar).

Một lỗi hơi khác khi tôi bấm đúp vào jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Một lần nữa, nếu bạn đã định cấu hình plugin lắp ráp như được đề xuất, bạn có một cái gì đó như sau:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

Với thiết lập này, logmanager-0.1.0-jar-with-dependencies.jarchứa các lớp từ mô-đun hiện tại các phụ thuộc của nó, nhưng theo lỗi, nó META-INF/MANIFEST.MF không chứa Main-Classmục nhập (có thể nó không giống MANIFEST.MF như trong logmanager-0.1.0.jar). Bình thực sự không thể thực thi, một lần nữa nó không phải là những gì bạn muốn.


Vì vậy, đề xuất của tôi sẽ là xóa configurationphần tử khỏi plugin maven-jar-và định cấu hình maven-assembly-plugin như sau:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Tất nhiên, thay thế org.sample.Appbằng lớp bạn muốn thực thi. Phần thưởng nhỏ, tôi đã assembly:singleđến packagegiai đoạn để bạn không phải chạy assembly:assemblynữa. Chỉ cần chạy mvn installvà lắp ráp sẽ được sản xuất trong quá trình xây dựng tiêu chuẩn.

Vì vậy, hãy cập nhật pom.xml của bạn với cấu hình được đưa ra ở trên và chạy mvn clean install. Sau đó, cd vào targetthư mục và thử lại:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

Nếu bạn gặp lỗi, vui lòng cập nhật câu hỏi của bạn với nó và đăng nội dung của META-INF/MANIFEST.MFtệp và phần có liên quan của bạn pom.xml(phần cấu hình plugin). Cũng xin vui lòng đăng kết quả của:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

để chứng minh nó hoạt động tốt trên dòng lệnh (bất kể nhật thực đang nói gì).

CHỈNH SỬA: Đối với Java 6, bạn cần phải định cấu hình maven-compiler-plugin. Thêm cái này vào pom.xml của bạn:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>

4
Cảm ơn ý kiến ​​của bạn! Tôi đã thay đổi pom.xml của mình như bạn đã chỉ định. Khi tôi chạy bản cài đặt sạch mvn, tôi nhận được một loạt lỗi biên dịch từ mã của mình, nói rằng chú thích, v.v. không được hỗ trợ trong -source 1.3. Tôi đang sử dụng jdk1.6 và nó biên dịch trong nhật thực; Tôi không chắc 1.3 đã được giới thiệu như thế nào. Có thể một trong những phiên bản thư viện trong đoạn mã pom là phiên bản cũ hơn?
RMorrisey

Cảm ơn! Tôi đã vượt qua vấn đề 1.3. Tôi cũng phải thêm phụ thuộc junit4 vào POM của mình. Tôi đang làm việc để gỡ rối những thứ khác; nếu tôi gặp khó khăn, tôi sẽ đăng lại! Nếu tôi nhận được bình chạy, tôi sẽ đánh dấu đây là câu trả lời. POM hiện tại của tôi được cập nhật trong câu hỏi trên.
RMorrisey

Có cách nào để loại trừ các tài nguyên khỏi tệp jar được tạo không?

2
Có thể có jar kết quả để có một tên "bình thường"?
Daniil Sheboardsv

1
Tôi cũng thấy điều này Sonatype blog post hữu ích

15

Câu trả lời của Pascal Thivent cũng giúp tôi. Nhưng nếu bạn quản lý các plugin của mình trong <pluginManagement>phần tử, bạn phải xác định lại assembly bên ngoài quản lý plugin, nếu không các phần phụ thuộc không được đóng gói trong jar nếu bạn chạy mvn install.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>

1
Cảm ơn Mike, Nó đã giúp tôi. Ban đầu gói của tôi được tạo mà không sử dụng <pluginManagement>. Nhưng Eclipse đã đưa ra một số lỗi trong pom.xml "maven - Thực thi plugin không nằm trong vòng đời". Làm tôi phân tâm. Vì vậy, để giải quyết vấn đề này, tôi đã thêm <pluginManagement>, hiện tại lỗi eclipse đã biến mất nhưng gói của tôi đã ngừng được xây dựng. Đoạn mã pom ở trên của bạn đã làm việc cho tôi. :)
shashaDenovo

2
Điều này rất hữu ích .. trong khi sử dụng <pluginManagement>, câu trả lời hàng đầu sẽ không hoạt động.
ininprsr

5

Nếu bạn không muốn thực thi mục tiêu hợp ngữ trên gói, bạn có thể sử dụng lệnh tiếp theo:

mvn package assembly:single

Đây là gói từ khóa.


-1

Nhấp chuột phải vào dự án và cung cấp cho maven build, maven clean, maven tạo tài nguyên và cài đặt maven. Tệp jar sẽ tự động tạo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.