Xây dựng một cái lọ có thể chạy được với Maven 2


82

Tôi còn khá mới đối với câu thần chú Maven, nhưng tôi đang cố gắng xây dựng một lọ có thể chạy được bằng dòng lệnh với Maven. Tôi đã thiết lập các phụ thuộc của mình, nhưng khi tôi chạy mvn installvà cố gắng chạy jar, hai điều xảy ra. Đầu tiên, không tìm thấy lớp chính nào, điều này có thể sửa được. Khi tôi sửa lỗi này, tôi gặp lỗi khi chạy rằng không thể tìm thấy các lớp.

Maven không đóng gói các thư viện phụ thuộc của tôi bên trong jar, vì vậy tôi không thể chạy jar như một ứng dụng độc lập. Làm cách nào để sửa lỗi này?


Bạn có thể sử dụng IDE cho maven như Netbenas
Sajad Bahmani

7
@SjB: và điều đó giải quyết vấn đề một cách kỳ diệu? Tôi không nghĩ vậy.
Joachim Sauer

1
Bản sao chính xác của những gì, chính xác?
Stefan Kendall

Có thể câu hỏi này là stackoverflow.com/questions/1832853/… hoặc stackoverflow.com/questions/574594/… (nhưng câu trả lời được chấp nhận là sai), hoặc stackoverflow.com/questions/1814526/… . Trên thực tế, điều này có vẻ là một trong những câu hỏi thường gặp nhất trên maven ...
Pascal Thivent

1
Các câu trả lời khác không rõ ràng và uber jar (ueber viết sai chính tả), không đề cập đến khả năng thực thi. Bên cạnh đó, các chủ đề khác được rải rác với các tài liệu không liên quan, chẳng hạn như cấp nguồn, vv
Stefan Kendall

Câu trả lời:


113

Cách dễ nhất để làm điều này là tạo một hợp ngữ bằng cách sử dụng maven-assembly-pluginvà bộ jar-with-dependenciesmô tả được xác định trước . Bạn cũng sẽ cần tạo một tệp kê khai với mục nhập lớp chính cho jar uber này. Đoạn mã dưới đây cho thấy cách định cấu hình plugin lắp ráp để làm như vậy:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>

Sau đó, để tạo assembly, chỉ cần chạy:

mvn assembly:assembly

Nếu bạn muốn tạo assembly như một phần của bản dựng của mình, chỉ cần liên kết assembly:singlemojo với giai đoạn gói:

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
      </configuration>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Và chỉ cần chạy:

mvn package

1
Maven-shadow-plugin cũng hoạt động tương tự và dành riêng cho mục đích này.
Dominic Mitchell

4
Điều này không hoạt động đối với mùa xuân và các thư viện khác mong đợi nhiều tài nguyên có cùng tên trên đường dẫn lớp. Trong trường hợp của mùa xuân, META-INF \ spring.schemas được bao gồm trong một số lọ (bean, jdbc, v.v.) và được sử dụng để định cấu hình hỗ trợ không gian tên XML cho trình phân tích cú pháp XML. Nếu bạn thử 'jar-with-dependencies', cách viết hoa application-context.xml sẽ không thành công trong thời gian chạy với một cái gì đó như "org.xml.sax.SAXParseException: cvc-elt.1: Không thể tìm thấy khai báo của phần tử 'bean'."
David Roussel

@David Maven sẽ không giải quyết "giới hạn" của Java. Chỉ cần đóng gói ứng dụng của bạn một cách sạch sẽ (tức là không nằm trong uberjar) trong trường hợp đó.
Pascal Thivent

Điều này hoạt động với cấu hình Spring mà không có vấn đề gì. Lớp chính của tôi tải tất cả các lớp khác với ngữ cảnh Ứng dụng Classpath và giải pháp này hoạt động hoàn hảo.
vsingh

2
Các assembly:assemblymục tiêu được phản
Jared Beck

25

Maven không đóng gói các phần phụ thuộc của bạn bên trong tệp jar của bạn, bởi vì bạn không thường làm điều này với các chương trình Java.

Thay vào đó bạn cung cấp những phụ thuộc cùng với file jar của bạn và đề cập đến chúng trong các Class-Pathtiêu đề của Manifest .

Để đi theo con đường này, bạn sẽ cần phải kích hoạt thuộc addClasspathtính (được nêu ở đây ) cho maven-jar-plugin.

Nếu bạn thực sự muốn bao gồm tất cả các phụ thuộc của mình trong tệp jar của mình, thì bạn có thể sử dụng plugin Maven Assembly để tạo jar-with-dependencies.


4
+1 Tôi đã gặp khó khăn khi tìm kiếm thông tin về cách các chương trình java thường được thiết kế để xây dựng và phân phối, đặc biệt là với Maven.
Ed Brannin

8

Đây là những gì tôi sẽ làm cho các dự án nhỏ. Hầu hết thời gian bạn không muốn có một cái lọ lớn.

để xây dựng: mvn clean dependency: gói copy-dependencies

để thực thi ( trong target dir ): java -cp myjar.jar: ./ dependency / * com.something.MyClass


Tuyệt quá! Tôi đã lưu nó trong Makefile của mình, trong cùng một thư mục với pom.xml. xây dựng: \ n mvn .... (bạn đã nói gì)
Roboprog

Cảm ơn. Sau khi tìm kiếm Internet cho hơn 2 giờ tìm thấy câu trả lời này rất hữu ích ....
Shekhar

6

Tôi đồng ý với Joachim Sauer,

Thay vì sử dụng jar-with-dependency, bạn nên định cấu hình plugin jar như thế trong pom.xml của bạn:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <index>true</index>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>[mainClassFullName]</mainClass>
            </manifest>
            <manifestEntries>
                <mode>development</mode>
                <url>${project.url}</url>
                <key>value</key>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

Và sử dụng cấu hình assembly này để thêm các phụ thuộc jar vào assembly của bạn:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>zip-with-jars</id>
  <formats>
    <format>zip</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySets>
    <dependencySet>
    <outputDirectory>/</outputDirectory>
    <useProjectArtifact>true</useProjectArtifact>
    <unpack>false</unpack>
    <scope>runtime</scope>
    </dependencySet>
</dependencySets>
  </dependencySets>
</assembly>

2

Chỉ cần thêm đoạn mã dưới đây vào pom.xml và Run as: maven: install. Jar sẽ được tạo trong thư mục đích của eclipse có thể được sử dụng như "java -jar Hello.jar". nhưng hãy đảm bảo rằng tên của lớp chính được cung cấp com.abc.HelloWorld.java

<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-shade-plugin</artifactid>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalname>HelloW</finalname>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestentries>
<main-class>com.abc.HelloWorld.java</main-class>
<build-number>1</build-number>
</manifestentries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

</build>
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.