17

在通过 Maven ear 插件构建 ear 时,我体验到应用packagewithoutclean会导致结果不一致:如果我更改依赖项的版本,则该依赖项现在在 ear 中出现两次,旧版本和新版本。如果我在 jar 名称中构建没有版本号的耳朵,我只会得到一个 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=标记

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

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

4

3 回答 3

11

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

但也有例外:如果您确定以前的构建元素不会影响您的新构建,则可以跳过clean. 但是,大多数情况下您无法知道,或者clean如果不引起此类冲突,则根本不可能跳过。我在下面详细解释。


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

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

如果我更改依赖项的版本,则该依赖项现在会在耳朵中出现两次,在旧版本和新版本中。

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

  • 首次构建:mydep-1.0.jar在其中生成target/classes/mydep,您的插件包含来自target/classes/mydepEAR 的所有文件。一切安好。
  • 第二次构建:mydep-2.0.jar已生成但mydep-1.0.jar仍在target/classes/mydep. 整个target/classes/mydep目录都包含在内,并且两个版本都包含在 EAR 中。

如果我在 jar 名称中构建没有版本号的耳朵,我只会得到一个 jar,但旧版本没有被正确替换。

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

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

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

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

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

输出不一致

大多数插件都经过优化,可以知道它们是否必须执行它们的任务。在某些情况下,输出可能会被以前的构建污染,最终结果不是您所期望的。在这种罕见的情况下,您可以调用clean阶段,这意味着:删除输出目录。您也可以这样称呼它mvn clean verify:首先清理输出目录,然后构建项目并验证结果。

于 2017-11-26T15:10:34.793 回答
4

通过编译最新版本的 maven-ear-plugin(3.0.0,比 2.10.2 更新,本身比官方的 2.12.1更新)查看问题是否仍然存在

正如您在最新代码EarMojo.java中看到的那样,该功能copyModules()已从2.10.1 实现更改,并且可能更加健壮。

于 2017-11-25T22:39:56.160 回答
0

ear存档将所有项目依赖项捆绑到一个 zip 中(遵循由 ear 格式指定的结构)。归档分两个阶段构建,首先 ear-maven-plugin 收集项目依赖项,然后创建归档。这些依赖项被复制到 ${project.build.directory} 中。

因此,clean应该始终与此插件一起使用,以防止由于将依赖项附加到先前执行可能复制了依赖项的另一个快照的目录而导致的任何不一致。如果跳过 clean 阶段,${project.build.directory} 目录将不会被截断,这很可能会导致构建的包不一致。

于 2017-12-02T08:26:52.780 回答