如何让 maven-assembly-plugin 遵守 pom.xml 中定义的排除项?
How to have maven-assembly-plugin respect the exclusions defined in pom.xml?
TL;DR
当某些(特定的)传递依赖项被 排除在 POM 文件中 但 程序集描述符被设置为获取所有依赖项时 , 排除的依赖项将包含在程序集中。 我怎样才能避免这种情况?
一些背景知识
有些依赖项可能很难处理,因为它们的 groupIds 和 artifactIds 几乎在每个版本(在我的例子中是 bouncycastle)都会改变。
我正在检索几个版本的 bouncycastle(138、1.38、1.45 和 1.50)。我的目的是消除除 1.50 以外的所有版本。准确地说,我有一个依赖项(我们称之为 some.perfectly.done:job
)导入 1.50,另一个依赖项(how.many.castles:do-you-need
)导入所有其他项。它们是公司依赖项,因此给您真实的 groupId:artifactId 不会帮助您进行测试。
pom.xml
我的依赖声明如下:
<dependency>
<groupId>some.perfectly.done</groupId>
<artifactId>job</artifactId>
</dependency>
<dependency>
<groupId>how.many.castles</groupId>
<artifactId>do-you-need</artifactId>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>bouncycastle</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
<outputDirectory>lib</outputDirectory>
<outputFileNameMapping>${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<!-- ... -->
</assembly>
我得到什么
$ ls *bouncycastle*
bouncycastle.bcmail-jdk14-138.jar org.bouncycastle.bcmail-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15-1.45.jar
bouncycastle.bcprov-jdk14-138.jar org.bouncycastle.bcpkix-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15on-1.50.jar
org.bouncycastle.bcmail-jdk14-1.38.jar org.bouncycastle.bcprov-jdk14-1.38.jar org.bouncycastle.bctsp-jdk14-1.38.jar
我期望(和需要)的东西
$ ls *bouncycastle*
org.bouncycastle.bcmail-jdk15on-1.50.jar org.bouncycastle.bcpkix-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15on-1.50.jar
一些可能的线索可以建立在
此处答案的真正价值在于找到 真实、通用 解决方案。我不想解决 我的 案例,我想为所有有类似案例的人找到解决方案。
因此,我想避免一些可行但确实与特定情况相关并且通常需要将 POM 的逻辑复制到程序集描述符中的解决方案。
但是,如果找不到更好的方法,这些线索可能会有所帮助。
重现程序集描述符中的排除模式
很明显。但在我自己的例子中,除了巧妙地使用 includes
/excludes
之外,这是非常不切实际的。这不是一个实用的解决方案。
制作几个依赖集
请注意,我知道 this question has already been asked,但对我的情况来说,唯一的答案尝试并不令人满意:
If you have such thing you need to define two dependencySet entries one which include the logback [with useTransitiveDependencies=false
] and other.
(根据khmarbaise)
使用maven-dependency-plugin
在 the same question as above, an approach which I might use if no question is asked has been proposed: first use dependency:copy-dependencies
上将我的正确依赖项复制到一个临时目录,然后 assemble 从该目录压缩我的文件。
作为一种解决方法,这可能是最有效的解决方案,因为它是通用的并且不会在程序集描述符中复制 POM 的逻辑,尽管这会使构建时间更长。
附带问题:为什么?
为什么 maven-assembly-plugin
会这样?我在文档中没有找到对此的任何引用。这是期望的行为,还是 (known/unknown) 错误?
使用maven-dependency-plugin
虽然这不是我正在寻找的最终解决方案,但这可能会帮助处于紧急情况的人。
pom.xml
在您的 POM 中,定义以下内容 属性(根据您的喜好调整路径):
<properties>
<!-- ... -->
<assembly.lib.directory>${project.build.directory}/lib</assembly.lib.directory>
<!-- ... -->
</properties>
在<build/>
部分:
<build>
<plugins>
<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>${assembly.lib.directory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<prependGroupId>true</prependGroupId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
assembly.xml
想法是将 dependencySet
替换为 fileSet
:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<fileSets>
<fileSet>
<directory>${assembly.lib.directory}</directory>
<outputDirectory>lib</outputDirectory>
</fileSet>
<!-- ... -->
</fileSets>
</assembly>
编辑:作为highlighted by user716401,最好在prepare-package
阶段执行dependencies:copy-dependencies
以确保它在assembly:single
.
之前运行
我在 spring maven 项目中遇到了同样的问题。查看 pom.xml 文件,我有以下两个 bouncycastle 依赖项。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.50</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.50</version>
</dependency>
我能够安全地删除 bcprov-jdk15on
依赖块,因为在后续构建成功后似乎没有任何东西依赖它,但是,问题仍然存在。因此,我 运行 在将 pom.xml 文件中的依赖插件版本从 2.6 更新为 2.10 后,以下 maven 命令不起作用。
mvn dependency:tree -Dverbose -Dincludes=bouncycastle
这给出了输出:
[INFO] ------------------------------------------------------------------------
[INFO] Building dhtexasAdmin 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ dhtexasAdmin ---
[WARNING] Using Maven 2 dependency tree to get verbose output,
[INFO] com.dhtexasadmin:dhtexasAdmin:war:1.0
[INFO] \- org.xhtmlrenderer:core-renderer:jar:R8pre2:compile
[INFO] \- com.lowagie:itext:jar:2.1.0:compile
[INFO] +- bouncycastle:bcmail-jdk14:jar:136:compile
[INFO] \- bouncycastle:bcprov-jdk14:jar:136:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.324 s
[INFO] Finished at: 2017-04-21T16:58:52+01:00
[INFO] Final Memory: 16M/39M
[INFO] ------------------------------------------------------------------------
所以我必须按照示例 Maven Dependency Exclusions
在 xhtmlrenderer 部分添加 bcprov-jdk14 排除项,如下所示
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8pre2</version>
<exclusions>
<exclusion>
<artifactId>bcprov-jdk14</artifactId>
<groupId>bouncycastle</groupId>
</exclusion>
</exclusions>
</dependency>
之后 mvn clean
然后 mvn package
就成功了。
编辑
maven-assembly-plugin
have been released Jan 01, 2019 的版本 3.1.1
。它解决了我在下面的回答中提到的 JIRA 问题(保留历史或无法升级插件的用户)。在这个版本中,maven-assembly-plugin
现在在依赖项排除中支持通配符。只需升级插件即可。
maven-assembly-plugin
版本 <= 3.1.0
的答案
Maven 程序集插件(版本 <= 3.1.0)似乎不支持使用通配符排除(*
),请参阅 MASSEMBLY-762, MASSEMBLY-861 or MASSEMBLY-675. From the last JIRA issue, the problem will be solved in version 3.1.1
of the plugin (see commit) . 在撰写本文时,3.1.1
版本尚未发布:3.1.0
是最新版本。
希望版本 <= 3.1.0 可以解决问题。
为此,只需声明正确的排除工件而不是 *
,它就可以正常工作。列出所有排除的依赖项可能会很痛苦,但至少我认为这是一个比公认的解决方案更好的解决方案(对 Maven 阶段的调整较少),尤其是在具有交叉依赖项的多模块项目上(我的案例)。此外,通过这样做,您可以更好地控制依赖关系。
希望对您有所帮助,等待 3.1.1
版本! :)
TL;DR
当某些(特定的)传递依赖项被 排除在 POM 文件中 但 程序集描述符被设置为获取所有依赖项时 , 排除的依赖项将包含在程序集中。 我怎样才能避免这种情况?
一些背景知识
有些依赖项可能很难处理,因为它们的 groupIds 和 artifactIds 几乎在每个版本(在我的例子中是 bouncycastle)都会改变。
我正在检索几个版本的 bouncycastle(138、1.38、1.45 和 1.50)。我的目的是消除除 1.50 以外的所有版本。准确地说,我有一个依赖项(我们称之为 some.perfectly.done:job
)导入 1.50,另一个依赖项(how.many.castles:do-you-need
)导入所有其他项。它们是公司依赖项,因此给您真实的 groupId:artifactId 不会帮助您进行测试。
pom.xml
我的依赖声明如下:
<dependency>
<groupId>some.perfectly.done</groupId>
<artifactId>job</artifactId>
</dependency>
<dependency>
<groupId>how.many.castles</groupId>
<artifactId>do-you-need</artifactId>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>bouncycastle</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
<outputDirectory>lib</outputDirectory>
<outputFileNameMapping>${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
<!-- ... -->
</assembly>
我得到什么
$ ls *bouncycastle*
bouncycastle.bcmail-jdk14-138.jar org.bouncycastle.bcmail-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15-1.45.jar
bouncycastle.bcprov-jdk14-138.jar org.bouncycastle.bcpkix-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15on-1.50.jar
org.bouncycastle.bcmail-jdk14-1.38.jar org.bouncycastle.bcprov-jdk14-1.38.jar org.bouncycastle.bctsp-jdk14-1.38.jar
我期望(和需要)的东西
$ ls *bouncycastle*
org.bouncycastle.bcmail-jdk15on-1.50.jar org.bouncycastle.bcpkix-jdk15on-1.50.jar org.bouncycastle.bcprov-jdk15on-1.50.jar
一些可能的线索可以建立在
此处答案的真正价值在于找到 真实、通用 解决方案。我不想解决 我的 案例,我想为所有有类似案例的人找到解决方案。
因此,我想避免一些可行但确实与特定情况相关并且通常需要将 POM 的逻辑复制到程序集描述符中的解决方案。
但是,如果找不到更好的方法,这些线索可能会有所帮助。
重现程序集描述符中的排除模式
很明显。但在我自己的例子中,除了巧妙地使用 includes
/excludes
之外,这是非常不切实际的。这不是一个实用的解决方案。
制作几个依赖集
请注意,我知道 this question has already been asked,但对我的情况来说,唯一的答案尝试并不令人满意:
If you have such thing you need to define two dependencySet entries one which include the logback [with
useTransitiveDependencies=false
] and other.
(根据khmarbaise)
使用maven-dependency-plugin
在 the same question as above, an approach which I might use if no question is asked has been proposed: first use dependency:copy-dependencies
上将我的正确依赖项复制到一个临时目录,然后 assemble 从该目录压缩我的文件。
作为一种解决方法,这可能是最有效的解决方案,因为它是通用的并且不会在程序集描述符中复制 POM 的逻辑,尽管这会使构建时间更长。
附带问题:为什么?
为什么 maven-assembly-plugin
会这样?我在文档中没有找到对此的任何引用。这是期望的行为,还是 (known/unknown) 错误?
使用maven-dependency-plugin
虽然这不是我正在寻找的最终解决方案,但这可能会帮助处于紧急情况的人。
pom.xml
在您的 POM 中,定义以下内容 属性(根据您的喜好调整路径):
<properties>
<!-- ... -->
<assembly.lib.directory>${project.build.directory}/lib</assembly.lib.directory>
<!-- ... -->
</properties>
在<build/>
部分:
<build>
<plugins>
<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>${assembly.lib.directory}</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<prependGroupId>true</prependGroupId>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
assembly.xml
想法是将 dependencySet
替换为 fileSet
:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<!-- Adds dependencies to zip package under lib directory -->
<fileSets>
<fileSet>
<directory>${assembly.lib.directory}</directory>
<outputDirectory>lib</outputDirectory>
</fileSet>
<!-- ... -->
</fileSets>
</assembly>
编辑:作为highlighted by user716401,最好在prepare-package
阶段执行dependencies:copy-dependencies
以确保它在assembly:single
.
我在 spring maven 项目中遇到了同样的问题。查看 pom.xml 文件,我有以下两个 bouncycastle 依赖项。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.50</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.50</version>
</dependency>
我能够安全地删除 bcprov-jdk15on
依赖块,因为在后续构建成功后似乎没有任何东西依赖它,但是,问题仍然存在。因此,我 运行 在将 pom.xml 文件中的依赖插件版本从 2.6 更新为 2.10 后,以下 maven 命令不起作用。
mvn dependency:tree -Dverbose -Dincludes=bouncycastle
这给出了输出:
[INFO] ------------------------------------------------------------------------
[INFO] Building dhtexasAdmin 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ dhtexasAdmin ---
[WARNING] Using Maven 2 dependency tree to get verbose output,
[INFO] com.dhtexasadmin:dhtexasAdmin:war:1.0
[INFO] \- org.xhtmlrenderer:core-renderer:jar:R8pre2:compile
[INFO] \- com.lowagie:itext:jar:2.1.0:compile
[INFO] +- bouncycastle:bcmail-jdk14:jar:136:compile
[INFO] \- bouncycastle:bcprov-jdk14:jar:136:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.324 s
[INFO] Finished at: 2017-04-21T16:58:52+01:00
[INFO] Final Memory: 16M/39M
[INFO] ------------------------------------------------------------------------
所以我必须按照示例 Maven Dependency Exclusions
在 xhtmlrenderer 部分添加 bcprov-jdk14 排除项,如下所示<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8pre2</version>
<exclusions>
<exclusion>
<artifactId>bcprov-jdk14</artifactId>
<groupId>bouncycastle</groupId>
</exclusion>
</exclusions>
</dependency>
之后 mvn clean
然后 mvn package
就成功了。
编辑
maven-assembly-plugin
have been released Jan 01, 2019 的版本 3.1.1
。它解决了我在下面的回答中提到的 JIRA 问题(保留历史或无法升级插件的用户)。在这个版本中,maven-assembly-plugin
现在在依赖项排除中支持通配符。只需升级插件即可。
maven-assembly-plugin
版本 <= 3.1.0
的答案
Maven 程序集插件(版本 <= 3.1.0)似乎不支持使用通配符排除(*
),请参阅 MASSEMBLY-762, MASSEMBLY-861 or MASSEMBLY-675. From the last JIRA issue, the problem will be solved in version 3.1.1
of the plugin (see commit) . 在撰写本文时,。3.1.1
版本尚未发布:3.1.0
是最新版本
希望版本 <= 3.1.0 可以解决问题。
为此,只需声明正确的排除工件而不是 *
,它就可以正常工作。列出所有排除的依赖项可能会很痛苦,但至少我认为这是一个比公认的解决方案更好的解决方案(对 Maven 阶段的调整较少),尤其是在具有交叉依赖项的多模块项目上(我的案例)。此外,通过这样做,您可以更好地控制依赖关系。
希望对您有所帮助,等待 3.1.1
版本! :)