【问题标题】:Apache Ivy and local Maven repo - how to handle snapshots built with Maven 3Apache Ivy 和本地 Maven 存储库 - 如何处理使用 Maven 3 构建的快照
【发布时间】: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 件事,但我不确定是否会有我没有想到的副作用。如果有人能对此有所了解,我将不胜感激:

  1. 对本地 .m2 存储库使用文件系统解析器,但推测缓存具有 useOrigin="true"(以及可选的低默认 TTL)。这样,似乎只有 xml 文件存储在 .ivy2 缓存中,而工件在 .m2 存储库中被引用,即它们没有被复制。

    这似乎可行,但我不确定第一次查找是否会从共享快照存储库 (Artifactory) 下载快照并且稍后将由本地构建更新。在这种情况下,我们最终可能会将工件的远程版本缓存在 .ivy2 中,并将较新的版本安装到 .m2 中,而 .pom 文件的日期在这两种情况下都是相同的。
  2. 使用带有 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 个。

标签: java ant maven-3 ivy


【解决方案1】:

...我们知道这种情况远非理想,我们正在评估 改善这一点的方法,但我们可以...

根据我的经验完全正常。许多大公司有很多混合了 ANT、Maven 和 Gradle 的项目。

以下是我将提出的一些建议

使用存储库管理器

集成这些不同技术的最佳方式是运行一个中间存储库来保存所有构建输出。这将有效地将您的构建步骤与以后使用二进制工件的方式分离。

推荐的存储库技术为 Maven 存储库(此时为 Java 标准),并且您可以选择可用的开源技术来托管您的存储库:

虽然运行额外的服务器可能看起来是一种开销,但随着依赖项目数量的增加(拥有单个大型共享文件系统无法扩展),它会大量收回成本。

无论如何,您都需要拥有发布二进制文件的参考副本。这些 Maven 存储库管理器允许您控制项目使用的第 3 方依赖项,并有助于缓存文件,这实际上会减少您的构建时间并简化共享依赖项管理。

最后,如何配置使用 Maven 存储库的 ivy 构建?如下使用 ibiblio 解析器(您会发现所有现代 Java 构建工具都对本地 Maven 存储库提供类似的支持)

<ivysettings>
    <settings defaultResolver="myrepo"/>
    <resolvers>
        <ibiblio name="myrepo" m2compatible="true" root="http://myrepo.com/path/to/repo"/>
    </resolvers>
</ivysettings>

注意快照版本

Snaphot 版本是 Maven 引入的一个概念,它是一个固执己见的构建框架。在我看来,使用它们时应该非常慎重:

正如您发现的那样,快照是不断变化的,在与期望不变的测试完美(如 QA)的小组共享时不能依赖快照。

以下讨论 Maven 发布管理方法的帖子塑造了我对此的想法:

最后,虽然我建议将快照的使用限制在密切合作的团队中,但 ivy 确实支持它们,但它们的使用存在一些众所周知的限制。因为它们是 Maven 构造,所以它们不是 100% 得到其他构建技术的支持。这是存储库管理器真正提供帮助的地方,因为他们能够重新生成正确的元数据以支持快照发布:

希望这会有所帮助。

【讨论】:

  • 感谢您的建议,我会调查的。我的问题可能不是很清楚,但我们已经在使用 Artifactory,它处理了我们链中的第三个解析器(ibiblio 一个)。我们的库最终部署在那里,但是在开发过程中,我们无法部署快照以免干扰其他人(并且在某些情况下,多个开发人员同时在同一个库上工作)-正如您所说,快照用于(本地) 仅用于开发。
  • @Thomas Ahh,抱歉,我错过了您问题中对 Artifactory 的提及。 ivy 文件系统解析器无法读取 Maven 元数据文件,这些文件告诉客户端哪个是最新的快照版本。值得庆幸的是 ibilio 解析器可以,但这意味着您需要将快照发布到 Artifactory。
  • 我查看了您发布的链接,但不幸的是,我没有看到任何可以立即帮助解决我们的问题的内容。但是,我尝试了一些事情并将其添加到我的问题中。如果你能看看那些,那就太好了。
猜你喜欢
  • 2013-05-10
  • 2010-12-13
  • 2014-03-27
  • 2011-03-30
  • 2020-03-05
  • 1970-01-01
  • 2014-12-22
  • 2015-07-24
相关资源
最近更新 更多