How to avoid copying dependencies with Ivy

。_饼干妹妹 提交于 2019-12-17 04:08:31

问题


I'm looking into using Ivy to manage dependencies but wow - that thing really likes to make multiple copies of jars! It spreads like the ivy in my back yard and is just as undesirable!

Is it possible to have Ivy simply define a classpath (for a specified profile) that references the resolved dependencies so my javac can reference them directly in the ivy repository (or cache?).

I've read the reference docs buy only see the option to set up symbolic links to the repository cache. I guess this will suffice, but it seems like a waste. Also, I'm not sure that a "war" task can build the war from symbolic links... but I guess I'll find out when I give it a try.

Any better suggestions?


回答1:


Here's my standard Java build file that creates an executable jar.

The objective is to manage project specific stuff via a combination of ANT properties and an ivy.xml file for the 3rd-party dependencies.

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="demo" default="build">

  <property name="src.dir" location="src"/>
  <property name="build.dir" location="build"/>
  <property name="dist.dir" location="dist"/>
  <property name="dist.jar" location="${dist.dir}/${ant.project.name}.jar"/>
  <property name="dist.main.class" value="HelloWorld"/>

  <target name="retrieve">
    <ivy:resolve/>
    <ivy:cachepath pathid="build.path" conf="build"/>
    <ivy:cachepath pathid="runtime.path" conf="runtime"/>
  </target>

  <target name="compile" depends="retrieve">
    <mkdir dir="${build.dir}/classes"/>
    <javac srcdir="${src.dir}" destdir="${build.dir}/classes" classpathref="build.path"/>
  </target>

  <target name="build" depends="compile">
    <ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]"/>

    <manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
      <classpath>
        <fileset dir="${dist.dir}/lib" includes="*.jar"/>
      </classpath>
    </manifestclasspath>

    <jar destfile="${dist.jar}" basedir="${build.dir}/classes">
      <manifest>
        <attribute name="Main-Class" value="${dist.main.class}"/>
        <attribute name="Class-Path" value="${jar.classpath}"/>
      </manifest>
    </jar>
  </target>

  <target name="clean">
    <delete dir="${build.dir}"/>
    <delete dir="${dist.dir}"/>
  </target>

</project>

As you've discovered in the Ivy docu, the cachepath Ivy task is used to manage two ANT paths. One for the build dependencies the other for the run-time dependencies of the executable jar.

The real power of Ivy is in something called configurations. I found it difficult to grasp initially until I realised it was simple a logical grouping of jars that I can define for my project. This example has two configurations:

  • build
  • runtime

Here's the ivy file demonstrating how dependencies can be associated with configurations:

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>
    <configurations>
        <conf name="build" description="Libraries needed to for compilation"/>
        <conf name="runtime" extends="build" description="Libraries that need to be included with project jar" />
    </configurations>
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->default"/>
        <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="runtime->default"/>
    </dependencies>
</ivy-module>

In conclusion I hope this example helps in understanding Ivy. I like the way it concentrates on only one thing, the management of 3rd-party dependencies.




回答2:


After battling through the badly written Ivy documentation (sigh - what is wrong with these people? - did they not attend high-school literacy classes in any language?), I see there is a post-resolve task called cachepath that will construct an ant path to the resolved dependency artifacts instead of copying files to a lib directory. This might be just what I'm looking for!




回答3:


Just to augment @Mark's answer.

Note that cachepath result can also be directly used in build without the need to copy jars with retrieve:

<target name="build" depends="compile">
    <jar destfile="${dist.ear}">
        <mappedresources>
            <resources refid="runtime.path"/>
            <chainedmapper>
                <flattenmapper/>
                <globmapper from="*" to="lib/*"/>
            </chainedmapper>
        </mappedresources>
    </jar>
</target>


来源:https://stackoverflow.com/questions/2609465/how-to-avoid-copying-dependencies-with-ivy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!