maven-assembly-plugin:如何使用 appendAssemblyId
maven-assembly-plugin: How to use appendAssemblyId
我有一个多模块 Maven 项目,在一个模块中我想在构建期间创建两个工件:
- 主要工件是一个 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 但它不会实际上这样做,当构建完成时,两个文件的大小仍然不同。
为什么会出现更换神器的警告?
好像classifier
已经弃用了为什么警告要我使用它?
那是因为你误解了警告。
让我们回顾一下。默认情况下,非 pom
类型的 Maven 项目将始终生成所谓的主工件。对于 JAR,此工件是将编译后的源代码打包到 JAR 中的结果;对于 WAR,它是构建网络应用程序的结果。
要记住的重要一点是,此工件 附加 到项目:此术语在项目安装(使用 mvn install
)、部署(使用 mvn deploy
) 或发布(使用 maven-release-plugin
)。 Attached表示这个工件会在项目运行时安装/部署/发布。并非所有在 Maven 构建期间生成的文件(基本上,target
文件夹下的所有文件)都是;只有附加的文件。因此,您可以很好地在 target
下创建大量文件,但只有一个已安装的工件。
除了这个主要工件,您可能希望您的构建生成其他工件以进行安装或部署。这就是附加或次要附加工件的概念。主要示例是 Javadoc 或源代码:通常在发布项目时,它的 Javadoc 和源代码也会发布。这就是 the notion classifier
kicks in.
在 Maven 存储库中,每个文件都必须遵循相同的命名约定:artifactId-version(-classifier).type
。每个次要工件都将具有与主要工件相同的 GAV(组 ID、工件 ID、版本),因此如果您想在 Maven 存储库中放入 1 个主要工件和 1 个附加工件(就像主 JAR 的情况一样)及其 JAR Javadoc 和 JAR 源),您需要一些方法来区分它们。 classifier
的用途是:区分次要工件和主要工件。
现在让我们回到您的示例。您的 jar
打包的 Maven 项目将默认生成一个名为 my.module-5.0.0-SNAPSHOT.jar
的主 JAR 工件;默认情况下,这个主 JAR 仍然附加到项目(并准备好安装/部署)。现在您正在配置 maven-assembly-plugin
以创建一个新的 JAR 工件(称为 helper-5.0.0-SNAPSHOT.jar
但它真的无关紧要)。 Assembly 插件,默认情况下,attaches to the project the artifact it produces。所以你最终得到了 2 个附加的工件
- 具有与
my.module
相同的工件 ID; target
文件夹中磁盘上的文件被命名为 helper
的事实是无关紧要的,只有 GAV 坐标才重要
- 具有相同版本的
5.0.0-SNAPSHOT
- 具有与 JAR 相同的包装
并且没有分类器来区分它们。这就是引发警告的原因:您最终将一个次要工件附加到项目,该次要工件有效地替换了主要工件,仅仅是因为它具有相同的坐标。所以结果是:
- 两个文件在
target
内的磁盘上具有不同的名称,但这无关紧要,因为
- 两者共享相同的坐标,因此只有 1 个幸存。
是Assembly Plugin产生的那个会在冲突中获胜,并替换掉附属的主神器
如果您想说服自己相信所有这些,请在项目上 运行 mvn clean install
并检查您的本地存储库。您会注意到只会安装 jar-with-dependencies
工件。另一个(主要神器)发出了噗声。
你也可以配置一个<distributionManagement>
:
<distributionManagement>
<repository>
<id>local-repo-test</id>
<url>file://...</url>
</repository>
</distributionManagement>
并调用 mvn clean deploy
。然后您可以检查唯一部署的工件将是 jar-with-dependencies
.
最后说明:是的,Assembly 插件的 classifier
参数已弃用,因为您应该只使用程序集 ID 作为分类器。
我有一个多模块 Maven 项目,在一个模块中我想在构建期间创建两个工件:
- 主要工件是一个 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 但它不会实际上这样做,当构建完成时,两个文件的大小仍然不同。
为什么会出现更换神器的警告?
好像
classifier
已经弃用了为什么警告要我使用它?
那是因为你误解了警告。
让我们回顾一下。默认情况下,非 pom
类型的 Maven 项目将始终生成所谓的主工件。对于 JAR,此工件是将编译后的源代码打包到 JAR 中的结果;对于 WAR,它是构建网络应用程序的结果。
要记住的重要一点是,此工件 附加 到项目:此术语在项目安装(使用 mvn install
)、部署(使用 mvn deploy
) 或发布(使用 maven-release-plugin
)。 Attached表示这个工件会在项目运行时安装/部署/发布。并非所有在 Maven 构建期间生成的文件(基本上,target
文件夹下的所有文件)都是;只有附加的文件。因此,您可以很好地在 target
下创建大量文件,但只有一个已安装的工件。
除了这个主要工件,您可能希望您的构建生成其他工件以进行安装或部署。这就是附加或次要附加工件的概念。主要示例是 Javadoc 或源代码:通常在发布项目时,它的 Javadoc 和源代码也会发布。这就是 the notion classifier
kicks in.
在 Maven 存储库中,每个文件都必须遵循相同的命名约定:artifactId-version(-classifier).type
。每个次要工件都将具有与主要工件相同的 GAV(组 ID、工件 ID、版本),因此如果您想在 Maven 存储库中放入 1 个主要工件和 1 个附加工件(就像主 JAR 的情况一样)及其 JAR Javadoc 和 JAR 源),您需要一些方法来区分它们。 classifier
的用途是:区分次要工件和主要工件。
现在让我们回到您的示例。您的 jar
打包的 Maven 项目将默认生成一个名为 my.module-5.0.0-SNAPSHOT.jar
的主 JAR 工件;默认情况下,这个主 JAR 仍然附加到项目(并准备好安装/部署)。现在您正在配置 maven-assembly-plugin
以创建一个新的 JAR 工件(称为 helper-5.0.0-SNAPSHOT.jar
但它真的无关紧要)。 Assembly 插件,默认情况下,attaches to the project the artifact it produces。所以你最终得到了 2 个附加的工件
- 具有与
my.module
相同的工件 ID;target
文件夹中磁盘上的文件被命名为helper
的事实是无关紧要的,只有 GAV 坐标才重要 - 具有相同版本的
5.0.0-SNAPSHOT
- 具有与 JAR 相同的包装
并且没有分类器来区分它们。这就是引发警告的原因:您最终将一个次要工件附加到项目,该次要工件有效地替换了主要工件,仅仅是因为它具有相同的坐标。所以结果是:
- 两个文件在
target
内的磁盘上具有不同的名称,但这无关紧要,因为 - 两者共享相同的坐标,因此只有 1 个幸存。
是Assembly Plugin产生的那个会在冲突中获胜,并替换掉附属的主神器
如果您想说服自己相信所有这些,请在项目上 运行 mvn clean install
并检查您的本地存储库。您会注意到只会安装 jar-with-dependencies
工件。另一个(主要神器)发出了噗声。
你也可以配置一个<distributionManagement>
:
<distributionManagement>
<repository>
<id>local-repo-test</id>
<url>file://...</url>
</repository>
</distributionManagement>
并调用 mvn clean deploy
。然后您可以检查唯一部署的工件将是 jar-with-dependencies
.
最后说明:是的,Assembly 插件的 classifier
参数已弃用,因为您应该只使用程序集 ID 作为分类器。