在通过 Maven ear 插件构建 ear 时,我遇到了应用 package
而不使用 clean
会导致不一致的结果:如果我更改依赖项的版本,依赖关系现在在耳朵中出现两次,在旧版本和新版本中。如果我在 jar 名称中构建没有版本号的 ear,我只会得到一个 jar,但旧版本不会被正确替换。
我看了源码
特别是 436 行很有趣:检查是否更新目标中的文件,但显然只检查绝对路径和最后修改日期。
总结:更改依赖项(或其版本)总是需要在构建之前调用 clean
我是对的吗?还是我错过了 package
中的一些智能?
最佳答案
是的...大多数时候您应该在更改依赖项或任何其他构建配置时调用clean
,否则以前的构建元素可能会与新构建发生冲突(就像你这里的情况一样)。一般来说,要确保以前的构建元素不会与新构建发生冲突,您应该事先调用 clean
- 配置更改与否。
但也有异常(exception):如果您确定以前的构建元素不会影响您的新构建,您可以跳过clean
。然而,大多数时候你不知道,或者跳过 clean
根本不可能不引起这样的冲突。我在下面详细解释。
当您使用 Maven 构建项目时,它会在 ${project.build.directory}
文件夹(默认为 target
)下生成文件和其他元素。然后,这些元素用于在 package
阶段创建您的 Artifact (在您的案例中为 EAR)。
如果在构建后不调用 clean
,target
下的所有元素在下一次构建期间仍会存在并可能影响它。 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.jar
在target/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 asmvn 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/