8

Maven 어셈블리 플러그인을 사용하여 다중 모듈 프로젝트의 어셈블리를 만듭니다. 이 다중 모듈 프로젝트에는 각각 별도의 종속성 세트가있는 두 개의 개별 응용 프로그램이 있습니다. 모듈 빌드와 각각의 종속성을 가진 두 개의 디렉토리 (각 애플리케이션 용)를 어셈블하는 커스텀 어셈블리 디스크립터를 만들었다. 모든 것을 훌륭하게 수행하지만 한 가지만 - 두 모듈의 종속성을 서로의 어셈블리에 적용합니다.Maven 어셈블리 플러그인을 사용하여 다중 모듈 종속성 관리

다음은 정확하게 동일한 동작을하는 내 프로젝트의 단순화 된 버전입니다. 데모 순수

APP 
    module1 
    module2 
    assembly 

내가 추가 한 종속 관계 :

은 두 개의 모듈로 구성된 프로젝트와 어셈블리 모듈을 고려

<project> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    <packaging>pom</packaging> 

    <modules> 
    <module>module1</module> 
    <module>module2</module> 
    <module>assembly</module> 
    </modules> 
</project> 

: 여기

com.test.app:module1:jar:1.0 
\- commons-cli:commons-cli:jar:1.2:compile 

com.test.app:module2:jar:1.0 
\- commons-daemon:commons-daemon:jar:1.0.8:compile 

부모 POM의 module1 POM :

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>module1</artifactId> 
    <version>1.0</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>commons-cli</groupId> 
     <artifactId>commons-cli</artifactId> 
     <version>1.2</version> 
    </dependency> 
    </dependencies> 
</project> 

모듈 2의 POM :

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>module2</artifactId> 
    <version>1.0</version> 
    <packaging>jar</packaging> 

    <dependencies> 
    <dependency> 
     <groupId>commons-daemon</groupId> 
     <artifactId>commons-daemon</artifactId> 
     <version>1.0.8</version> 
    </dependency> 
    </dependencies> 
</project> 

조립 POM :

<project> 
    <parent> 
    <groupId>com.test</groupId> 
    <artifactId>app</artifactId> 
    <version>1.0</version> 
    </parent> 

    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.test.app</groupId> 
    <artifactId>assembly</artifactId> 
    <version>1.0</version> 
    <packaging>pom</packaging> 

    <build> 
    <plugins> 
     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <version>2.2.2</version> 

     <executions> 
      <execution> 
      <id>make-assembly</id> 
      <phase>package</phase> 

      <goals> 
       <goal>single</goal> 
      </goals> 
      </execution> 
     </executions> 

     <configuration> 
      <appendAssemblyId>false</appendAssemblyId> 

      <descriptors> 
      <descriptor>src/main/assembly/descriptor.xml</descriptor> 
      </descriptors> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 
</project> 

그리고 마지막으로, 조립 기술자 :

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>dir</format> 
    </formats> 

    <moduleSets> 
    <moduleSet> 
     <useAllReactorProjects>true</useAllReactorProjects> 

     <includes> 
     <include>com.test.app:module1:jar</include> 
     </includes> 

     <binaries> 
     <outputDirectory>module1</outputDirectory> 
     <unpack>false</unpack> 

     <dependencySets> 
      <dependencySet> 
      <unpack>false</unpack> 
      </dependencySet> 
     </dependencySets> 
     </binaries> 
    </moduleSet> 

    <moduleSet> 
     <useAllReactorProjects>true</useAllReactorProjects> 

     <includes> 
     <include>com.test.app:module2:jar</include> 
     </includes> 

     <binaries> 
     <outputDirectory>module2</outputDirectory> 
     <unpack>false</unpack> 

     <dependencySets> 
      <dependencySet> 
      <unpack>false</unpack> 
      </dependencySet> 
     </dependencySets> 
     </binaries> 
    </moduleSet> 
    </moduleSets> 
</assembly> 

당신이 볼 수 있듯이, 어셈블리 상을 패키지로 결합한다 . 그래서, 상위 디렉토리에서

mvn package 

실행할 때, 나는

module1/ 
    commons-cli-1.2.jar 
    commons-daemon-1.0.8.jar 
    module1-1.0.jar 
module2/ 
    commons-cli-1.2.jar 
    commons-daemon-1.0.8.jar 
    module2-1.0.jar 

기본적으로 다음과 같은 어셈블리를 가지고, 여기에 문제는 모듈 1은 공유지 - 데몬에 의존하지 않는, 그러나 조립 플러그인이 포함되어있다 의존. 마찬가지로 module2와 commons-cli도 있습니다.

왜 어셈블리 플러그인이 이런 식으로 행동하는지 설명 할 수 있습니까?

해결책은 무엇입니까?

+0

'maven-assembly-plugin'의 이상한 동작을 기대하지 않습니다 ... 부모로부터 어셈블리 프로젝트로 푸시 된 의존성이 없습니까? 어셈블리 프로젝트를 위해 생성 된 종속성 트리를 보여줍니다. –

+0

