Maven으로 항아리에 종속성 포함


353

maven (2.0.9)이 모든 jar 파일을 단일 jar 파일에 포함 시키도록 강제하는 방법이 있습니까?

단일 jar 파일로 빌드 한 프로젝트가 있습니다. 종속성의 클래스도 jar로 복사하기를 원합니다.

업데이트 : 단지 jar 파일에 jar 파일을 포함시킬 수 없다는 것을 알고 있습니다. 종속성으로 지정된 항아리를 풀고 클래스 파일을 내 항아리에 패키지하는 방법을 찾고 있습니다.




2
jar 파일을 jar 파일에 maven에 포함시키는 방법은 무엇입니까?
Kush Patel

답변:


488

"jar-with-dependencies"설명자와 함께 maven-assembly 플러그인을 사용하여이를 수행 할 수 있습니다. 이를 수행하는 pom.xml 중 하나의 관련 청크가 있습니다.

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

30
attached목표는 사용되지 않습니다. single또는 directory-single목표 대신 선호한다.
파스칼 티 벤트

16
directory-single더 이상 사용되지 않습니다.
James McMahon

14
사용하여 단일하는 것은 공식에 추천 웹 사이트
mateuszb

42
새로운 mvn 사람들이 나와 같이 붙어있는 경우 <project> 안에있는 <build> 안의 <plugins>에 플러그인을 추가하십시오.
DA

10
Christian.tucker @ 다음과 같이 생성 된 대상 디렉토리에 2 항아리있다 : ./target/example-0.0.1-SNAPSHOT.jar./target/example-0.0.1-SNAPSHOT-jar-with-dependencies.jar은
technocrat

145

Maven 2에서이를 수행하는 올바른 방법 은 사전 정의 된 설명자 파일 이있는 Maven2 Assembly Plugin 을 사용하는 것이며 명령 행에서 사용할 수 있습니다.

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

이 jar을 실행 가능하게하려면 플러그인 구성에 실행할 기본 클래스를 추가하십시오.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>my.package.to.my.MainClass</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

일반 빌드 프로세스의 일부로 해당 어셈블리를 작성하려면 단일 또는 디렉토리 단일 목표 ( assembly목표는 명령 행에서만 실행해야 package함)를 다음과 같이 라이프 사이클 단계에 적용 해야합니다.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

적응 configuration(말씀으로 매니페스트 물건 예를 들어) 당신의 요구에 맞게 요소를.


나는 이것을 정확하게 시도하고 있지만 플러그인이 실행되지 않고 빌드가 부드럽게 실행 되더라도 jar 파일이 생성되지 않습니다. 내가 겪었을 수있는 일반적인 함정이 있습니까?
posdef

6
그것은 나를 위해 일하고 있지만 탐구하고 있습니다. 빌드 후 프로젝트 artifactid-version과 artifactid-version- "jar-with-dependencies"가있는 두 개의 jar 파일이 생성됩니다. 그러나 나는 단지 하나의 항아리 만 만들어지기를 원합니다. 다른 방법이 있습니까
Souvik Bhattacharya

38

실행 가능한 jar 파일을 수행하려면 주 클래스도 설정해야합니다. 따라서 전체 구성이되어야합니다.

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

2
jar의 이름에 "jar-with-dependencies"가 추가되는 이유는 무엇입니까?! 해결 방법이 있습니까?
Tina J

1
@Tina J 태그 <appendAssemblyId>false</appendAssemblyId>내에 추가 <configuration>하여 최종 이름에서 "-jar-with-dependencies"접미사를 제외 할 수 있습니다 .
ccu December


17

<classifier>태그 를 사용하여 새로 만든 jar을 사용할 수 있습니다 .

<dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>your.artifact.id</artifactId>
        <version>1.0</version>
        <type>jar</type>
        <classifier>jar-with-dependencies</classifier>
    </dependency>
</dependencies>

14

(나 같은) 당신이 특히처럼 해달라고하면 항아리-와 의존성 접근 위에서 설명한, 내가 선호하는 받는다는-솔루션은 당신이 구축 만 독립형 자바 응용 프로그램이 경우에도 단순히 WAR 프로젝트를 구축하는 것입니다 :

  1. 일반적인 maven jar-project를 만들어 jar 파일을 빌드하십시오 (종속성 없음).

  2. 또한 jar 프로젝트가있는 maven war-project ( maven 빌드의 경고 / 오류를 피하는 빈 src / main / webapp / WEB-INF / web.xml 파일 만 사용)를 설정하십시오. 의존성을 높이고 jar 프로젝트를 <module>전쟁 프로젝트 아래에 만듭니다. (이 전쟁 프로젝트는 모든 jar 파일 종속성을 zip 파일로 감싸는 간단한 방법입니다.)

  3. war 파일을 생성하기 위해 war 프로젝트를 빌드하십시오.

  4. 배포 단계에서 .war 파일의 이름을 * .zip으로 바꾸고 압축을 풉니 다.

