Maven을 사용하여 종속성이있는 실행 가능한 JAR을 어떻게 만들 수 있습니까?


질문

 

배포를 위해 단일 실행 가능한 JAR에서 프로젝트를 패키지화하고 싶습니다.

Maven Project 패키지를 모든 종속성 항아리를 내 출력 항아리로 만들 수 있습니까?


답변

 

<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 설치 또는 배포 / 릴리스를 수행 할 때 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>
      <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>
  </plugins>
</build>


답변

종속성 플러그인을 사용하여 패키지 단계 앞에 별도의 디렉토리의 모든 종속성을 생성 한 다음 매니페스트의 클래스 경로에서 해당 사항을 포함 할 수 있습니다.

<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-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>

JAR 실행 가능 및 클래스 경로를 알게하십시오

<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 파일은 sibling ... 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>

이제 / $ {project.build.finalName} (zip | tar.bz2 | tar.gz) 각 jar 및 lib / *.


Apache Maven 어셈블리 플러그인

장단점 단점들 클래스 재배치 지원 없음 (클래스 재배치가 필요하면 Maven-Shade-Plugin 사용).

<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>

목표 / $ {project.bulid.finalname} -jar-with dependencies.jar가 있습니다.


Apache Maven Shade Plugin

장단점 단점들

<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>

/ $ {project.build.finalname} -shaded.jar를 대상으로합니다.


onejar-maven-plugin.

장단점 단점들 2012 년 이후 적극적으로 지원되지 않습니다.

<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>

스프링 부츠 Maven 플러그인

장단점 단점들 잠재적 인 불필요한 스프링 및 스프링 부팅 관련 클래스를 추가하십시오.

<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>

/ $ {project.bulid.finalname} -spring-boot.jar 대상이 있습니다.



답변

답이없는 대답을하고 그것을 다시 포맷하고, 우리는 다음과 같습니다.

<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에 추가하고 패키지 수명주기 이벤트에 바인딩하십시오.그러나 Gotcha는 어셈블리를 호출해야한다는 것입니다. 명령 줄에서 수동으로 실행하는 경우 '어셈블리 : 어셈블리'를 호출하는 동안 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를 사용하려고하면이 플러그인이 내 필요에 가장 적합한 것을 발견했습니다.

이 플러그인은 특히 특정 파일의 콘텐츠를 덮어 쓰는 대신에 병합 할 때 특히 유용합니다.이는 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-Shade Plugin을 사용하여 아래와 같이 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>
출처:https://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven