【问题标题】:How to have maven-assembly-plugin respect the exclusions defined in pom.xml?如何让 maven-assembly-plugin 尊重 pom.xml 中定义的排除项?
【发布时间】:2015-09-08 15:03:26
【问题描述】:

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>

程序集.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,但唯一的答案尝试对我的情况并不满意:

如果你有这样的事情,你需要定义两个dependencySet条目,其中一个包括logb​​ack [with useTransitiveDependencies=false] 和其他。

(khmarbaise)

使用maven-dependency-plugin

在the same question as above 上,有人提出了一种我可能会在没有问题的情况下使用的方法:首先使用dependency:copy-dependencies 将我的正确依赖项复制到一个临时目录,然后从该目录组装我的 zip。

作为一种变通方法,这可能是最有效的解决方案,因为它是通用的并且不会从程序集描述符中的 POM 中复制逻辑,尽管这会使构建时间更长。

附带问题:为什么?

为什么maven-assembly-plugin 会这样?我在文档中没有找到任何对此的参考。这是期望的行为,还是(已知/未知)错误?

【问题讨论】:

标签: maven maven-3 maven-assembly-plugin


【解决方案1】:

使用maven-dependency-plugin

虽然不是我正在寻找的最终解决方案,但这可能会对处于紧急情况的人有所帮助。

pom.xml

在您的 POM 中,定义以下属性(根据您的偏好调整路径):

<properties>
    <!-- ... -->
    <assembly.lib.directory>${project.build.directory}/lib</assembly.lib.directory>
    <!-- ... -->
</properties>

在&lt;build/&gt; 部分:

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

程序集.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之前运行。

【讨论】:

  • 注意——预打包阶段实际上称为“prepare-package”
【解决方案2】:

编辑

maven-assembly-plugin have been released Jan 01, 2019 的版本 3.1.1。它解决了我在下面的答案中提到的 JIRA 问题(保留历史记录或无法升级插件的用户)。在此版本中,maven-assembly-plugin 现在在依赖项排除项中支持通配符。只需升级插件。

回答maven-assembly-plugin 版本

Maven 程序集插件(版本 )似乎不支持使用通配符 (*) 的排除项,请参阅 MASSEMBLY-762、MASSEMBLY-861 或 MASSEMBLY-675。从上一个 JIRA 问题开始,该问题将在插件的版本3.1.1 中得到解决(请参阅commit)。 在撰写本文时,3.1.1 版本尚未发布:3.1.0 是最新版本。

希望可以使用

为此,只需声明正确的排除工件而不是 *,它就可以正常工作。列出所有排除的依赖项可能会很痛苦,但至少我认为它是一个比公认的解决方案更好的解决方案(对 Maven 阶段的调整较少),尤其是在具有交叉依赖关系的多模块项目上(我的情况)。此外,通过这样做,您可以更好地控制依赖关系。

希望对您有所帮助,等待3.1.1 版本! :)

【讨论】:

  • 嗨,很好的输入。谢谢!我没有接受我自己的答案,因为确实,我发现它很脏。请不要犹豫,尽快测试和更新插件。如果没问题,只需更新答案,您就会被接受。 :)(请在评论中通知我,以便我知道更新)
  • @Chop 我刚刚注意到新版本的maven-assembly-plugin 已在年初发布(它解决了您的问题)。我已经相应地更新了我的答案。
【解决方案3】:

我在 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] ------------------------------------------------------------------------

所以我必须在下面的 xhtmlrenderer 部分中为 bcprov-jdk14 添加一个排除项,如下示例 Maven Dependency Exclusions

<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 仍然将它们包含在它构建的包中。我不得不解决maven-dependency-plugin。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 1970-01-01
  • 2017-09-23
  • 2014-09-05
  • 1970-01-01
相关资源
最近更新 更多