배포를 위해 단일 실행 가능한 JAR에 프로젝트를 패키징하고 싶습니다.
Maven 프로젝트 패키지를 모든 종속성 JAR을 내 출력 JAR로 만들려면 어떻게 해야 합니까?
질문자 :soemirno
배포를 위해 단일 실행 가능한 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>
종속성 플러그인을 사용하여 패키지 단계 전에 별도의 디렉터리에 모든 종속성을 생성한 다음 매니페스트의 클래스 경로에 포함할 수 있습니다.
<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에 통합하지만, jar를 로드하려면 사용자 정의 클래스 로딩 코드를 추가해야 합니다.
실행 가능한 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>
이제 jar
및 lib/*
가 포함된 target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
가 있습니다.
<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
목표를 호출해야 하는 반면 명령줄에서 수동으로 실행하는 경우 '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 - ie 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-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>
Long은 maven 어셈블리 플러그인 "already added, skipping"
문제에 대한 솔루션을 찾을 수 없습니다. 이제 다른 플러그인인 onejar-maven-plugin을 사용하고 있습니다. 아래 예( mvn package
빌드 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>
단일 결과 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>
이것이 제대로 작동하려면 종속성에 컴파일 또는 런타임 범위가 있어야 합니다.
maven-shade-plugin
과 maven-jar-plugin
결합할 수 있습니다.
maven-shade-plugin
은 클래스와 모든 종속성을 단일 jar 파일에 압축합니다.maven-jar-plugin
을 구성하십시오(Set Up The Classpath , "Make The Jar Executable" 장 참조). maven-jar-plugin
대한 POM 구성 예:
<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>
패키지 단계에 있는 경우 리소스로 포함되지 않기 때문에 압축 풀기는 리소스 생성 단계에 있어야 합니다. 깨끗한 패키지를 시도하면 알 수 있습니다.
maven-assembly-plugin-2.2.1로 공유 어셈블리 파일을 찾는 데 문제가 있습니까?
descriptor/descriptor 또는 descriptorRefs/descriptorRef 매개변수 대신 descriptorId 구성 매개변수를 사용해 보십시오.
둘 다 필요한 작업을 수행하지 않습니다. 클래스 경로에서 파일을 찾으십시오. 물론 maven-assembly-plugin의 클래스 경로에 공유 어셈블리가 있는 패키지를 추가해야 합니다(아래 참조). Maven 2.x(Maven 3.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>
이 작업을 수행한 후 이 명령으로 MAVEN 도구를 실행하는 것을 잊지 마십시오. mvn clean compile assembly:single
다른 사람들이 이전에 이미 그렇게 했으므로 질문에 직접 대답하지 않겠지만 프로젝트의 항아리 자체에 모든 종속성을 포함시키는 것이 좋은 생각인지 정말 궁금합니다.
요점(배포/사용 용이성)을 알지만 프로젝트의 사용 사례에 따라 다릅니다(대안이 있을 수 있음(아래 참조)).
완전히 독립 실행형으로 사용한다면 왜 안 될까요?
그러나 다른 컨텍스트에서 프로젝트를 사용하는 경우(예: webapp에서 또는 다른 jar가 있는 폴더에 떨어뜨림) 클래스 경로에 jar 복제본이 있을 수 있습니다(폴더에 있는 것, jar에 있는 것). 어쩌면 입찰 거래는 아니지만 나는 보통 이것을 피합니다.
좋은 대안:
이와 같이 결국 매니페스트와 "특별한 동적 클래스 로더 메인"만 있으면 다음과 같이 프로젝트를 시작할 수 있습니다.
java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
명령줄 자체에서 실행 가능한 JAR을 만들려면 프로젝트 경로에서 아래 명령을 실행하기만 하면 됩니다.
mvn assembly:assembly
나를 위해 일한 것은 다음과 같습니다.
<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이 "패키지 준비" 단계에서 실행됩니다. 2) 압축을 푼 클래스를 "대상/클래스"로 직접 추출합니다.
이것이 내가 찾은 가장 좋은 방법입니다.
<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 서버를 시작하고 start
또는 stop
매개변수를 Main
클래스( com.myDomain.etc.MainClassName
그래서 이것으로 다음과 같이 내 응용 프로그램을 시작할 수있었습니다.
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>
나는 여기에서 가장 많이 투표 한 답변을 시도했고 항아리를 실행할 수있었습니다. 그러나 프로그램이 제대로 실행되지 않았습니다. 이유가 무엇인지 모르겠습니다. 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의 구성이 아니라 종속성의 속성입니다.
이미 수백만 개의 답변이 있습니다. 애플리케이션에 entryPoint를 추가할 필요가 없다면 <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
와 같이 사용하려는 경우에 대한 예제가 있습니다. 여기서 어떠한 artifactItems도 포함되지 않았지만 작동하지 않습니다.
이 블로그 게시물은 maven-jar 및 maven-assembly 플러그인을 결합하는 또 다른 접근 방식을 보여줍니다. 블로그 게시물의 어셈블리 구성 xml을 사용하여 종속성이 확장되거나 폴더에서 수집되고 매니페스트의 클래스 경로 항목에서 참조되는지 여부도 제어할 수 있습니다.
이상적인 솔루션은 lib 폴더에 jar를 포함하고 기본 jar의 manifest.mf 파일에 클래스 경로의 모든 jar를 포함하는 것입니다.
그리고 정확히 그 내용이 여기에 설명되어 있습니다. https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
내 경험이 누군가에게 도움이 되기를 바랍니다. 내 앱 Spring(cas 클라이언트 사용)을 Spring Boot(아직 2.4가 아닌 1.5)로 마이그레이션하고 싶습니다. 나는 다음과 같은 많은 문제에 봉착했습니다.
target/cas-client-web.jar에 기본 매니페스트 속성 없음
모든 종속성을 가진 하나의 고유한 항아리를 만들고 싶습니다. 인터넷에서 검색에 몇 일 후. 나는 다음 줄로 내 일을 할 수 있습니다.
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <mainClass>${start-class}</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>${start-class}</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin>
start-class 는 기본 클래스입니다.
<properties> <java.version>1.8</java.version> <start-class>com.test.Application</start-class> </properties>
그리고 내 응용 프로그램 은 다음과 같습니다.
package com.test; import java.util.Arrays; import com.test.TestProperties; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @SpringBootApplication @EnableAutoConfiguration @EnableConfigurationProperties({TestProperties.class}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { System.out.println("Let's inspect the beans provided by Spring Boot:"); String[] beanNames = ctx.getBeanDefinitionNames(); Arrays.sort(beanNames); for (String beanName : beanNames) { System.out.println(beanName); } }; } }
<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>
출처 : http:www.stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven
JavaScript에서 null, 정의되지 않음 또는 공백 변수를 확인하는 표준 함수가 있습니까? (0) | 2021.11.10 |
---|---|
JavaScript에서 현재 날짜를 어떻게 얻습니까? (0) | 2021.11.10 |
설치된 PowerShell 버전 확인 (0) | 2021.11.10 |
PHP의 배열에서 요소 삭제 (0) | 2021.11.10 |
"B"를 인쇄하는 것이 "#"을 인쇄하는 것보다 훨씬 느린 이유는 무엇입니까? (0) | 2021.11.10 |