Ant Ivy conf 特定检索在我发布的 jar 上失败
Posted
技术标签:
【中文标题】Ant Ivy conf 特定检索在我发布的 jar 上失败【英文标题】:Ant Ivy conf specific retrieve is failing on my published jar 【发布时间】:2016-09-22 01:15:33 【问题描述】:使用 Ant Ivy 构建,我试图将我的 jar 分成一个配置用于 3rd 方 jar,另一个配置用于我构建和发布的 jar。 ProjectA 使用 3rd 方 jar 并构建 ProjectB 所依赖的 jar,但是当我使用 Ant Ivy confs 时,我无法让 ProjectB 检索 ProjectA jar。
当我为 ProjectB 执行 ant 脚本时,它可以很好地构建 ProjectA。 ProjectA 构建将一个 jar 发布到本地存储库。 ProjectB 从公共存储库中检索必要的 jar 没有问题,但是当它尝试检索 ProjectA jar 时,它说 UNRESOLVED DEPENDENCY: testproject#ProjectA;2.0.0: configuration not found in testproject#ProjectA;2.0.0 :'本地罐'。 testproject#ProjectB;2.0.0 localjars 需要它
如果我删除对第二个配置 localjars 的所有引用,并且只对所有内容使用默认值,它就可以正常工作。不过,我真的需要将我的罐子分类到不同的 confs 中。
我已成功使用从 ant 脚本传递的修订值代替下面的“2.0.0”并用 $revision 引用,但 conf 错误是相同的。
ProjectA ivy.xml(为简洁起见,包含依赖项的子集):
<ivy-module version="2.0">
<info organisation="testproject" module="ProjectA" revision="2.0.0" status="release" publication="20160524124555"/>
<configurations>
<conf name="default" transitive="false" visibility="public"/>
<conf name="localjars" extends="default" visibility="public"/>
</configurations>
<publications>
<artifact name="projectA-jar-2.0.0" type="jar" conf="localjars" ext="jar"/>
</publications>
<dependencies>
<dependency org="commons-beanutils" name="commons-beanutils" rev="1.7.0" conf="default->master"/>
<dependency org="commons-collections" name="commons-collections" rev="3.1" conf="default->master"/>
</dependencies>
</ivy-module>
ProjectA build.xml 发布目标:
<target name="publish" depends="package"
description="--> compile test and publish this project in the local ivy repository">
<ivy:publish artifactspattern="$DEPLOY_DIR_LIB/[artifact].[ext]"
resolver="local" pubrevision="2.0.0" status="release"
srcivypattern="$ivy.dep.file" forcedeliver="true" overwrite="true" conf="localjars,default"/>
<echo message="project $ant.project.name released with version 2.0.0" />
</target>
ProjectB ivy.xml:
<ivy-module version="2.0">
<info organisation="testproject" module="ProjectB" revision="2.0.0" status="release" publication="20160524103113"/>
<configurations>
<conf name="default"/>
<conf name="localjars" extends="default"/>
</configurations>
<publications>
<artifact name="projectB-2.0.0" conf="localjars" type="jar" ext="jar"/>
</publications>
<dependencies>
<dependency org="testproject" name="ProjectA" rev="$revision" transitive="true" conf="localjars->localjars; default->default"/>
</dependencies>
ProjectB Ant 解析目标:
<target name="resolve" description="--> retrieve dependencies with ivy">
<ivy:retrieve pattern="$DEPLOY_DIR_LIB/[artifact]-2.0.0.[ext]" revision="2.0.0" conf="localjars" />
</target>
知道有什么问题吗?谢谢!
帕特里克
【问题讨论】:
【参考方案1】:不完全确定为什么您的配置不起作用。我建议的一件事是不要禁用传递依赖。您会注意到我在下面的工作示例中创建“默认”配置时采用了不同的方法。
示例
每个项目都有自己的本地构建和 ivy 文件。通过发布到“本地”存储库的 jar 进行协作。
├── build.xml
├── ProjectA
│ ├── build.xml
│ ├── ivy.xml
│ └── src
│ └── Hello.txt
└── ProjectB
├── build.xml
├── ivy.xml
└── src
└── Hello.txt
build.xml
使用buildlist 任务以正确顺序构建所有模块的主构建文件。
另外,我通常会包含一个额外的目标来安装 ivy。
<project name="main" default="publish" xmlns:ivy="antlib:org.apache.ivy.ant">
<available classname="org.apache.ivy.Main" property="ivy.installed"/>
<target name="install-ivy" unless="ivy.installed">
<mkdir dir="$user.home/.ant/lib"/>
<get dest="$user.home/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.4.0/ivy-2.4.0.jar"/>
<fail message="Ivy has been installed. Run the build again"/>
</target>
<target name="publish" depends="install-ivy">
<ivy:buildlist reference="build-path">
<fileset dir="." includes="*/build.xml"/>
</ivy:buildlist>
<subant target="publish" buildpathref="build-path"/>
</target>
<target name="clean">
<subant target="clean">
<fileset dir="." includes="*/build.xml"/>
</subant>
</target>
<target name="clean-all" depends="clean">
<ivy:cleancache/>
</target>
</project>
ProjectA/ivy.xml
“主”配置仅包含工件。此命名约定反映了scopes used by Maven。
还要注意“默认”配置如何扩展“主”和“运行时”。这使客户能够提取他们需要的一切。
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="ProjectA"/>
<configurations>
<conf name="default" description="Master artifact and runtime dependencies" extends="master,runtime"/>
<conf name="master" description="Artifact published by this module"/>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
</configurations>
<publications>
<artifact name="ProjectA" type="jar" ext="jar" conf="master"/>
</publications>
<dependencies>
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>
<!-- runtime dependencies -->
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>
<!-- test dependencies -->
<dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
</dependencies>
</ivy-module>
ProjectB/ivy.xml
注意 ProjectA 是如何成为唯一依赖项的,它将远程“默认”配置映射到本地“编译”配置。
另一个微妙的问题是使用“latest.integration”动态修订。这意味着我们不需要对 ProjectA 的修订进行硬编码。
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="ProjectB"/>
<configurations>
<conf name="default" description="Master artifact and runtime dependencies" extends="master,runtime"/>
<conf name="master" description="Artifact published by this module"/>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
</configurations>
<publications>
<artifact name="ProjectB" type="jar" ext="jar" conf="master"/>
</publications>
<dependencies>
<dependency org="com.myspotontheweb" name="ProjectA" rev="latest.integration" conf="compile->default"/>
</dependencies>
</ivy-module>
ProjectA/build.xml
要发布的修订被设置为一个属性,如果需要可以覆盖它。
还要注意如何使用 ivy 配置来控制构建中的类路径,使用 cachepath 任务
<project name="ProjectA" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="build.dir" location="build"/>
<property name="pub.version" value="1.0"/>
<property name="pub.resolver" value="local"/>
<target name="resolve">
<ivy:resolve/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="test.path" conf="test"/>
</target>
<target name="build" depends="resolve">
<mkdir dir="$build.dir"/>
<jar destfile="$build.dir/$ant.project.name.jar" basedir="src"/>
</target>
<target name="publish" depends="build">
<ivy:publish pubrevision="$pub.version" resolver="$pub.resolver" overwrite="true">
<artifacts pattern="$build.dir/[artifact].[ext]"/>
</ivy:publish>
</target>
<target name="clean">
<delete dir="$build.dir"/>
</target>
</project>
ProjectB/build.xml
与其他项目相同,只是名称属性不同。
<project name="ProjectB" default="build" ....
【讨论】:
虽然我仍然不确定为什么我的问题中的配置不起作用,但我接受了您的回答,因为它非常彻底、信息丰富且有效。谢谢!我仍在努力研究如何处理修订。我不认为使用 latest.integration 对我有用,因为我有时需要能够指定较低的修订号。我的最新版本是针对修订版 2.14.5,但是 latest.integration 尝试获取修订版 2.15.0,因为我之前构建了该版本。我可以在 ivy.xml 中使用 $revision,但是 IvyDE 会一直抱怨,直到我运行了构建脚本。 我想我发现了 IvyDE 的修订问题。在配置 IvyDE 托管库时,我可以将其指向一个 .properties 文件,在该文件中设置“修订”字段,就像在构建脚本中所做的那样。然后,ivy.xml 可以在 IvyDE 执行时解析 $revision。以上是关于Ant Ivy conf 特定检索在我发布的 jar 上失败的主要内容,如果未能解决你的问题,请参考以下文章
如何确定 Ivy 检索任务是不是更新了我的 lib 文件夹中的任何依赖项?
如何解决模块 X 的多个工件被检索到 Apache Ivy 中的同一个文件?