java - Maven ear 插件 - "doubled"artifact 不使用 clean

标签 java maven maven-ear-plugin

在通过 Maven ear 插件构建 ear 时,我遇到了应用 package 而不使用 clean 会导致不一致的结果:如果我更改依赖项的版本,依赖关系现在在耳朵中出现两次,在旧版本和新版本中。如果我在 jar 名称中构建没有版本号的 ear,我只会得到一个 jar,但旧版本不会被正确替换。

我看了源码

http://svn.apache.org/viewvc/maven/plugins/tags/maven-ear-plugin-2.10.1/src/main/java/org/apache/maven/plugin/ear/EarMojo.java?view=markup

特别是 436 行很有趣:检查是否更新目标中的文件,但显然只检查绝对路径和最后修改日期。

总结:更改依赖项(或其版本)总是需要在构建之前调用 clean 我是对的吗?还是我错过了 package 中的一些智能?

最佳答案

是的...大多数时候您应该在更改依赖项或任何其他构建配置时调用clean,否则以前的构建元素可能会与新构建发生冲突(就像你这里的情况一样)。一般来说,要确保以前的构建元素不会与新构建发生冲突,您应该事先调用 clean - 配置更改与否。

但也有异常(exception):如果您确定以前的构建元素不会影响您的新构建,您可以跳过clean。然而,大多数时候你不知道,或者跳过 clean 根本不可能不引起这样的冲突。我在下面详细解释。


当您使用 Maven 构建项目时,它会在 ${project.build.directory} 文件夹(默认为 target)下生成文件和其他元素。然后,这些元素用于在 package 阶段创建您的 Artifact (在您的案例中为 EAR)。

如果在构建后不调用 cleantarget 下的所有元素在下一次构建期间仍会存在并可能影响它。 Maven 插件如何区分并知道哪些元素来自旧版本或新版本?文件时间戳显然是不够的,除非使用一些模糊的机制来识别哪些文件来自哪个构建,否则很难做到。

If I change the version of a dependency, the dependency now appears twice in the ear, in the old and the new version.

这可能是因为您在 target 下的构建复制依赖项和您的打包插件会将整个目录包含到生成的 Artifact (在您的情况下为 EAR)中。例如,如果您使用不同的版本运行两次构建:

  • 第一次构建:mydep-1.0.jartarget/classes/mydep 中生成,您的插件包含来自 target/classes/mydep 进入 EAR。一切安好。
  • 第二次构建:mydep-2.0.jar 已生成,但 mydep-1.0.jar 仍在 target/classes/mydep 中。包括整个 target/classes/mydep 目录,并且两个版本最终都在 EAR 中。

If I build the ear without version numbers in the jar names, I get just one jar, but old versions are not replaced properly.

那是因为一些插件 - 用于优化 - 如果看到结果已经存在,将不会重新编译或重新执行操作。在您的情况下,正如您所指出的,EAR 插件可能会保留该文件的“旧”版本,因为它已经存在,实际上应该用同名的更新版本替换它。这可能是因为您没有指定版本:

  • 在第一种情况下,mydep-0.1.jar 已存在并创建了一个新的 mydep-0.2.jar 但两者都包含在您的 EAR 中
  • 现在,没有版本,你有 mydep.jar,它没有被最新版本覆盖,因为“它已经存在”,因此“旧”文件保留在原处并包含在耳朵。

结论:Maven 插件无法 100% 确定元素是来自以前的构建还是新构建。更新构建配置时,应始终调用 clean 以确保新旧构建元素之间不会发生冲突。即使没有构建配置更改,也可能需要调用 clean - 但这是另一回事。

我建议在运行构建时总是调用clean,除非不可能发生冲突并且它提供了一个真正的值(value),例如时间增益,因为重建整个项目太长或其他原因证明它。

编辑:根据@JF Meier 的来源请求,Running Maven guide根据 clean 目标和相关的不一致风险提供建议:

Inconsistent output

Most plugins are optimized to know if they have to execute their task. In some cases the output can be polluted from a previous build and the end result is not what you expected. In such rare situations you can call the clean phase which means: remove the output directory. You can also call it as mvn clean verify which means: first clean up the output directory, next build the project and verify the outcome.

关于java - Maven ear 插件 - "doubled"artifact 不使用 clean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47436946/

相关文章:

java - Java 版 IntelliJ : view as object by default

java - MongoDB : How to make findAndModify returns the Last Updated Record

java - 如何使用 Maven 编译 Java+Kotlin 项目?

java - Maven 阴影插件无法执行目标?

java - 重新编码从可调用返回值的 future

java - 如何让jOOQ生成不引用主键的复合外键?

java - Maven - 如何安装/部署带时间戳的快照

Maven:找不到处理 Castor、antrun 和 Ear 插件的市场条目

jakarta-ee - 在java EE中,我应该将哪些jar放在库目录中?

java - 使用 maven 构建耳朵