我们目前的项目使用Ivy进行依赖管理和Ant作为通用构建工具(虽然这里可能不相关)。此外,我们还有一堆库是使用Maven构建的,并且项目(我们有多个)依赖于它们。我们知道这种情况远非理想,正在评估改进方式,但我们不能像我们想的那样快速更改。因此,我们必须在目前拥有的基础上工作。
无论如何,问题在于:它可以与Maven 2和Ivy配合使用,但最近我们开始转向Maven 3,原因有几个(包括更好的冲突解决),但这种组合破坏了我们的构建过程。
首先,我将尝试描述我们如何使用Maven 2和Ivy进行构建。之后,我会添加在切换到Maven 3时出现的问题。
Ivy + Maven 2
当开发我们的库的新版本时,我们使用SNAPSHOT版本,这些版本安装到本地Maven存储库(.m2)中。此外,我们将这些快照部署到Artifactory以共享中间构建,以启用一些并行开发。
然后,我们的项目声明对这些快照的依赖关系。相应的ivysettings.xml如下所示:
由于这种设置,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
以下是我尝试解决问题的两件事,但我不确定是否会有任何我没有考虑到的副作用。如果有人能为此提供一些启示,我将不胜感激:
无论如何,问题在于:它可以与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
以下是我尝试解决问题的两件事,但我不确定是否会有任何我没有考虑到的副作用。如果有人能为此提供一些启示,我将不胜感激:
- 使用文件系统解析器来管理本地.m2仓库,但与一个缓存一起使用,该缓存具有
useOrigin="true"
(可选低defaultTTL)。这样看起来只有xml文件存储在.ivy2缓存中,而工件则在.m2存储库中引用,即它们不会被复制。
这似乎可以工作,但我不确定如果第一次查找会从共享快照存储库(Artifactory)下载快照,并且稍后由本地构建更新,是否会起作用。在这种情况下,我们可能会在.ivy2中缓存远程版本的工件,并在.m2中安装更新版本,.pom文件日期在两种情况下都相同。 - 使用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"
。