이제 jar와 응용 프로그램을 실행하는 데 필요한 모든 종속성과 함께 lib 디렉토리 (원하는 곳으로 이동할 수 있음)가 있어야합니다.

java -cp 'path/lib/*' MainClass

(classpath의 와일드 카드는 Java-6 이상에서 작동합니다)

필자는 이것이 maven에서 설정하는 것이 더 간단하고 (어셈블리 플러그인으로 엉망으로 만들 필요가 없음) 응용 프로그램 구조를 더 명확하게 볼 수 있다고 생각합니다 (모든 종속 jar의 버전 번호는 일반보기로 표시됩니다. 모든 것을 단일 jar 파일로 막지 마십시오).


Eclipse "Runnable jar로 내보내기"와 동일합니까? 이를 통해 "JAR로 모든 종속성을 패키지"하도록 선택할 수 있으므로 jar를 따라 project-lib 폴더에 모든 종속성을 가져옵니다.
WesternGun

@FaithReaper- "같은"것일 수도 있습니다. 그러나 Eclipse를 사용하면 쉽게 스크립트 할 수 없으므로 자동화 된 빌드 + 배포 파이프 라인 을 구현하려는 경우 필수 입니다. 예를 들어 Jenkins-server가 자식 소스 리포지토리 또는 이와 유사한 빌드를 수행하도록하십시오.
Rop

12

http://fiji.sc/Uber-JAR 은 대안에 대한 훌륭한 설명을 제공합니다.

uber-JAR을 구성하는 일반적인 세 ​​가지 방법이 있습니다.

  1. 음영 처리되지 않았습니다. 모든 JAR 파일의 압축을 푼 다음 단일 JAR로 다시 압축하십시오.
    • Pro : Java의 기본 클래스 로더와 함께 작동합니다.
    • 단점 : 경로가 동일한 여러 JAR 파일에 존재하는 파일 (예 : META-INF / services / javax.script.ScriptEngineFactory)은 서로 덮어 쓰여 동작이 잘못됩니다.
    • 도구 : Maven Assembly Plugin, Classworlds Uberjar
  2. 음영 처리 음영 처리되지 않은 것과 동일하지만 모든 종속성의 모든 패키지 이름을 바꾸십시오 (예 : "음영").
    • Pro : Java의 기본 클래스 로더와 함께 작동합니다. 일부 (전부는 아님) 종속성 버전 충돌을 방지합니다.
    • 단점 : 경로가 동일한 여러 JAR 파일에 존재하는 파일 (예 : META-INF / services / javax.script.ScriptEngineFactory)은 서로 덮어 쓰여 동작이 잘못됩니다.
    • 도구 : Maven Shade Plugin
  3. JAR의 JAR. 최종 JAR 파일에는 다른 JAR 파일이 포함되어 있습니다.
    • Pro : 종속성 버전 충돌을 방지합니다. 모든 리소스 파일이 유지됩니다.
    • 단점 : Java가 래핑 된 JAR 파일에서 클래스를로드 할 수 있도록 특수한 "부트 스트랩"클래스 로더를 번들로 제공해야합니다. 클래스 로더 문제 디버깅이 더 복잡해집니다.
    • 도구 : Eclipse JAR 파일 내보내기, 1JAR

1
서비스와 관련하여 사실은 아니지만, 쉐이드 플러그인에는 변환기가 있으며 그중 하나는 META-INF/services디렉토리 아래에 파일의 내용을 연결하는 것입니다 . 자세한 정보는 여기에 : maven.apache.org/plugins/maven-shade-plugin/examples/…
vitro

7
        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            

4

Eclipse Luna 및 m2eclipse에 대한 나의 결정적인 솔루션 : 사용자 정의 클래스 로더 (프로젝트에 다운로드하여 추가, 5 클래스 만 해당) : http://git.eclipse.org/c/jdt/eclipse.jdt.ui.git/plain/org. eclipse.jdt.ui / jar % 20in % 20jar % 20loader / org / eclipse / jdt / internal / jarinjarloader / ; 이 클래스 로더는 가장 빠른 단일 클래스 클래스 로더이며 매우 빠릅니다.

<project.mainClass>org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader</project.mainClass> <project.realMainClass>my.Class</project.realMainClass>

