배포를 위해 프로젝트를 단일 실행 가능한 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
컴파일 목표는 어셈블리 전에 추가해야합니다 : 단일 또는 그렇지 않으면 자신의 프로젝트 코드가 포함되지 않습니다.
주석에서 자세한 내용을 참조하십시오.
일반적으로이 목표는 빌드 단계와 연결되어 자동으로 실행됩니다. 이를 통해 mvn install
배치 / 릴리스를 실행 하거나 수행 할 때 JAR이 빌드됩니다 .
<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
compile
당신은 망했다.
dependency-plugin을 사용하여 패키지 단계 전에 별도의 디렉토리에 모든 종속성을 생성 한 후 매니페스트의 클래스 경로에 포함시킬 수 있습니다.
<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
모든 jar 파일을 기본 jar에 통합하기 위해 OutputDirectory로 사용 하십시오. 그러나 jar를로드하려면 사용자 정의 클래스 로딩 코드를 추가해야합니다.
${project.build.directory}/classes/lib
as outputDirectory
를 사용 하지만이 jars를로드하기 위해 사용자 정의 클래스 로딩 코드를 추가하는 방법은 무엇입니까? 다음과 같이 작업을 실행해야합니다 java -jar main-jar-with-deps.jar
. 이것이 가능한가 ?
나는 이것을하는 몇 가지 다른 방법에 대해 블로그했습니다.
Apache Maven으로 실행 가능한 Jar 참조 (WordPress)이 포함 된
또는 실행 가능한 jar-with-maven-example (GitHub)
이러한 장단점은 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>
이 시점에서 jar
실제로는 외부 클래스 경로 요소로 실행 가능합니다.
$ 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
라이프 사이클 이벤트에 바인딩하십시오 . 그러나 assembly:single
이것을 pom.xml에 넣으면 목표 를 호출해야하지만 명령 줄에서 수동으로 실행하면 'assembly : assembly'를 호출해야합니다.
<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을 사용하려고 시도한 후이 플러그인이 내 요구에 가장 적합하다는 것을 알았습니다.
이 플러그인은 특정 파일의 내용을 덮어 쓰지 않고 병합하므로 특히 유용합니다. 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-plugin을 사용하고 있습니다. 아래 예제 ( mvn package
빌드 항아리) :
<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>
단일 결과 JAR 내의 다른 JAR 컨텐츠를 실제로 다시 패키지하려는 경우 또 다른 옵션은 Maven Assembly 플러그인 입니다. 압축을 풀고를 통해 모든 것을 디렉토리에 다시 압축 <unpack>true</unpack>
합니다. 그런 다음 하나의 거대한 JAR로 빌드 한 두 번째 패스가 있습니다.
또 다른 옵션은 OneJar 플러그인 입니다. 위의 재 포장 작업을 모두 한 단계로 수행합니다.
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 assembly : single 을 실행해야 하며 종속성이있는 실행 가능한 JAR 파일이 빌드됩니다. cd ./target 을 사용하여 출력 (대상) 디렉토리로 전환 하고 java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar와 유사한 명령으로 jar을 시작할 때이를 확인할 수 있습니다. .
나는 이것을 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
하나의 jar 파일에 클래스와 모든 종속성을 압축합니다.maven-jar-plugin
실행 가능한 jar의 기본 클래스를 지정하도록를 구성하십시오 ( " 클래스 경로 설정 ", "jar 실행 파일 작성"장 참조 ).의 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
켄 리우는 제 생각에 옳습니다. maven dependency 플러그인을 사용하면 모든 종속성을 확장하여 리소스로 취급 할 수 있습니다. 이를 통해 주요 이슈 에 포함시킬 수 있습니다 . 어셈블리 플러그인을 사용하면 수정하기 어려운 보조 아티팩트가 생성됩니다. 필자의 경우 사용자 정의 매니페스트 항목을 추가하고 싶었습니다. 내 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>
포장 풀기 단계에서는 자원으로 포함되지 않으므로 압축 풀기 작업은 자원 생성 단계에 있어야합니다. 깨끗한 패키지를 사용해보십시오.
maven-assembly-plugin-2.2.1로 공유 어셈블리 파일을 찾는 데 문제가 있습니까?
descriptors / descriptor 또는 descriptorRefs / descriptorRef 매개 변수 대신 descriptorId 구성 매개 변수를 사용해보십시오.
둘 중 어느 것도 필요한 것을 수행하지 않습니다. classpath에서 파일을 찾으십시오. 물론 공유 어셈블리가 maven-assembly-plugin의 클래스 경로에있는 패키지를 추가해야합니다 (아래 참조). Maven 3.x가 아닌 Maven 2.x를 사용하는 경우 pluginManagement 섹션의 최상위 부모 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>
이 문제를 해결하기 위해 종속 JAR과 함께 JAR을 단일 실행 가능 JAR 파일로 작성하는 Maven Assembly Plugin을 사용합니다. 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>
이 작업을 수행 한 후 mvn clean compile assembly 명령으로 MAVEN 도구를 실행하는 것을 잊지 마십시오.
다른 사람들이 이미 그랬듯이 질문에 직접 대답하지는 않지만 프로젝트의 항아리 자체에 모든 종속성을 포함시키는 것이 좋은지 궁금합니다.
요점 (배치 / 사용의 용이성)을 볼 수 있지만 그것은 당신의 의견의 유스 케이스에 달려 있습니다 (그리고 대안이있을 수 있습니다 (아래 참조)).
완전히 독립형으로 사용한다면 어떨까요?
그러나 다른 컨텍스트 (예 : webapp 또는 다른 항아리가있는 폴더에 떨어 뜨림)에서 프로젝트를 사용하는 경우 클래스 경로에 항아리 복제본이있을 수 있습니다 (폴더에있는 항아리, 항아리에있는 항아리). 아마 입찰 거래는 아니지만 나는 보통 이것을 피합니다.
좋은 대안 :
이와 같이 매니페스트와 "특수 동적 클래스 로더 메인"만 있으면 다음과 같이 프로젝트를 시작할 수 있습니다.
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
클래스 가 없으며 컨텍스트가 있지만 종속성 중 하나 에는 JMX 서버를 시작하고 a 또는 매개 변수를 받는 Main
클래스 ( com.myDomain.etc.MainClassName
)가 있습니다. 그래서 이것으로 나는 다음과 같이 내 응용 프로그램을 시작할 수있었습니다 :start
stop
java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
여러분 모두에게 도움이되기를 기다립니다.
이 게시물에서 언급 한 트리 플러그인을 비교했습니다. 2 개의 항아리와 모든 항아리가있는 디렉토리를 생성했습니다. 나는 결과를 비교했고 확실히 maven-shade-plugin이 최고입니다. 내 과제는 병합해야 할 여러 스프링 리소스와 jax-rs 및 JDBC 서비스가 있다는 것입니다. 그것들은 maven-assembly-plugin과 비교하여 shade 플러그인에 의해 올바르게 병합되었습니다. 이 경우 스프링을 리소스 폴더에 복사하고 수동으로 한 번 병합하지 않으면 스프링이 실패합니다. 두 플러그인 모두 올바른 종속성 트리를 출력합니다. 나는 테스트, 제공, 컴파일 등과 같은 여러 범위를 가지고 테스트를 제공했으며 두 플러그인 모두 생략했습니다. 둘 다 동일한 매니페스트를 생성했지만 변환기를 사용하여 음영 플러그인으로 라이센스를 통합 할 수있었습니다. 물론 maven-dependency-plugin을 사용하면 항아리가 추출되지 않기 때문에 이러한 문제가 없습니다. 그러나 다른 사람들이 지적했듯이 제대로 작동하려면 하나의 추가 파일을 가지고 있어야합니다. 다음은 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>
내 의존성이 시스템 1이기 때문에 특별한 경우가있었습니다.
<dependency>
..
<scope>system</scope>
<systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>
@ user189057에서 제공하는 코드를 변경하여 변경했습니다. 1) maven-dependency-plugin이 "prepare-package"단계에서 실행됩니다. 2) 압축이 풀린 클래스를 "target / classes"로 직접 추출합니다.
여기에서 가장 투표가 많은 답변을 시도하고 항아리를 실행할 수있었습니다. 그러나 프로그램이 제대로 실행되지 않았습니다. 이유가 무엇인지 모르겠습니다. 내가 도망 칠 때Eclipse
하면 다른 결과가 표시되지만 명령 줄에서 jar을 실행하면 다른 결과가 발생합니다 (프로그램 별 런타임 오류로 충돌).
프로젝트에 너무 많은 (Maven) 종속성이 있다는 OP와 비슷한 요구 사항이있었습니다. 다행히도 나를 위해 일한 유일한 솔루션은을 사용하는 것 Eclipse
입니다. 매우 간단하고 간단합니다. 이것은 OP에 대한 솔루션은 아니지만 요구 사항은 비슷하지만 Maven 종속성이 많은 사람을위한 솔루션입니다.
1) 프로젝트 폴더 (Eclipse에서)를 마우스 오른쪽 버튼으로 클릭하고 Export
2) 그런 다음 Java
->를 선택하십시오.Runnable Jar
3) jar 파일의 위치를 선택하라는 메시지가 표시됩니다.
4) 마지막으로 실행할 Main 메소드가있는 클래스를 선택 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>
있습니다. 응용 프로그램에 entryPoint를 추가 할 필요가 없으면 필요하지 않게 추가하고 싶었습니다. 예를 들어 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 패키지는 모든 의존성 jar를 포함하여 하나의 지방 jar을 추가로 생성합니다.
이 블로그 게시물은 maven-jar 및 maven-assembly 플러그인을 결합하는 또 다른 접근법을 보여줍니다. 블로그 게시물의 어셈블리 구성 xml을 사용하면 종속성이 확장되거나 폴더에서 수집되고 매니페스트의 클래스 경로 항목으로 참조되는지 여부를 제어 할 수도 있습니다.
이상적인 해결책은 jar를 lib 폴더에 포함하고 주 jar의 manifest.mf 파일은 모든 jar을 classpath에 포함하는 것입니다.
그리고 그 중 하나가 여기에 설명되어 있습니다 : https://caffebig.wordpress.com/2013/04/05/ executable-jar-file-with-dependent-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 파일을 사용하지 않는다는 것을 알고 있습니다. 그러나 Netbeans에서 프로그램을 컴파일하고 실행하는 데 문제가 있었지만 Java -jar MyJarFile.jar을 시도하면 실패했습니다. 이제 Maven을 완전히 이해하지 못했기 때문에 Netbeans 8.0.2에서 jar 파일을 라이브러리에 포함시켜 jar 파일에 넣는 데 Netbeans 8.0.2를 가져 오는 데 왜 어려움이 있었는지 생각합니다. Eclipse에서 Maven이없는 jar 파일을 사용하는 방법에 대해 생각하고있었습니다.
모든 의존성과 플러그인을 컴파일 할 수있는 Maven입니다. 넷빈이 아닙니다. (Netbeans을 얻을 수 있고 java .jar을 사용하여이를 수행 할 수 있다면 (^. ^) v 알려주십시오)
터미널을 열어서 [Solved-for 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
이 문제를 비슷한 문제가있는 다른 두 페이지에 게시하겠습니다. 잘만되면 나는 일주일의 좌절에서 누군가를 구할 수 있기를 바랍니다.