Tôi muốn gói dự án của mình trong một JAR thực thi duy nhất để phân phối.
Làm cách nào tôi có thể tạo gói dự án Maven tất cả các JAR phụ thuộc vào JAR đầu ra của mình?
Tôi muốn gói dự án của mình trong một JAR thực thi duy nhất để phân phối.
Làm cách nào tôi có thể tạo gói dự án Maven tất cả các JAR phụ thuộc vào JAR đầu ra của mình?
Câu trả lời:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
và bạn chạy nó với
mvn clean compile assembly:single
Mục tiêu biên dịch nên được thêm vào trước khi lắp ráp: không bao gồm mã hoặc dự án riêng của bạn.
Xem thêm chi tiết trong ý kiến.
Thông thường mục tiêu này được gắn với một giai đoạn xây dựng để thực hiện tự động. Điều này đảm bảo JAR được xây dựng khi thực hiện mvn install
hoặc thực hiện triển khai / phát hành.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
mvn clean compile assembly:single
.
<appendAssemblyId>false</appendAssemblyId>
vào configuration
để tránh hậu tố "
compile
và bạn đang say sưa.
Bạn có thể sử dụng plugin phụ thuộc để tạo tất cả các phụ thuộc trong một thư mục riêng trước giai đoạn gói và sau đó đưa nó vào đường dẫn lớp của tệp kê khai:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>theMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Hoặc sử dụng ${project.build.directory}/classes/lib
như OutputDirectory để tích hợp tất cả các tệp jar vào tệp chính, nhưng sau đó bạn sẽ cần thêm mã tải lớp tùy chỉnh để tải các tệp.
${project.build.directory}/classes/lib
như outputDirectory
để có một .jar chính với tất cả các phụ thuộc bên trong, nhưng - Làm cách nào để thêm mã tải lớp tùy chỉnh để tải tệp này? Tôi cần phải thực hiện công việc như : java -jar main-jar-with-deps.jar
. Điều này có thể không?
Tôi viết blog về một số cách khác nhau để làm điều này.
Xem Jar thực thi với Apache Maven (WordPress)
hoặc thực thi-jar-with-maven-example (GitHub)
Những ưu và nhược điểm được cung cấp bởi Stephan .
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
<mainClass>${fully.qualified.main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Tại thời điểm jar
này, thực sự có thể thực thi được với các phần tử classpath bên ngoài.
$ java -jar target/${project.build.finalName}.jar
Các jar
tập tin chỉ được thực thi với ...lib/
thư mục anh chị em . Chúng ta cần lưu trữ để triển khai với thư mục và nội dung của nó.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>antrun-archive</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
<property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
<property name="tar.destfile" value="${final.name}.tar"/>
<zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
<tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
<gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
<bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
</target>
</configuration>
</execution>
</executions>
</plugin>
Bây giờ bạn có target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
cái nào chứa jar
và lib/*
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>${fully.qualified.main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Bạn có target/${project.bulid.finalName}-jar-with-dependencies.jar
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${fully.qualified.main.class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Bạn có target/${project.build.finalName}-shaded.jar
.
<plugin>
<!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>${fully.qualified.main.class}</mainClass>
<attachToBuild>true</attachToBuild>
<!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
<!--classifier>onejar</classifier-->
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>${fully.qualified.main.class}</mainClass>
</configuration>
</execution>
</executions>
</plugin>
Bạn có target/${project.bulid.finalName}-spring-boot.jar
.
Lấy câu trả lời chưa được trả lời và định dạng lại nó, chúng ta có:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
Tiếp theo, tôi khuyên bạn nên biến điều này thành một phần tự nhiên trong bản dựng của bạn, thay vì gọi một cách rõ ràng. Để biến điều này thành một phần không thể thiếu trong bản dựng của bạn, hãy thêm plugin này vào của bạn pom.xml
và liên kết nó với package
sự kiện vòng đời. Tuy nhiên, một vấn đề khó khăn là bạn cần gọi assembly:single
mục tiêu nếu đặt mục tiêu này vào tệp pom.xml của bạn, trong khi bạn sẽ gọi 'assembly: assembly' nếu thực hiện thủ công từ dòng lệnh.
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
[...]
</plugins>
[...]
</build>
</project>
Sử dụng maven-bóng-plugin để đóng gói tất cả các phụ thuộc vào một uber-jar. Nó cũng có thể được sử dụng để xây dựng một jar thực thi bằng cách chỉ định lớp chính. Sau khi thử sử dụng maven-assembly và maven-jar, tôi thấy rằng plugin này phù hợp nhất với nhu cầu của tôi.
Tôi thấy plugin này đặc biệt hữu ích vì nó hợp nhất nội dung của các tệp cụ thể thay vì ghi đè lên chúng. Điều này là cần thiết khi có các tệp tài nguyên có cùng tên trên các tệp và plugin cố gắng đóng gói tất cả các tệp tài nguyên
Xem ví dụ dưới đây
<plugins>
<!-- This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<!-- signed jars-->
<excludes>
<exclude>bouncycastle:bcprov-jdk15</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<!-- Main class -->
<mainClass>com.main.MyMainClass</mainClass>
</transformer>
<!-- Use resource transformers to prevent file overwrites -->
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>properties.properties</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>applicationContext.xml</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/cxf/cxf.extension</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>META-INF/cxf/bus-extensions.xml</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Long đã sử dụng plugin lắp ráp maven , nhưng tôi không thể tìm ra giải pháp cho vấn đề này "already added, skipping"
. Bây giờ, tôi đang sử dụng một plugin khác - onejar-maven-plugin . Ví dụ dưới đây ( mvn package
xây dựng jar):
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<configuration>
<mainClass>com.company.MainClass</mainClass>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Bạn cần thêm kho lưu trữ cho plugin đó:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
Bạn có thể sử dụng maven-lệ thuộc-plugin, nhưng câu hỏi là làm thế nào để tạo một JAR thực thi. Để làm điều đó đòi hỏi phải có sự thay đổi sau đây đối với phản hồi của Matthew Franglen (btw, sử dụng plugin phụ thuộc mất nhiều thời gian hơn để xây dựng khi bắt đầu từ mục tiêu sạch):
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/target/dependency</directory>
</resource>
</resources>
</build>
Bạn có thể sử dụng plugin maven-bóng để xây dựng một uber jar như bên dưới
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Một tùy chọn khác nếu bạn thực sự muốn đóng gói lại các nội dung JAR khác bên trong JAR kết quả duy nhất của bạn là plugin Maven hội . Nó giải nén và sau đó đóng gói lại mọi thứ vào một thư mục thông qua <unpack>true</unpack>
. Sau đó, bạn sẽ có một đường chuyền thứ hai xây dựng nó thành một JAR lớn.
Một tùy chọn khác là plugin OneJar . Điều này thực hiện tất cả các hành động đóng gói lại ở trên trong một bước.
Bạn có thể thêm phần sau vào tệp pom.xml của mình :
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.package.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.mycompany.package.MainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Sau đó, bạn phải chuyển qua bàn điều khiển đến thư mục chứa pom.xml. Sau đó, bạn phải thực hiện lắp ráp mvn: đơn và sau đó tệp JAR thực thi của bạn với các phụ thuộc sẽ được hy vọng xây dựng. Bạn có thể kiểm tra nó khi chuyển sang thư mục đầu ra (đích) bằng cd ./target và khởi động jar của bạn bằng lệnh tương tự với java -jar mavenproject1-1.0-SNAPSHOT-jar-with-Depencies.jar .
Tôi đã thử nghiệm điều này với Apache Maven 3.0.3 .
Tôi đã đi qua tất cả các câu trả lời này để tìm ra một bình thực thi chất béo có chứa tất cả các phụ thuộc và không ai trong số chúng hoạt động đúng. Câu trả lời là plugin bóng râm, nó rất dễ dàng và đơn giản.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<!-- Run shade goal on package phase -->
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>path.to.MainClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Xin lưu ý rằng các phụ thuộc của bạn cần phải có phạm vi biên dịch hoặc thời gian chạy để điều này hoạt động đúng.
plugin
yếu tố đi vào pom.xml
dưới build/plugins
.
Bạn có thể kết hợp maven-shade-plugin
và maven-jar-plugin
.
maven-shade-plugin
gói của bạn và tất cả các phụ thuộc trong một tệp jar duy nhất.maven-jar-plugin
để chỉ định lớp chính của tệp thực thi của bạn (xem Thiết lập Đường dẫn lớp , chương "Tạo tệp thực thi").Cấu hình POM ví dụ cho maven-jar-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Cuối cùng tạo jar thực thi bằng cách gọi:
mvn clean package shade:shade
Ken Liu có nó đúng theo ý kiến của tôi. Plugin phụ thuộc maven cho phép bạn mở rộng tất cả các phụ thuộc mà sau đó bạn có thể coi là tài nguyên. Điều này cho phép bạn đưa chúng vào vật phẩm chính . Việc sử dụng plugin lắp ráp tạo ra một tạo phẩm thứ cấp có thể khó sửa đổi - trong trường hợp của tôi, tôi muốn thêm các mục nhập bảng kê khai tùy chỉnh. Pom của tôi đã kết thúc như:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
<resources>
<resource>
<directory>${basedir}/target/dependency</directory>
<targetPath>/</targetPath>
</resource>
</resources>
</build>
...
</project>
Nó nên như thế:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
Việc giải nén phải ở trong giai đoạn tạo tài nguyên vì, nếu trong giai đoạn gói, sẽ không được đưa vào làm tài nguyên. Hãy thử gói sạch và bạn sẽ thấy.
Vấn đề với việc định vị tệp lắp ráp được chia sẻ với maven-assembly-plugin-2.2.1?
Hãy thử sử dụng tham số cấu hình descriptorId thay vì tham số mô tả / mô tả hoặc descriptorRefs / descriptorRef.
Không ai trong số họ làm những gì bạn cần: tìm tệp trên classpath. Tất nhiên, bạn cần thêm gói nơi tập hợp được chia sẻ nằm trên đường dẫn lớp của maven-assembly-plugin (xem bên dưới). Nếu bạn đang sử dụng Maven 2.x (không phải Maven 3.x), bạn có thể cần thêm phụ thuộc này vào pom.xml cha mẹ hàng đầu nhất trong phần Trình quản lý plugin.
Xem điều này để biết thêm chi tiết.
Lớp: org.apache.maven.plugin.assugging.io.DefaultAss lanhReader
Thí dụ:
<!-- Use the assembly plugin to create a zip file of all our dependencies. -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorId>assembly-zip-for-wid</descriptorId>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>cz.ness.ct.ip.assemblies</groupId>
<artifactId>TEST_SharedAssemblyDescriptor</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
Để giải quyết vấn đề này, chúng tôi sẽ sử dụng Plugin Maven hội sẽ tạo JAR cùng với các JAR phụ thuộc của nó vào một tệp JAR thực thi duy nhất. Chỉ cần thêm cấu hình plugin bên dưới vào tệp pom.xml của bạn.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.your.package.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
Sau khi làm điều này, đừng quên chạy công cụ MAVEN với lệnh này mvn biên dịch biên dịch sạch: đơn
Tôi sẽ không trả lời trực tiếp câu hỏi vì những người khác đã làm điều đó trước đây, nhưng tôi thực sự tự hỏi liệu có nên nhúng tất cả các phụ thuộc vào chính cái bình của dự án hay không.
Tôi thấy điểm (dễ triển khai / sử dụng) nhưng nó phụ thuộc vào trường hợp sử dụng của bài thơ của bạn (và có thể có các lựa chọn thay thế (xem bên dưới)).
Nếu bạn sử dụng nó hoàn toàn độc lập, tại sao không.
Nhưng nếu bạn sử dụng dự án của mình trong các bối cảnh khác (như trong một ứng dụng web, hoặc bị rơi trong một thư mục nơi các lọ khác đang ngồi), bạn có thể có các bản sao jar trong đường dẫn lớp của bạn (các tệp trong thư mục, một trong các tệp trong lọ). Có thể không phải là một thỏa thuận thầu nhưng tôi thường tránh điều này.
Một lựa chọn tốt:
Như thế này, cuối cùng chỉ là một bảng kê khai và "chính trình nạp lớp động đặc biệt", bạn có thể bắt đầu dự án của mình với:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Để tạo một JAR thực thi từ chính dòng lệnh, chỉ cần chạy lệnh dưới đây từ đường dẫn dự án:
mvn assembly:assembly
pom.xml
nếu không bạn nhận được Error reading assemblies: No assembly descriptors found.
. Dù sao đó cũng là điều xảy ra với tôi.
Đây là cách tốt nhất tôi tìm thấy:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.myDomain.etc.MainClassName</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Với cấu hình này, tất cả các phụ thuộc sẽ được đặt trong /dependency-jars
. Ứng dụng của tôi không có Main
lớp, chỉ có ngữ cảnh, nhưng một trong những phụ thuộc của tôi có một Main
lớp ( com.myDomain.etc.MainClassName
) khởi động máy chủ JMX và nhận một start
hoặc một stop
tham số. Vì vậy, với điều này, tôi đã có thể bắt đầu ứng dụng của mình như thế này:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Tôi chờ đợi nó sẽ hữu ích cho tất cả các bạn.
Tôi đã so sánh các plugin cây được đề cập trong bài viết này. Tôi đã tạo ra 2 lọ và một thư mục với tất cả các lọ. Tôi đã so sánh kết quả và chắc chắn plugin maven-bóng-plugin là tốt nhất. Thách thức của tôi là tôi có nhiều tài nguyên mùa xuân cần được sáp nhập, cũng như các dịch vụ jax-rs và JDBC. Tất cả chúng đều được hợp nhất bởi plugin bóng râm so với plugin maven-assembly-plugin. Trong trường hợp đó, lò xo sẽ thất bại trừ khi bạn sao chép chúng vào thư mục tài nguyên của riêng bạn và hợp nhất chúng một cách thủ công một lần. Cả hai plugin đều tạo ra cây phụ thuộc chính xác. Tôi đã có nhiều phạm vi như kiểm tra, cung cấp, biên dịch, v.v. kiểm tra và cung cấp đã bị bỏ qua bởi cả hai plugin. Cả hai đều tạo ra cùng một bảng kê khai nhưng tôi có thể hợp nhất các giấy phép với plugin bóng râm bằng cách sử dụng biến áp của họ. Với plugin phụ thuộc maven tất nhiên bạn không ' T có những vấn đề vì lọ không được trích xuất. Nhưng giống như một số khác đã chỉ ra rằng bạn cần phải mang thêm một (các) tệp để hoạt động đúng. Đây là một đoạn trích của pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>compile</includeScope>
<excludeTransitive>true</excludeTransitive>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
Một cái gì đó đã làm việc cho tôi là:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>SimpleKeyLogger</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Tôi đã có trường hợp đặc biệt bởi vì sự phụ thuộc của tôi là hệ thống một:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
Tôi đã thay đổi mã được cung cấp bởi @ user189057 với các thay đổi: 1) maven-lệ thuộc-plugin được thực thi trong "gói chuẩn bị" giai đoạn 2) Tôi đang trích xuất trực tiếp lớp được giải nén sang "đích / lớp"
Tôi đã thử câu trả lời được bình chọn nhiều nhất ở đây, và đã có thể có được bình có thể chạy được. Nhưng chương trình không chạy chính xác. Tôi không biết lý do là gì. Khi tôi cố chạy từEclipse
, tôi nhận được một kết quả khác nhưng khi tôi chạy jar từ dòng lệnh tôi nhận được một kết quả khác (nó gặp sự cố với lỗi thời gian chạy cụ thể theo chương trình).
Tôi có một yêu cầu tương tự như OP chỉ là tôi có quá nhiều phụ thuộc (Maven) cho dự án của mình. May mắn thay, giải pháp duy nhất hiệu quả với tôi là sử dụng Eclipse
. Rất đơn giản và rất đơn giản. Đây không phải là giải pháp cho OP nhưng là giải pháp cho người có yêu cầu tương tự nhưng có nhiều phụ thuộc Maven,
1) Chỉ cần nhấp chuột phải vào thư mục dự án của bạn (trong Eclipse) và chọn Export
2) Sau đó chọn Java
->Runnable Jar
3) Bạn sẽ được yêu cầu chọn vị trí của tệp jar
4) Cuối cùng, chọn lớp có phương thức Main mà bạn muốn chạy và chọn Package dependencies with the Jar file
và nhấpFinish
Đây cũng có thể là một tùy chọn, Bạn sẽ có thể xây dựng tệp jar của mình
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>WordListDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Đối với bất kỳ ai đang tìm kiếm các tùy chọn để loại trừ các phụ thuộc cụ thể khỏi uber-jar, đây là một giải pháp hiệu quả với tôi:
<project...>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>1.6.1</version>
<scope>provided</scope> <=============
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>...</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Vì vậy, nó không phải là cấu hình của plugin mvn-assembly-plugin mà là một thuộc tính của sự phụ thuộc.
Đã có hàng triệu câu trả lời, tôi muốn thêm bạn không cần <mainClass>
nếu bạn không cần thêm entrypoint vào ứng dụng của mình. Ví dụ, API có thể không nhất thiết phải có main
phương thức.
<build>
<finalName>log-enrichment</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
mvn clean compile assembly:single
ll target/
total 35100
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf 4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf 0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf 0 Sep 29 16:08 maven-status/
Thêm vào pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
và
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
Đó là nó. Gói mvn tiếp theo cũng sẽ tạo thêm một lọ chất béo, bao gồm tất cả các lọ phụ thuộc.
Các maven-lắp ráp-plugin làm việc tuyệt vời cho tôi. Tôi đã dành hàng giờ với plugin phụ thuộc maven và không thể làm cho nó hoạt động. Lý do chính là tôi phải xác định rõ ràng trong phần cấu hình các mục tạo tác cần được đưa vào như được mô tả trong tài liệu . Có một ví dụ cho các trường hợp khi bạn muốn sử dụng nó như : mvn dependency:copy
, trong đó không bao gồm bất kỳ artifactItems nào nhưng nó không hoạt động.
Bài đăng trên blog này cho thấy một cách tiếp cận khác với việc kết hợp các plugin maven-jar và maven-lắp ráp. Với cấu hình lắp ráp xml từ bài đăng trên blog, nó cũng có thể được kiểm soát nếu các phụ thuộc sẽ được mở rộng hoặc chỉ được thu thập trong một thư mục và được tham chiếu bởi một mục nhập đường dẫn trong tệp kê khai:
Giải pháp lý tưởng là bao gồm các tệp trong thư mục lib và tệp manifest.mf của tệp chính bao gồm tất cả các tệp trong đường dẫn lớp.
Và chính xác cái đó được mô tả ở đây: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-deperee-jars-USE-maven/
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Được rồi, đây là giải pháp của tôi. Tôi biết nó không sử dụng tệp pom.xml. Nhưng tôi đã gặp sự cố khi chương trình của tôi biên dịch và chạy trên Netbeans nhưng không thành công khi tôi dùng thử MyJarFile.jar của Java. Bây giờ, tôi không hiểu đầy đủ về Maven và tôi nghĩ đây là lý do khiến Netbeans 8.0.2 gặp sự cố khi đưa tệp jar của tôi vào thư viện để đặt chúng vào tệp jar. Tôi đã suy nghĩ về cách tôi từng sử dụng các tệp jar không có Maven trong Eclipse.
Đó là Maven có thể biên dịch tất cả các phụ thuộc và plugin. Không phải Netbeans. (Nếu bạn có thể nhận Netbeans và có thể sử dụng java .jar để làm điều này, vui lòng cho tôi biết cách (^. ^) V)
[Đã giải quyết - cho Linux] bằng cách mở một thiết bị đầu cuối.
Sau đó
cd /MyRootDirectoryForMyProject
Kế tiếp
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
Kế tiếp
mvn install
Điều này sẽ tạo tập tin jar trong thư mục đích.
MyJarFile-1.0-jar-with-dependencies.jar
Hiện nay
cd target
(Bạn có thể cần chạy chmod +x MyJarFile-1.0-jar-with-dependencies.jar
:)
Và cuối cùng
java -jar MyJarFile-1.0-jar-with-dependencies.jar
Xin vui lòng xem
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclPhaseNotFoundException
Tôi sẽ đăng giải pháp này lên một vài trang khác có vấn đề tương tự. Hy vọng tôi có thể cứu ai đó khỏi một tuần thất vọng.