Apache Ivy和本地Maven仓库 - 如何处理使用Maven 3构建的快照版本

9
我们目前的项目使用Ivy进行依赖管理和Ant作为通用构建工具(虽然这里可能不相关)。此外,我们还有一堆库是使用Maven构建的,并且项目(我们有多个)依赖于它们。我们知道这种情况远非理想,正在评估改进方式,但我们不能像我们想的那样快速更改。因此,我们必须在目前拥有的基础上工作。
无论如何,问题在于:它可以与Maven 2和Ivy配合使用,但最近我们开始转向Maven 3,原因有几个(包括更好的冲突解决),但这种组合破坏了我们的构建过程。
首先,我将尝试描述我们如何使用Maven 2和Ivy进行构建。之后,我会添加在切换到Maven 3时出现的问题。
Ivy + Maven 2
当开发我们的库的新版本时,我们使用SNAPSHOT版本,这些版本安装到本地Maven存储库(.m2)中。此外,我们将这些快照部署到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会解析正确的快照版本。
Ivy + Maven 3
上述解决方案在使用Maven 3构建快照时会出现问题。原因似乎是已安装的.pom文件不会获得当前时间戳作为其文件日期,而是保留了复制的原始pom.xml的文件日期。因此,Ivy无法再检测快照是否更新。
似乎Maven 3将更新时间戳存储在maven-metadata-local.xml中,但Ivy不会读取这些内容。我们知道有ibiblio解析器(我们正在使用),但根据我们所知(例如从这里的问题),它适用于真正的远程存储库,并且在应用于本地.m2 repo时可能会产生问题。
我们也考虑跟踪其他文件的文件日期,例如maven-metadata-local.xml或实际工件,但我们不确定这是否明智,或者是否会在其他情况下破坏构建。
那么我们应该/可以如何解决?
TL;DR
处理使用Maven 3构建并在本地.m2 repo中部署的快照的Ivy依赖关系的标准/建议方法是什么?
更新2016-07-26
以下是我尝试解决问题的两件事,但我不确定是否会有任何我没有考虑到的副作用。如果有人能为此提供一些启示,我将不胜感激:
  1. 使用文件系统解析器来管理本地.m2仓库,但与一个缓存一起使用,该缓存具有useOrigin="true"(可选低defaultTTL)。这样看起来只有xml文件存储在.ivy2缓存中,而工件则在.m2存储库中引用,即它们不会被复制。

    这似乎可以工作,但我不确定如果第一次查找会从共享快照存储库(Artifactory)下载快照,并且稍后由本地构建更新,是否会起作用。在这种情况下,我们可能会在.ivy2中缓存远程版本的工件,并在.m2中安装更新版本,.pom文件日期在两种情况下都相同。
  2. 使用ibiblio解析器和root="file://${user.home}/.m2/repository/",它似乎能够解析大多数工件(以下是例外情况),但在读取元数据时仍然会失败,即它不会使用在.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解析器会让你感到烦恼?你使用的是远程存储库。 - davidxxx
@davidhxxx,问题不在于删除存储库或ibiblio解析器,而是我们构建项目时有三个层次:1. ivy缓存 2. 本地m2存储库 3. 远程存储库 - 我们需要全部三个。 - Thomas
1个回答

5

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

在我的经验中,这是完全正常的。许多大型公司都有许多使用ANT、Maven和越来越多Gradle混合构建的项目。

以下是我要提出的一些建议:

使用存储库管理器

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

推荐的存储库技术是Maven存储库(目前Java标准),您可以选择开源技术来托管您的存储库:

虽然运行额外的服务器可能看起来是一个负担,但随着依赖项目数量的增加,它会得到回报(使用单个大型共享文件系统无法扩展)。

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

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

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

注意快照版本的风险

快照版本是Maven引入的概念,它是一种有偏见的构建框架。在我看来,使用它们时应该非常谨慎:

正如你所发现的那样,快照版本不断变化,不能保证与期望进行测试的团队共享一个稳定的版本(例如QA测试)。

我的想法受到以下文章的影响,它讨论了Maven的发布管理方法:

最后,虽然我建议将快照版本的使用限制在密切合作的团队中,但Ivy确实支持它们,只是它们的使用存在一些已知的限制。因为它们是Maven的构造物,所以其他构建技术并不完全支持它们。这就是Repository Manager真正帮助的地方,因为它们能够重新生成正确的元数据以支持快照版本:

希望这可以帮到你。


感谢您的建议,我会仔细研究。也许我的问题没有表达清楚,但我们已经在使用Artifactory了,它处理了我们链中的第三个解析器(即ibiblio)。我们的库最终部署在那里,但在开发过程中,我们不能部署快照,以免干扰其他开发者(有多个开发者同时在处理同一库的情况),正如您所说,快照仅供(本地)开发使用。 - Thomas
@Thomas 啊,抱歉我在你的问题中错过了对Artifactory的引用。Ivy文件系统解析器无法读取Maven元数据文件,这些文件告诉客户端哪个是最新的快照版本。幸运的是,ibilio解析器可以,但这意味着您需要将快照发布到Artifactory。 - Mark O'Connor
我看了你发的链接,但很遗憾没有看到能够立即解决我们问题的内容。不过,我尝试了一些方法并将它们添加到我的问题中。如果你能看一下那些内容就太好了。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接