어셈블리 모듈의 종속성 트리는 POM에 종속성 선언이 없으므로 분명 비어 있습니다. – sertsy

답변

10

필자는 최종 결과가 예상 한 것이 아닌 다중 모듈 프로젝트에서 어셈블리 플러그인을 사용하여 비슷한 경험을 항상 해왔습니다. 왜 다른 사람이 그 일이 일어나는 지와 그 두 개념을 동시에 사용하는 것이 가장 정확한 답변을 제공해주기를 바랍니다.

즉, 가능한 해결 방법은 module1과 module2가 각각의 jar와 종속성을 포함하는 자체 어셈블리 아티팩트를 생성하는 것입니다. 그런 다음 형제 하위 모듈 pom 파일을 수정하여 형제 모듈에서 생성 된 배포 아티팩트에 대한 종속성을 가지 고이를 새 어셈블리로 압축을 풀 수 있습니다.

Module1과 Module2의 pom 파일 모두에서 어셈블리 하위 모듈과 마찬가지로 패키지 단계에 어셈블리 플러그인 구성을 추가 할 수 있습니다.

<build> 
    <plugins> 
     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <version>2.2.2</version> 

     <executions> 
      <execution> 
      <id>make-assembly</id> 
      <phase>package</phase> 
      <goals> 
       <goal>single</goal> 
      </goals> 
      </execution> 
     </executions> 

     <configuration> 
      <descriptors> 
      <descriptor>src/main/assembly/descriptor.xml</descriptor> 
      </descriptors> 
     </configuration> 
     </plugin> 
    </plugins> 
    </build> 

으로 Module1는 것 같은 SRC/주/조립/descriptor.xml이

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>zip</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <outputDirectory>module1</outputDirectory> 
     <unpack>false</unpack> 
    </dependencySet> 
    </dependencySets> 
</assembly> 

그리고 모듈 2는 비슷한 SRC/주/조립/descriptor.xml

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>zip</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <outputDirectory>module2</outputDirectory> 
     <unpack>false</unpack> 
    </dependencySet> 
    </dependencySets> 
</assembly> 
이있을 것이다

그런 다음 assembly/pom.xml에서 Module 1 및 2 zip 아티팩트를 종속성으로 추가합니다.

<dependencies> 
    <dependency> 
     <groupId>com.test.app</groupId> 
     <artifactId>module1</artifactId> 
     <version>1.0</version> 
     <type>zip</type> 
     <classifier>distribution</classifier> 
    </dependency> 
    <dependency> 
     <groupId>com.test.app</groupId> 
     <artifactId>module2</artifactId> 
     <version>1.0</version> 
     <type>zip</type> 
     <classifier>distribution</classifier> 
    </dependency> 
    </dependencies> 
,

... 어셈블리를 트림/SRC/주/조립/descriptor.xml 파일 나는이 주위에 하나의 가능한 일이 될 것 말했듯이

<assembly> 
    <id>distribution</id> 
    <includeBaseDirectory>false</includeBaseDirectory> 

    <formats> 
    <format>dir</format> 
    </formats> 

    <dependencySets> 
    <dependencySet> 
     <useTransitiveDependencies>false</useTransitiveDependencies> 
     <unpack>true</unpack> 
    </dependencySet> 
    </dependencySets> 

</assembly> 

처럼 불행하게도 많은 양을 추가하기 빌드 프로세스에 대한 추가 XML 구성 그러나 그것은 효과적이다.

+1

감사합니다. 회신을 위해, 키이스. 필자가 보았던 예제에서 부모 POM에서'mvn package'를 실행하면 module1을 먼저 어셈블하고 module2와 패키징 어셈블리 모듈은 처음 두 어셈블리를 함께 놓습니다. 그러나 이것은 별도의 어셈블리 모듈의 용도를 파괴합니다. 어셈블리를위한 별도의 모듈 뒤에있는 아이디어는 모든 모듈이 어셈블리가 만들어 질 때 만들어 졌는지 확인하는 것입니다. – sertsy

+0

module1에 대한 종속성 인 다른 module-module3이 있다고 가정합니다. module1의 패키지 단계에서 module3이 아직 빌드되지 않은 경우 module1은 어셈블리를 생성 할 수 없습니다 (어셈블리가 패키지 단계에 연결되어 있으므로). 이것이 어셈블리 모듈이 항상 마지막에 배치되어 다른 모듈이 이미 빌드되었는지 확인하는 이유입니다. 당신이 제안한 예가 제가 제시 한 예에서 효과가있을 것이지만, 그것이 올바른 방법은 아니라고 생각합니다. 나는 내 생각을 분명히했으면 좋겠다. – sertsy

+1

상위 pom에 나열된 모듈의 순서는 적합하지 않습니다. maven reactor는 올바른 빌드 순서로 모든 의존성을 구축 할 것입니다. 어셈블리 pom은 module1과 module2가 종속물로 나열되어 있기 때문에 수행 방법을 알고 있습니다. module3을 module1에 대한 종속성으로 추가하더라도 모듈 3을 먼저 작성한 다음 module1, module2를 조립품으로 마무리합니다. – Keith