【发布时间】:2016-11-23 20:06:09
【问题描述】:
我们目前有一个项目设置,它使用 Ivy 进行依赖管理,使用 Ant 作为通用构建工具(尽管这可能与这里无关)。此外,我们有一堆用 Maven 构建的库,这些项目(我们有多个)依赖于这些库。我们知道这种情况远非理想,我们正在评估改进方法,但我们无法尽快改变。因此,我们必须利用我们目前拥有的东西。
总之,问题出在:它适用于 Maven 2 和 Ivy,但我们最近开始切换到 Maven 3,原因有几个(一个是更好地解决冲突),这种组合破坏了我们的构建。
首先,我将尝试描述我们的构建如何与 Maven 2 和 Ivy 一起工作。之后,我将添加切换到 Maven 3 时出现问题的地方。
常春藤 + Maven 2
在开发我们的库的新版本时,我们使用的是安装在本地 Maven 存储库 (.m2) 中的 SNAPSHOT 版本。此外,我们将这些快照部署到我们的 Artifactory 中,以便能够共享中间构建以实现一些并行开发。
然后我们的项目声明对这些快照的依赖关系。对应的ivysettings.xml如下所示:
<ivysettings>
<settings defaultResolver="default" />
<include url="${ivy.default.settings.dir}/ivysettings-local.xml" />
<resolvers>
<ibiblio name="public" root="path.to.our.artifactory" m2compatible="true" />
<filesystem name="local-maven2" m2compatible="true" checkmodified="true" changingPattern=".*SNAPSHOT">
<ivy pattern="${user.home}/.m2/repository/[organisation]/[module]/[revision]/[module]-[revision].pom" />
<artifact pattern="${user.home}/.m2/repository/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
</filesystem>
<filesystem name="local" checkmodified="true" changingPattern=".*SNAPSHOT">
<ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}" />
<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
</filesystem>
<filesystem name="local2" checkmodified="true" changingPattern=".*SNAPSHOT">
<ivy pattern="${user.home}/.ivy2/cache/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="${user.home}/.ivy2/cache/[organisation]/[module]/[artifact]-[revision].[ext]" />
</filesystem>
<chain name="default" checkmodified="true" changingPattern=".*SNAPSHOT">
<resolver ref="local" />
<resolver ref="local-maven2" />
<resolver ref="public" />
</chain>
</resolvers>
<include url="${ivy.default.settings.dir}/ivysettings-shared.xml" />
</ivysettings>
由于此设置,Ivy 应该寻找更新版本的快照并正确解决该问题。通过比较相应 .pom 文件的文件日期来识别较新的版本。
当我们使用 Maven 2 构建快照时,相应的 .pom 将获取当前构建的文件日期,因此该检查有效并且 Ivy 解析正确的快照版本。
常春藤 + Maven 3
上述解决方案在使用 Maven 3 构建快照时会中断。原因似乎是安装的 .pom 文件没有将当前时间戳作为其文件日期,而是保留了原始 pom.xml 的文件日期被复制。因此,Ivy 无法检测快照是否更新。
似乎 Maven 3 将更新时间戳存储在 maven-metadata-local.xml 中,但 Ivy 不读取这些。我们知道有 ibiblio 解析器(我们正在使用),但根据我们所知道的(例如来自this 之类的问题),它旨在与真正删除存储库一起使用,并且在应用于本地 .m2 时可能会产生问题回购。
我们还考虑过跟踪其他文件的文件日期,例如maven-metadata-local.xml 或实际的工件,但我们不确定这是否明智或会在其他情况下破坏构建。
那么我们应该/可以如何解决这个问题?
TL;DR
在使用 Maven 3 构建并部署在本地 .m2 存储库中的快照上处理 Ivy 依赖项的标准/建议方法是什么?
2016 年 7 月 26 日更新
这是我尝试解决问题的 2 件事,但我不确定是否会有我没有想到的副作用。如果有人能对此有所了解,我将不胜感激:
- 对本地 .m2 存储库使用文件系统解析器,但推测缓存具有
useOrigin="true"(以及可选的低默认 TTL)。这样,似乎只有 xml 文件存储在 .ivy2 缓存中,而工件在 .m2 存储库中被引用,即它们没有被复制。
这似乎可行,但我不确定第一次查找是否会从共享快照存储库 (Artifactory) 下载快照并且稍后将由本地构建更新。在这种情况下,我们最终可能会将工件的远程版本缓存在 .ivy2 中,并将较新的版本安装到 .m2 中,而 .pom 文件的日期在这两种情况下都是相同的。 - 使用带有
root="file://${user.home}/.m2/repository/"的 ibiblio 解析器,它似乎能够解析大多数工件(例外见下文),但在读取元数据时似乎仍然失败,即它不会使用更新的版本更新缓存可以在 .m2 存储库中找到。
虽然能够解析 .m2 存储库中的大多数工件,但在工件存在时,我似乎遇到了一些“url”的解析错误,例如file://{user.home}/.m2/repository/javax/enterprise/cdi-api/1.0/cdi-api-1.0.jar,即我直接从 Windows 资源管理器复制了路径,它是"${user.home}\.m2\repository\javax\enterprise\cdi-api\1.0\cdi-api-1.0.jar"。
【问题讨论】:
-
为什么使用 ibiblio 解析器会惹恼你?您使用远程存储库。
-
@davidhxxx 问题不是删除 repo 或 ibiblio 解析器,但基本上我们在构建项目时有 3 层:1. ivy cache 2. local m2 repo 3. remote repo - 我们需要全部 3 个。