source

메이븐과의 관계도 포함해서

factcode 2022. 8. 11. 21:55
반응형

메이븐과의 관계도 포함해서

maven(2.0.9)이 하나의 jar 파일에 모든 종속성을 포함하도록 강제하는 방법이 있습니까?

하나의 항아리 파일로 빌드하는 프로젝트가 있어요.의존 관계 클래스도 항아리에 복사해 주었으면 합니다.

업데이트: jar 파일에 jar 파일을 포함할 수 없습니다.의존관계로 지정된 항아리를 풀고 클래스 파일을 항아리에 패키지하는 방법을 찾고 있습니다.

이 작업은 "의존 관계가 있는 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>

Maven 2에서는 이 목적을 위해 미리 정의된 디스크립터 파일이 있는 Maven 2 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 파일을 작성하려면 메인 클래스도 설정해야 합니다.따라서 전체 구성은 다음과 같습니다.

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

음영 메이븐 플러그인이 있습니다.종속성을 패키징하고 이름을 변경하는 데 사용할 수 있습니다(클래스 경로의 종속성 문제를 제외).

새로 만든 항아리를 사용할 수 있습니다.<classifier>붙이다

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

위에서 설명한 jar-with-dependencies 접근법이 마음에 들지 않는 경우, maven-solution은 단순히 WAR-project를 구축하는 것입니다.설령 이것이 스탠드아론의 Java 어플리케이션일지라도,

  1. 일반 maven jar-project를 만듭니다.이 프로젝트는 (의존관계가 없는) jar 파일을 빌드합니다.

  2. 또한 maven war-project(빈 src/main/webapp/WEB-INF/web.xml 파일만 사용하여 maven-build의 경고/오류를 피할 수 있음)를 설정하고 jar-project를 종속성으로 합니다.<module>(이 전쟁 jar-file 를 zip파일로 정리하는 불과합니다).

  3. 전쟁 파일을 만들기 위해 전쟁 프로젝트를 구축합니다.

  4. 전개 단계에서 .war 파일의 이름을 *.zip으로 변경하고 압축을 풉니다.

이제 lib-directory(원하는 곳으로 이동할 수 있음)와 jar 및 응용 프로그램 실행에 필요한 모든 종속성이 있어야 합니다.

java -cp 'path/lib/*' MainClass

(클래스 패스의 와일드카드는 Java-6 이상에서 동작합니다).

이것은 maven에서 셋업하는 것(어셈블리 플러그인을 조작할 필요가 없음)과 어플리케이션 구조를 보다 명확하게 볼 수 있다고 생각합니다(모든 의존적인 jar의 버전 번호를 플레인 뷰에 표시해, 모든 것을 jar 파일에 짜넣는 것을 방지합니다).

http://fiji.sc/Uber-JAR 에서는 대체 방법에 대한 훌륭한 설명을 제공하고 있습니다.

uber-J를 구성하는 일반적인 방법은 세 가지가 있습니다.AR:

  1. 늘이지지 않않않않않모든 JAR 파일을 압축 해제한 후 단일 JAR로 다시 압축합니다.
    • Pro: Java의 기본 클래스 로더와 함께 작동합니다.
    • 단점: 같은 경로를 가진 여러 JAR 파일에 파일이 있습니다(META-INF/services/javax.script 등).Script Engine Factory)는 서로 덮어쓰며 결과적으로 동작에 장애가 발생합니다.
    • 도구: Maven 어셈블리 플러그인, Classworlds Uberjar
  2. 음영 처리됨. 음영 처리되지 않은 것과 동일하지만 모든 종속성의 패키지의 이름을 변경합니다(즉, "음영 처리").
    • Pro: Java의 기본 클래스 로더와 함께 작동합니다.일부(전부는 아님) 종속 버전 충돌을 방지합니다.
    • 단점: 같은 경로를 가진 여러 JAR 파일에 파일이 있습니다(META-INF/services/javax.script 등).Script Engine Factory)는 서로 덮어쓰며 결과적으로 동작에 장애가 발생합니다.
    • 도구: Maven Shad Plugin
  3. JARs 。JAR를 사용하다
    • 찬성: 종속 버전 충돌을 방지합니다.모든 리소스 파일이 보존됩니다.
    • 단점: Java가 랩된 JAR 파일에서 클래스를 로드할 수 있도록 하기 위해 특별한 "부트스트랩" 클래스로더를 번들해야 합니다.클래스 로더 문제의 디버깅은 복잡해집니다.
    • 도구: Eclipse JAR 파일 익스포터, One-JAR.

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/; 이 클래스로더는 1개의 자로 이루어진 클래스로더 중 매우 우수하며 매우 빠릅니다.

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

JIJConstants에서 "Rsrc-Class-Path"를 "Class-Path"로 편집합니다.
mvn 클린 의존관계: 복사 의존관계 패키지
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은 제쳐두고 JAR 라이브러리를 Main Jar 안에 넣을 수 있지만, 독자적인 클래스 로더를 사용해야 합니다.

이 프로젝트 확인:JAR 링크텍스트

아래 스니펫을 POM.xml 파일에 추가하고 Mp 문제를 해결하여 모든 종속 jar를 포함하는 fat jar 파일을 만듭니다.

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

저도 비슷한 걸 하려고 했는데 모든 항아리가 들어가는 걸 원치 않았어요.지정된 종속성의 특정 디렉토리를 포함하려고 합니다.또한 분류자 태그가 이미 사용 중이어서 다음을 수행할 수 없었습니다.

<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>
  1. maven-dependency-plugin과 unpack goal을 사용했습니다.
  2. 그리고 내가 원하는 걸 풀어서${project.build.directory}/classes그렇지 않으면 생략됩니다.
  3. 클래스 디렉토리에 있었기 때문에 메이븐은 마침내 그것을 항아리에 넣었다.
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>my.group</groupId>
                        <artifactId>my.artifact</artifactId>
                        <classifier>occupied</classifier>
                        <version>1.0</version>
                        <type>jar</type>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>${project.build.directory}/classes</outputDirectory>
                <includes>aaa/**, bbb/**, ccc/**</includes>
            </configuration>
        </execution>
    </executions>
</plugin>

이 게시물은 조금 오래된 것일 수도 있지만, 저도 최근에 같은 문제가 있었습니다.John Stauffer가 제안한 첫 번째 해결책은 좋은 해결책이지만, 저는 이번 봄에 일하느라 몇 가지 문제가 있었습니다.내가 사용하는 스프링의 종속성-jars에는 동일한 경로와 이름을 공유하는 몇 가지 속성 파일과 xml-schemas 선언이 있습니다.이러한 jars는 같은 버전이지만, dependencies maven-goal이 마지막으로 발견된 파일로 jar-with-dependencies maven-goal이 파일을 덮어쓰고 있었습니다.

결국 스프링 항아리가 올바른 속성 파일을 찾을 수 없었기 때문에 응용 프로그램을 시작할 수 없었습니다.이 경우 Rop이 제안한 솔루션이 제 문제를 해결했습니다.

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

이 답을 보세요.

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>

간단하게 하기 위해서, 이하의 플러그인을 사용할 수 있습니다.

             <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>
                                com.nirav.certificate.CertificateUtility
                            </mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

언급URL : https://stackoverflow.com/questions/1729054/including-dependencies-in-a-jar-with-maven

반응형