JIJConstants "Rsrc-Class-Path"에서 "Class-Path"로 편집
mvn clean dependency : copy-dependencies 패키지
는 얇은 클래스 로더를 사용하여 lib 폴더에 종속 된 jar 파일을 생성합니다

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.java</include>
                <include>**/*.properties</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*</include>
            </includes>
            <targetPath>META-INF/</targetPath>
        </resource>
        <resource>
            <directory>${project.build.directory}/dependency/</directory>
            <includes>
                <include>*.jar</include>
            </includes>
            <targetPath>lib/</targetPath>
        </resource>
    </resources>
<pluginManagement>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${project.mainClass}</mainClass>
                            <classpathPrefix>lib/</classpathPrefix>
                        </manifest>

                        <manifestEntries>
                            <Rsrc-Main-Class>${project.realMainClass}  </Rsrc-Main-Class>
                            <Class-Path>./</Class-Path>
                        </manifestEntries>

                    </archive>
                </configuration>
            </plugin>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

maven-dependency-plugin <outputDirectory>가 작동하지 않습니다. 항상 "dependency"폴더에 쓰기
Glaucio Southier

프로젝트 의존성을 포함하는 내부 폴더 "종속성"이있는 jar 파일을 만들고 MANIFEST.MF에 배치
Glaucio Southier

<resources> <resource> <directory> src / main / java </ directory> <includes> <include> ** / *. java </ include> <include> ** / *. properties </ include> </ include> > </ resource> <resource> <directory> src / main / resources </ directory> <filtering> true </ filtering> <includes> <include> ** / * </ include> </ includes> <targetPath> META -INF / </ targetPath> </ resource> <resource> <directory> $ {project.build.directory} / dependency / </ directory> <includes> <include> *. jar </ include> </ includes> < targetPath> lib / </ targetPath> </ resource> </ resources>
Glaucio Southier

1
이 답변을 바탕 으로이 프로젝트를 만들었습니다. pom 파일을 제외하고는 아무것도 변경할 필요가 없습니다. github.com/raisercostin/jarinjarloader
raisercostin


0

이 게시물은 약간 오래되었지만 최근에도 같은 문제가있었습니다. John Stauffer가 제안한 첫 번째 해결책은 좋은 해결책이지만 이번 봄에 일할 때 약간의 문제가있었습니다. 내가 사용하는 스프링의 의존성 jar에는 동일한 경로와 이름을 공유하는 일부 속성 파일과 xml-chema 선언이 있습니다. 이 jar는 동일한 버전에서 제공되었지만 jar-with-dependencies maven-goal은 마지막 파일을 사용하여 이러한 파일을 덮어 썼습니다.

결국, 스프링 항아리가 올바른 특성 파일을 찾을 수 없어서 애플리케이션을 시작할 수 없었습니다. 이 경우 Rop이 제안한 솔루션으로 내 문제가 해결되었습니다.

그 이후로 스프링 부트 프로젝트가 존재합니다. 패키지 목표를 과부하시키고 자체 클래스 로더를 제공하는 maven 목표를 제공 하여이 문제를 관리하는 매우 멋진 방법이 있습니다. 보기 봄 부츠 참조 가이드를


0

이 답변을 살펴보십시오.

Java JAR 파일로 실행되는 설치 프로그램을 작성 중이며 WAR 및 JAR 파일을 설치 디렉토리의 적절한 위치에 압축 해제해야합니다. 종속성 플러그인은 복사 단계와 함께 패키지 단계에서 사용될 수 있으며 Maven 저장소의 파일 (WAR 파일 포함)을 다운로드하여 필요할 때마다 작성합니다. 출력 디렉토리를 $ {project.build.directory} / classes로 변경 한 후 일반 JAR 태스크에 파일이 제대로 포함되어 있습니다. 그런 다음 추출하여 설치 디렉토리에 쓸 수 있습니다.

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
    <execution>
        <id>getWar</id>
        <phase>package</phase>
        <goals>
            <goal>copy</goal>
        </goals>
        <configuration>
            <artifactItems>
                <artifactItem>
                    <groupId>the.group.I.use</groupId>
                    <artifactId>MyServerServer</artifactId>
                    <version>${env.JAVA_SERVER_REL_VER}</version>
                    <type>war</type>
                    <destFileName>myWar.war</destFileName>
                </artifactItem>
            </artifactItems>
            <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
    </execution>
</executions>


0

감사합니다 .POM.xml 파일에 아래 스 니펫을 추가하고 Mp 문제가 해결되어 모든 종속 항아리를 포함하는 뚱뚱한 항아리 파일을 만듭니다.

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <descriptorRefs>
                <descriptorRef>dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
</plugins>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.