我有一个多模块 Maven 项目,我想在一个模块中在构建期间创建两个 Artifact :
- 主要 Artifact 是其他一些模块将依赖的 jar 库。
- 执行一些辅助函数的可执行 jar 文件。没有其他模块依赖于此,它只供用户在某些情况下手动运行。
这是我用来配置 maven-assembly-plugin
插件的代码:
<plugin>
<artifactId>
maven-assembly-plugin
</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>dist-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>bso</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>helper-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>HelperMain<mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
我将 appendAssemblyId
设置为 false
因为否则 -jar-with-dependencies
将附加到最终名称,我看不到对它的需要。省略它可以使文件名更简洁、更易于使用。
当我运行 mvn integration-test
时,我会收到以下警告:
[WARNING] Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing. Instead of attaching the assembly file: [...]/target/helper-5.0.0-SNAPSHOT.jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: [...]/target/my.module-5.0.0-SNAPSHOT.jar with assembly file: [...]/target/helper-5.0.0-SNAPSHOT.jar
有两件事让我恼火:
尽管警告声称它将用 helper-5.0.0-SNAPSHOT.jar 替换 my.module-5.0.0-SNAPSHOT.jar 它实际上并没有这样做,并且当构建完成时文件的大小仍然不同。
为什么会出现更换 Artifact 的警告?
似乎
classifier
已被弃用,为什么警告要求我使用它?
最佳答案
那是因为您误解了警告。
让我们回顾一下。不属于 pom
类型的 Maven 项目默认情况下,将始终生成所谓的主 Artifact 。对于 JAR,此 Artifact 是将编译后的源打包成 JAR 的结果;对于 WAR,它是构建 Web 应用程序的结果。
需要记住的重要一点是,这个 Artifact 附加到项目中:这个术语在项目安装(使用 mvn install
)、部署(使用 mvn deploy
)或发布时很有用(使用 maven-release-plugin
)。 Attached 表示该 Artifact 将在项目完成时安装/部署/发布。并非所有在 Maven 构建期间生成的文件(基本上是 target
文件夹下的所有文件)都是;只有附加的文件。因此,您可以很好地在 target
下创建大量文件。但只有一个已安装的 Artifact 。
除了这个主要 Artifact ,您可能希望您的构建生成其他 Artifact 以进行安装或部署。这就是附加或次要附加 Artifact 的概念。主要的例子是 Javadoc 或源代码:通常当一个项目发布时,它的 Javadoc 和它的源代码也是如此。这就是the notion classifier
kicks in .
在 Maven 存储库中,每个文件都必须遵循相同的命名约定:artifactId-version(-classifier).type
.每个辅助 Artifact 都将具有与主 Artifact 相同的 GAV(组 ID、 Artifact ID、版本),因此如果您想放入 Maven 存储库中,则需要 1 个主 Artifact 和 1 个附加 Artifact (就像主 JAR 的情况一样)使用它的 JAR Javadoc 和 JAR 源),您需要一些方法来区分它们。这是classifier
用于:区分次要 Artifact 和主要 Artifact 。
现在让我们回到您的示例。您的 Maven 项目,位于 jar
打包,默认情况下会生成一个名为 my.module-5.0.0-SNAPSHOT.jar
的主要 JAR Artifact ;仍然默认情况下,这个主 JAR 附加到项目(并准备好安装/部署)。现在您正在配置 maven-assembly-plugin
创建一个新的 JAR Artifact (称为 helper-5.0.0-SNAPSHOT.jar
,但这并不重要)。程序集插件,默认为 attaches to the project the artifact it produces .所以你最终会得到 2 个附加的 Artifact
- 具有与
my.module
相同的 Artifact ID ;事实上,磁盘上的文件target
文件夹名为helper
因为一个无关紧要,只有 GAV 坐标很重要 - 拥有相同版本的
5.0.0-SNAPSHOT
- 具有相同的 JAR 包装
并且没有分类器来区分它们。这就是引发警告的原因:您最终会在项目中附加一个有效替换主要 Artifact 的次要 Artifact ,仅仅是因为它具有相同的坐标。所以结果是:
target
内磁盘上的两个文件具有不同的名称,但这无关紧要,因为- 两者共享相同的坐标,因此只有 1 个能够存活。
它是由Assembly Plugin 产生的,将赢得冲突,并替换附加的主要 Artifact 。
如果您想说服自己相信这一切,请运行 mvn clean install
在项目上并检查您的本地仓库。您会注意到只有 jar-with-dependencies
Artifact 将被安装。另一个(主要 Artifact )失败了。
您还可以配置 <distributionManagement>
:
<distributionManagement>
<repository>
<id>local-repo-test</id>
<url>file://...</url>
</repository>
</distributionManagement>
并调用 mvn clean deploy
.然后,您可以检查唯一部署的 Artifact 是 jar-with-dependencies
.
最后说明:是的, classifier
不推荐使用 Assembly Plugin 的参数,因为您应该只使用程序集 id 作为分类器。
关于java - maven-assembly-plugin:如何使用 appendAssemblyId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38482839/