是的...大多数时候您应该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/mydep
EAR 的所有文件。一切安好。
- 第二次构建:
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
:首先清理输出目录,然后构建项目并验证结果。