使用Maven程序集插件管理多模块依赖项 [英] Managing multi-module dependencies with Maven assembly plugin
问题描述
我使用Maven程序集插件为我的多模块项目创建一个程序集.从该多模块项目中构建了两个单独的应用程序,每个应用程序都有一组独立的依赖项.我制作了一个自定义程序集描述符,该描述符将两个目录(针对每个应用程序)与模块构建及其各自的依赖项进行汇编.它做的一切都很好,但有一件事情-将两个模块的依赖关系放到彼此的程序集中.
I use Maven assembly plugin to create an assembly for my multi-module project. There are two separate applications built from this multi-module project, each having a separate set of dependencies. I made a custom assembly descriptor which assembles two directories (for each application) with module builds and their respective dependencies. It does everything fine but one thing - it puts dependencies for both modules to each other's assembly.
以下是我的项目的简化版本,具有完全相同的行为.
The following is a simplified version of my project, that has exactly the same behavior.
考虑一个由两个模块和一个装配模块组成的项目:
Consider a project consisting of two modules and an assembly module:
APP
module1
module2
assembly
我纯粹是为了演示添加了依赖项:
I have added dependencies purely for demonstration:
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:
<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>
module1 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>
module2 POM:
module2 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>
如您所见,程序集绑定到打包阶段.所以,当我执行
As you can see, assembly is bind to package phase. So, when I execute
mvn package
在父目录中,我具有以下程序集
from parent directory, I have the following assembly
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
基本上,这里的问题是module1不依赖于commons-daemon,但是Assembly插件已经包含了依赖关系.同样,使用module2和commons-cli.
Basically, the problem here is that module1 does not depend on commons-daemon, but the assembly plugin has included the dependence. Similarly, with module2 and commons-cli.
有人可以解释为什么汇编插件会这样吗?
Can someone explain why the assembly plugin behaves this way?
什么是解决方案?
推荐答案
我一直在将组装插件与多模块项目结合使用时经历过类似的经历,但最终结果并非我所期望的那样.我希望其他人可以提供更准确的答案,以了解发生这种情况的原因以及如何最好地同时使用这两个概念.
I've always had similar experiences using the assembly plugin with multi-module projects where the end result wasn't what I expected. I hope someone else can provide a more accurate answer as to why that's happening and how best to use those two concepts in tandem.
也就是说,一种可能的解决方法是让module1和module2生成自己的程序集构件,其中包含它们各自的jar和依赖项.然后,您可以修改程序集子模块pom文件,使其对从其同级模块生成的分发工件具有依赖性,然后将其解压缩到新的程序集中.
That said, a possible work-around would be to have module1 and module2 generate their own assembly artifacts which contain their respective jars and dependencies. Then you can modify the assembly sub-module pom file to have dependencies on the generated distribution artifacts from its sibling modules and then unpack those into a new assembly.
在Module1和Module2的pom文件中,都可以将程序集插件配置添加到程序包阶段,就像对程序集子模块所做的一样.
In both Module1 and Module2's pom files you can add an assembly plugin configuration to your package phase much like you did with the assembly sub-module.
<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/main/assembly/descriptor.xml
Module1 would have a src/main/assembly/descriptor.xml like this
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>module1</outputDirectory>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>
并且Module2将具有类似的src/main/assembly/descriptor.xml
And Module2 will have a similar src/main/assembly/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中,将模块1和2 zip工件添加为依赖项
Then in the assembly/pom.xml you would add the Module 1 and 2 zip artifacts as dependencies
<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>
...并整理Assembly/src/main/assembly/descriptor.xml文件,使其看起来像这样
...and trim up the assembly/src/main/assembly/descriptor.xml file to look like this
<assembly>
<id>distribution</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>dir</format>
</formats>
<dependencySets>
<dependencySet>
<useTransitiveDependencies>false</useTransitiveDependencies>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>
就像我说的那样,这可能是一种可能的解决方法,不幸的是,这将为您的构建过程添加大量的其他XML配置.但这有效.
Like I said this would be one possible work around and unfortunately adds a significant amount of additional XML configuration to your build process. But it works.
这篇关于使用Maven程序集插件管理多模块依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!