Question

I'm trying to set up my ant build so that the targets which run Ivy functions are completely separated from the ones that the continuous build and most developers run. I want one target to download updated dependencies, which I'll check in. Other targets will set up their classpath by including *.jar from the relevant directory.

I have two configurations:

<configurations>
    <conf name="compile" />
    <conf name="test" />
</configurations>

I have some dependencies:

<dependency
    org="my.org"
    name="some-lib"
    rev="latest.release"
    conf="compile->default" />
<dependency
    org="my.org"
    name="some-test-lib"
    rev="latest.release"
    conf="test->default" />

And I download those dependencies and their transitive dependencies using ivy:retrieve:

<ivy:retrieve
    pattern="lib/[conf]/[type]/[artifact]-[revision].[ext]"
    sync="true"
    file="ivy.xml" />

The problem is that I'm seeing some duplicates jars between the compile and the test directories, which come from transitive dependencies. Since I want to check in all these jars and use them for creating classpaths, I'd like to avoid duplicates. Is this possible?

lib/compile/jar/some-lib-1.0.jar
lib/compile/jar/slf4j-api-1.5.11.jar
lib/test/jar/some-test-lib-1.0.jar
lib/test/jar/junit-4.7.jar
lib/test/jar/slf4j-api-1.5.11.jar

Was it helpful?

Solution 2

If I can do this through Ivy directly, that would be best. For now I've solved the problem by just deleting duplicates using ant.

OTHER TIPS

This is not duplication, each configuration is a separate set of jars and the ivy restrieve task is faithly creating each set....

Perhaps it would make more sense to create the classpaths directly, rather than populating a local lib directory.

Here's a snippet of my ANT build files:

<target name="get-dependencies">
    <ivy:resolve/>

    <ivy:cachepath pathid="compile.path" conf="compile" />
    <ivy:cachepath pathid="test.path" conf="test" />
</target>

<target name="compile" depends="get-dependencies">
    <javac srcdir="src" destdir="build/classes" classpathref="compile.path"/>
</target>

I normally only use the ivy retrieve task when I need to create a local copy of a set of jars, for example assembling a web app's directory:

<ivy:retrieve pattern="build/WEB_INF/lib/[artifact].[ext]" conf="runtime"/>

Update

Another alternative is to instruct ivy to exclude the slf4j module when downloading transient dependencies, as follows:

<dependency org="my.org" name="some-lib" rev="latest.release" conf="compile->default">
    <exclude module="slf4j-api"/> 
</dependency>

<dependency org="my.org" name="some-test-lib" rev="latest.release" conf="test->default">
    <exclude module="slf4j-api"/> 
</dependency>

Try the following. Your test should extend compile

<dependency
org="my.org"
name="some-test-lib"
rev="latest.release"
conf="**test->compile**" />

If i am right IVY should find that test extends compile and would download slf4j only once.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top