ฉันต้องการจัดทำโปรเจคของฉันใน JAR ที่ปฏิบัติการได้ครั้งเดียวเพื่อแจกจ่าย
ฉันจะสร้างแพ็กเกจโปรเจ็กต์ Maven ทั้งหมดให้พึ่งพา JAR ในเอาต์พุต JAR ของฉันได้อย่างไร?
ฉันต้องการจัดทำโปรเจคของฉันใน JAR ที่ปฏิบัติการได้ครั้งเดียวเพื่อแจกจ่าย
ฉันจะสร้างแพ็กเกจโปรเจ็กต์ Maven ทั้งหมดให้พึ่งพา JAR ในเอาต์พุต JAR ของฉันได้อย่างไร?
คำตอบ:
<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>
และคุณเรียกใช้ด้วย
mvn clean compile assembly:single
ควรเพิ่มเป้าหมายการคอมไพล์ก่อนการประกอบ: อย่างเดียวหรืออย่างอื่นไม่รวมรหัสในโครงการของคุณเอง
ดูรายละเอียดเพิ่มเติมในความคิดเห็น
โดยทั่วไปเป้าหมายนี้เชื่อมโยงกับเฟสบิลด์เพื่อดำเนินการโดยอัตโนมัติ สิ่งนี้ทำให้มั่นใจได้ว่า JAR ถูกสร้างขึ้นเมื่อmvn install
เรียกใช้งานหรือดำเนินการปรับใช้ / ปล่อย
<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>
ลงconfiguration
ในส่วนต่อท้ายเพื่อหลีกเลี่ยงส่วนต่อท้าย "-jar-with-dependencies" ที่น่ารำคาญได้
compile
แล้วคุณจะเมา
คุณสามารถใช้การพึ่งพา - ปลั๊กอินเพื่อสร้างการอ้างอิงทั้งหมดในไดเรกทอรีแยกต่างหากก่อนขั้นตอนแพคเกจและจากนั้นรวมไว้ใน classpath ของรายการ:
<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>
หรือใช้${project.build.directory}/classes/lib
เป็น OutputDirectory เพื่อรวมไฟล์ jar ทั้งหมดลงใน jar หลัก แต่จากนั้นคุณจะต้องเพิ่มรหัส classloading ที่กำหนดเองเพื่อโหลดขวด
${project.build.directory}/classes/lib
เป็นoutputDirectory
ที่จะมีหนึ่งขวดหลักที่มีการอ้างอิงทั้งหมดภายใน แต่ - วิธีการเพิ่มรหัส classloading ที่กำหนดเองเพื่อโหลดขวดนี้หรือไม่? java -jar main-jar-with-deps.jar
ฉันต้องการที่จะทำให้การดำเนินงานที่ต้องการ: เป็นไปได้ไหม
ฉัน blogged เกี่ยวกับวิธีการต่าง ๆ ในการทำเช่นนี้
ดูJar ที่ปฏิบัติการได้กับ Apache Maven (WordPress)
หรือexecutable-jar-with-maven-example (GitHub)
สเตฟานจัดหาข้อดีและข้อเสียเหล่านั้น
<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>
ณ จุดนี้การjar
ปฏิบัติการจริงกับองค์ประกอบ classpath ภายนอก
$ java -jar target/${project.build.finalName}.jar
jar
ไฟล์เป็นเพียงปฏิบัติการกับพี่น้อง...lib/
ไดเรกทอรี เราจำเป็นต้องสร้างคลังเก็บเพื่อปรับใช้กับไดเรกทอรีและเนื้อหา
<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>
ตอนนี้คุณมีtarget/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
ซึ่งแต่ละที่มีและjar
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>
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>
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>
target/${project.bulid.finalName}-spring-boot.jar
คุณมี
รับคำตอบของ Unanswered และทำการฟอร์แมตใหม่เรามี:
<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>
ต่อไปฉันขอแนะนำให้ทำให้นี่เป็นส่วนหนึ่งของงานสร้างของคุณแทนที่จะเป็นสิ่งที่จะเรียกอย่างชัดเจน ในการทำให้ส่วนนี้เป็นส่วนสำคัญของงานสร้างให้เพิ่มปลั๊กอินนี้ลงในpom.xml
และผูกเข้ากับpackage
วงจรชีวิตของเหตุการณ์ อย่างไรก็ตาม gotcha คือคุณต้องโทรหาassembly:single
เป้าหมายหากวางสิ่งนี้ลงใน pom.xml ของคุณในขณะที่คุณเรียก 'แอสเซมบลี: แอสเซมบลี' ถ้าดำเนินการด้วยตนเองจากบรรทัดคำสั่ง
<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>
ใช้ maven-shade-plugin เพื่อรวมการอ้างอิงทั้งหมดไว้ใน uber-jar หนึ่งรายการ นอกจากนี้ยังสามารถใช้เพื่อสร้าง jar ที่ปฏิบัติการได้โดยการระบุคลาสหลัก หลังจากพยายามใช้ maven-assembly และ maven-jar ฉันพบว่าปลั๊กอินนี้เหมาะสมที่สุดกับความต้องการของฉัน
ฉันพบว่าปลั๊กอินนี้มีประโยชน์อย่างยิ่งเนื่องจากมันรวมเนื้อหาของไฟล์ที่เฉพาะเจาะจงแทนที่จะเขียนทับมัน สิ่งนี้จำเป็นเมื่อมีไฟล์ทรัพยากรที่มีชื่อเหมือนกันทั่วทั้งขวดและปลั๊กอินพยายามทำแพ็กเกจไฟล์ทรัพยากรทั้งหมด
ดูตัวอย่างด้านล่าง
<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>
ลองใช้Maven ประกอบปลั๊กอิน"already added, skipping"
แต่ฉันไม่สามารถหาวิธีการแก้ปัญหาที่มี ตอนนี้ผมใช้ปลั๊กอินอื่น - onejar-Maven ปลั๊กอิน ตัวอย่างด้านล่าง ( mvn package
build 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>
คุณต้องเพิ่มที่เก็บสำหรับปลั๊กอินนั้น:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
คุณสามารถใช้ maven-dependency-plugin ได้ แต่คำถามคือวิธีสร้าง JAR ที่สามารถเรียกใช้งานได้ ในการทำเช่นนั้นจำเป็นต้องมีการแก้ไขการตอบสนองของ Matthew Franglen ต่อไปนี้ (btw การใช้ปลั๊กอินการพึ่งพาใช้เวลานานในการสร้างเมื่อเริ่มต้นจากเป้าหมายที่สะอาด):
<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>
คุณสามารถใช้ปลั๊กอิน maven-shade เพื่อสร้าง uber jar เหมือนด้านล่าง
<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>
อีกตัวเลือกหนึ่งถ้าคุณอยากจะ repackage ขวดอื่น ๆ เนื้อหาภายใน JAR ผลลัพธ์ของคุณคนเดียวเป็นปลั๊กอิน Maven สภา มันคลายแล้วบรรจุทุกอย่างลงในไดเรกทอรีผ่าน<unpack>true</unpack>
ทุกอย่างลงในไดเรกทอรีผ่าน จากนั้นคุณจะต้องผ่านรอบที่สองซึ่งสร้างเป็น JAR อันยิ่งใหญ่
ตัวเลือกหนึ่งคือปลั๊กอิน OneJar นี่เป็นการดำเนินการ repackaging ข้างต้นทั้งหมดในขั้นตอนเดียว
คุณสามารถเพิ่มสิ่งต่อไปนี้ในpom.xmlของคุณ:
<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>
หลังจากนั้นคุณต้องสลับผ่านคอนโซลไปยังไดเรกทอรีซึ่งมีที่ตั้งของ pom.xml จากนั้นคุณจะต้องเรียกใช้งานแอสเซมบลี mvn: เดี่ยวและจากนั้นไฟล์ JAR ที่สามารถใช้งานได้ซึ่งมีการอ้างอิงของคุณจะถูกสร้างขึ้นด้วยความหวัง คุณสามารถตรวจสอบได้เมื่อสลับไปยังไดเรกทอรีเอาต์พุต (เป้าหมาย) ด้วยcd ./targetและเริ่ม jar ของคุณด้วยคำสั่งที่คล้ายกับjava -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jarmavenproject1-1.0-snapshot
ผมทดสอบนี้กับApache Maven 3.0.3
ฉันผ่านการตอบสนองเหล่านี้ทุกครั้งเพื่อหาขวดปฏิบัติการที่เต็มไปด้วยไขมันที่มีการอ้างอิงทั้งหมดและไม่มีใครทำงานได้ถูกต้อง คำตอบคือปลั๊กอินเงาซึ่งง่ายและตรงไปตรงมามาก
<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>
โปรดทราบว่าการพึ่งพาของคุณต้องมีขอบเขตของการคอมไพล์หรือรันไทม์เพื่อให้สิ่งนี้ทำงานได้อย่างเหมาะสม
plugin
องค์ประกอบไปในภายใต้pom.xml
build/plugins
คุณสามารถรวมและmaven-shade-plugin
maven-jar-plugin
maven-shade-plugin
แพ็คชั้นเรียนและการอ้างอิงของคุณทั้งหมดในเดียวไหไฟล์maven-jar-plugin
เพื่อระบุคลาสหลักของ jar ที่สามารถเรียกใช้งานได้ของคุณ (ดูการตั้งค่า The Classpath , บท "Make The Jar Executionable")ตัวอย่างการกำหนดค่า POM สำหรับ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>
ในที่สุดสร้าง jar ที่ปฏิบัติการได้โดยเรียกใช้:
mvn clean package shade:shade
Ken Liu คิดถูกแล้ว ปลั๊กอินการพึ่งพา maven อนุญาตให้คุณขยายการขึ้นต่อกันทั้งหมดซึ่งคุณสามารถใช้เป็นทรัพยากรได้ สิ่งนี้อนุญาตให้คุณรวมไว้ในสิ่งประดิษฐ์หลัก การใช้แอสเซมบลีปลั๊กอินสร้างสิ่งประดิษฐ์รองซึ่งอาจเป็นการยากที่จะแก้ไข - ในกรณีของฉันฉันต้องการเพิ่มรายการรายการแบบกำหนดเอง pom ของฉันจบลงด้วยการเป็น:
<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>
มันควรจะเป็นอย่างนั้น:
<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>
การคลายแพ็กจำเป็นต้องอยู่ในเฟส create-resources เนื่องจากหากอยู่ในเฟสแพ็กเกจจะไม่ถูกรวมเป็นรีซอร์ส ลองทำความสะอาดแพ็คเกจแล้วคุณจะเห็น
มีปัญหากับการค้นหาไฟล์ชุดประกอบที่แชร์ด้วย maven-assembly-plugin-2.2.1?
ลองใช้พารามิเตอร์การกำหนดค่า descriptorId แทนพารามิเตอร์ descriptor / descriptor หรือ descriptorRefs / descriptorRef
ไม่ทำสิ่งที่คุณต้องการ: ค้นหาไฟล์ใน classpath แน่นอนคุณต้องเพิ่มแพคเกจที่แอสเซมบลีที่ใช้ร่วมกันอยู่ใน classpath ของ maven-assembly-plugin (ดูด้านล่าง) หากคุณใช้ Maven 2.x (ไม่ใช่ Maven 3.x) คุณอาจต้องเพิ่มการพึ่งพานี้ใน pom.xml พาเรนต์ที่ติดอันดับสูงสุดในส่วนการจัดการปลั๊กอิน
ดูสิ่งนี้สำหรับรายละเอียดเพิ่มเติม
คลาส: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
ตัวอย่าง:
<!-- 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>
ในการแก้ไขปัญหานี้เราจะใช้ Maven Assembly Plugin ที่จะสร้าง JAR พร้อมกับ JAR ที่อ้างอิงได้ลงในไฟล์ JAR ที่สามารถเรียกใช้งานได้เพียงไฟล์เดียว เพียงเพิ่มการกำหนดค่าปลั๊กอินด้านล่างในไฟล์ pom.xml ของคุณ
<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>
หลังจากทำสิ่งนี้แล้วอย่าลืมเรียกใช้เครื่องมือ MAVEN ด้วยคำสั่งนี้ mvn ชุดคอมไพล์คอมไพล์แบบคลีน: เดี่ยว
ฉันจะไม่ตอบคำถามโดยตรงเช่นที่คนอื่นทำไปแล้วมาก่อน แต่ฉันสงสัยจริงๆว่าเป็นความคิดที่ดีหรือไม่ที่จะฝังการอ้างอิงทั้งหมดไว้ในโถของโครงการ
ฉันเห็นจุด (ความง่ายในการปรับใช้ / การใช้งาน) แต่ขึ้นอยู่กับกรณีการใช้งานของ poject ของคุณ (และอาจมีทางเลือก (ดูด้านล่าง))
ถ้าคุณใช้มันแบบสแตนด์อโลนอย่างสมบูรณ์ทำไมไม่
แต่ถ้าคุณใช้โครงการของคุณในบริบทอื่น ๆ (เช่นใน webapp หรือวางในโฟลเดอร์ที่โหลขวดอื่นกำลังนั่งอยู่) คุณอาจมี jar ซ้ำใน classpath ของคุณ (ที่อยู่ในโฟลเดอร์หนึ่งใน jars) อาจไม่ใช่ข้อเสนอการประมูล แต่ฉันมักจะหลีกเลี่ยงสิ่งนี้
ทางเลือกที่ดี:
เช่นนี้ในท้ายที่สุดเป็นเพียงรายการและ "หลัก classloader แบบไดนามิกพิเศษ" คุณสามารถเริ่มต้นโครงการของคุณด้วย:
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
หากต้องการสร้าง JAR ที่สามารถเรียกใช้งานได้จากบรรทัดคำสั่งให้เรียกใช้คำสั่งด้านล่างจากพา ธ โครงการ:
mvn assembly:assembly
pom.xml
Error reading assemblies: No assembly descriptors found.
นั่นคือสิ่งที่เกิดขึ้นกับฉัน
นี่คือวิธีที่ดีที่สุดที่ฉันพบ:
<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>
/dependency-jars
ด้วยการกำหนดค่านี้อ้างอิงทั้งหมดจะตั้งอยู่ใน แอปพลิเคชันของฉันไม่มีMain
คลาส แต่เป็นบริบท แต่หนึ่งในการอ้างอิงของฉันมีMain
คลาส ( com.myDomain.etc.MainClassName
) ที่เริ่มเซิร์ฟเวอร์ JMX และรับstart
หรือstop
พารามิเตอร์ ด้วยเหตุนี้ฉันจึงสามารถเริ่มต้นแอปพลิเคชันของฉันเช่นนี้:
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
ฉันรอมันจะเป็นประโยชน์สำหรับคุณทุกคน
ฉันเปรียบเทียบปลั๊กอินต้นไม้ที่กล่าวถึงในโพสต์นี้ ฉันสร้าง 2 ไหและไดเรกทอรีพร้อมไหทั้งหมด ฉันเปรียบเทียบผลลัพธ์และแน่นอน maven-shade-plugin ที่ดีที่สุด ความท้าทายของฉันคือฉันมีทรัพยากรหลายอย่างในฤดูใบไม้ผลิที่จำเป็นต้องรวมเข้าด้วยกันรวมถึงบริการ jax-rs และ JDBC พวกเขาทั้งหมดถูกผสานอย่างถูกต้องโดยปลั๊กอินที่ร่มเมื่อเปรียบเทียบกับ maven-assembly-plugin ในกรณีนี้สปริงจะล้มเหลวเว้นแต่คุณจะคัดลอกไปยังโฟลเดอร์ทรัพยากรของคุณเองและทำการรวมด้วยตนเองหนึ่งครั้ง ปลั๊กอินทั้งสองส่งทรีการพึ่งพาที่ถูกต้อง ฉันมีขอบเขตหลายอย่างเช่นการทดสอบจัดหาคอมไพล์ ฯลฯ การทดสอบและการจัดเตรียมนั้นถูกข้ามโดยปลั๊กอินทั้งสอง พวกเขาทั้งสองผลิตรายการเดียวกัน แต่ฉันสามารถรวมใบอนุญาตกับปลั๊กอินที่ร่มโดยใช้หม้อแปลงของพวกเขา ด้วย maven-dependency-plugin แน่นอนคุณไม่ต้อง ' ไม่มีปัญหาเหล่านั้นเพราะไหไม่ถูกแยกออกมา แต่เหมือนคนอื่น ๆ ที่ชี้ว่าคุณต้องพกไฟล์พิเศษหนึ่งไฟล์เพื่อให้ทำงานได้อย่างถูกต้อง นี่คือ snip ของ 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>
สิ่งที่ทำงานให้ฉันคือ:
<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>
ฉันมีกรณีพิเศษเพราะการพึ่งพาของฉันคือระบบที่หนึ่ง:
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
ฉันได้เปลี่ยนรหัสที่ได้รับจาก @ user189057 เมื่อมีการเปลี่ยนแปลง: 1) maven-dependency-plugin ทำงานใน "เตรียมแพ็คเกจ" เฟส 2) ฉันกำลังแยก classess ที่ไม่แตกออกเป็น "เป้าหมาย / คลาส" โดยตรง
ฉันลองคำตอบที่ได้รับการโหวตมากที่สุดที่นี่และสามารถรับ jar ที่รันได้ แต่โปรแกรมทำงานไม่ถูกต้อง ฉันไม่รู้ว่าเหตุผลคืออะไร เมื่อฉันพยายามวิ่งหนีEclipse
ฉันได้รับผลที่แตกต่างกัน แต่เมื่อฉันเรียกใช้ jar จากบรรทัดคำสั่งฉันได้รับผลลัพธ์ที่แตกต่างกัน (มันล้มเหลวด้วยข้อผิดพลาดรันไทม์เฉพาะโปรแกรม)
ฉันมีข้อกำหนดที่คล้ายกันเนื่องจาก OP มีเพียงการพึ่งพา (Maven) มากเกินไปสำหรับโครงการของฉัน Eclipse
โชคดีที่โซลูชั่นเดียวที่ทำงานสำหรับฉันคือการที่ใช้ ง่ายมากและตรงไปตรงมามาก นี่ไม่ใช่วิธีแก้ปัญหาสำหรับ OP แต่เป็นวิธีแก้ปัญหาสำหรับคนที่มีความต้องการคล้ายกัน แต่มีการพึ่งพา Maven จำนวนมาก
1) เพียงคลิกขวาที่โฟลเดอร์โครงการของคุณ (ใน Eclipse) และเลือก Export
2) จากนั้นเลือกJava
->Runnable Jar
3) คุณจะถูกขอให้เลือกตำแหน่งของไฟล์ jar
4) สุดท้ายเลือกคลาสที่มีวิธีการหลักที่คุณต้องการเรียกใช้และเลือกPackage dependencies with the Jar file
และคลิกFinish
นี่อาจเป็นตัวเลือกคุณจะสามารถสร้างไฟล์ jar ของคุณได้
<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>
สำหรับใครที่กำลังมองหาตัวเลือกที่จะไม่รวมการพึ่งพาเฉพาะจาก uber-jar นี่เป็นวิธีแก้ปัญหาที่เหมาะกับฉัน:
<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>
ดังนั้นจึงไม่ใช่การกำหนดค่าของ mvn-assembly-plugin แต่เป็นคุณสมบัติของการพึ่งพา
มีคำตอบนับล้านแล้วฉันต้องการเพิ่มคุณไม่จำเป็น<mainClass>
ถ้าคุณไม่ต้องการเพิ่มจุดเข้าใช้งานของคุณ ตัวอย่างเช่น API อาจไม่มีmain
วิธีที่จำเป็น
<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/
เพิ่มใน pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
และ
<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>
แค่นั้นแหละ. แพ็คเกจ mvn ถัดไปจะสร้างหนึ่งขวดไขมันนอกจากนี้รวมทั้งขวดอ้างอิงทั้งหมด
maven-assembly-plugin ใช้งานได้ดีสำหรับฉัน ฉันใช้เวลาหลายชั่วโมงกับ maven-dependency-plugin และไม่สามารถทำงานได้ เหตุผลหลักคือการที่ฉันได้มีการกำหนดในส่วนการกำหนดค่าอย่างชัดเจนรายการสิ่งประดิษฐ์ซึ่งควรจะรวมอยู่ในขณะที่มันได้อธิบายไว้ในเอกสาร มีตัวอย่างสำหรับกรณีที่เมื่อคุณต้องการที่จะใช้มันเช่น: mvn dependency:copy
ที่มีไม่รวมรายการสิ่งของใด ๆ แต่มันไม่ทำงาน
โพสต์บล็อกนี้แสดงวิธีการอื่นด้วยการรวมปลั๊กอิน maven-jar และ maven-assembly ด้วยการกำหนดค่าแอสเซมบลี xml จากบล็อกโพสต์สามารถควบคุมได้หากการพึ่งพาจะขยายหรือเพียงแค่รวบรวมในโฟลเดอร์และอ้างอิงโดยรายการ classpath ในรายการ:
ทางออกที่ดีที่สุดคือการรวมไหในโฟลเดอร์ lib และไฟล์ manifest.mf ของโถหลักรวมถึงขวดทั้งหมดใน classpath
และตรงตามที่อธิบายไว้ที่นี่: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-drants-jars-using-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>
โอเคนี่คือทางออกของฉัน ฉันรู้ว่ามันไม่ได้ใช้ไฟล์ pom.xml แต่ฉันมีปัญหาฉัน programmme รวบรวมและทำงานบน Netbeans แต่มันล้มเหลวเมื่อฉันพยายาม Java -jar MyJarFile.jar ตอนนี้ฉันไม่เข้าใจ Maven อย่างสมบูรณ์และฉันคิดว่านี่เป็นสาเหตุที่ทำให้เกิดปัญหาในการรับ Netbeans 8.0.2 เพื่อรวมไฟล์ jar ของฉันไว้ในไลบรารีเพื่อใส่ลงในไฟล์ jar ฉันคิดว่าฉันเคยใช้ไฟล์ jar โดยไม่มี Maven ใน Eclipse ได้อย่างไร
มัน Maven ที่สามารถรวบรวมผู้อ้างอิงและปลั๊กอินทั้งหมดได้ ไม่ใช่ Netbeans (ถ้าคุณสามารถรับ Netbeans และสามารถใช้ java .jar เพื่อทำสิ่งนี้โปรดบอกฉันว่า (^. ^) v)
[แก้ไขแล้ว - สำหรับ Linux] โดยเปิดเทอร์มินัล
แล้วก็
cd /MyRootDirectoryForMyProject
ต่อไป
mvn org.apache.maven.plugins:maven-compiler-plugin:compile
ต่อไป
mvn install
สิ่งนี้จะสร้างไฟล์ jar ในไดเรกทอรีเป้าหมาย
MyJarFile-1.0-jar-with-dependencies.jar
ตอนนี้
cd target
(คุณอาจจำเป็นต้องเรียกใช้: chmod +x MyJarFile-1.0-jar-with-dependencies.jar
)
และในที่สุดก็
java -jar MyJarFile-1.0-jar-with-dependencies.jar
โปรดมอง
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
ฉันจะโพสต์วิธีการแก้ปัญหานี้ในหน้าอื่น ๆ ที่มีปัญหาที่คล้ายกัน หวังว่าฉันสามารถช่วยคนจากความผิดหวังในหนึ่งสัปดาห์