Ant Ivy conf 特定检索在我发布的 jar 上失败

Ant Ivy conf specific retrieve is failing on my published jar

使用 Ant Ivy 构建,我试图将我的 jar 分成一个用于第 3 方 jar 的配置和另一个用于我构建和发布的 jar 的配置。 ProjectA 使用第三方 jar 并构建了 ProjectB 所依赖的 jar,但是当我使用 Ant Ivy confs 时,我无法让 ProjectB 检索 ProjectA jar。

当我执行 ProjectB 的 ant 脚本时,它可以很好地构建 ProjectA。 ProjectA 构建将一个 jar 发布到本地存储库。 ProjectB 从 public 存储库中检索必要的 jar 没有问题,但是当它尝试检索 ProjectA jar 时,它说 UNRESOLVED DEPENDENCY: testproject#ProjectA;2.0.0: configuration not found in testproject #ProjectA;2.0.0:'localjars'。它是 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>

项目 B 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> 

知道出了什么问题吗?谢谢!

帕特里克

不完全确定您的配置为何不起作用。我建议的一件事是不要禁用传递依赖项。您会注意到我在下面的工作示例中使用不同的方法创建 "default" 配置。

例子

每个项目都有自己的本地构建和 ivy 文件。通过发布到 "local" 存储库的 jars 进行协作。

├── 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

"master" 配置仅包含工件。此命名约定反映了 scopes used by Maven.

另请注意 "default" 配置如何扩展 "master" 和 "runtime"。这使客户能够拉下他们需要的一切。

<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 是唯一的依赖项,它将远程 "default" 配置映射到本地 "compile" 配置。

另一个微妙的问题是 "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" ....