David Stanley
David Stanley

Reputation: 343

Ivy Resolves Dependencies In Other Configurations

I'm having trouble retrieving the dependencies I expect by configuration name. I have a shared library I'm publishing to a local repository, using the following ivy file:

<?xml version="1.0"?>
<ivy-module version="2.0">
    <info organisation="my.org" module="my-stuff" status="release"/>
    <configurations>
        <conf name="runtime"/>
        <conf name="provided" extends="runtime"/>
        <conf name="test"     extends="provided"/>
    </configurations>
    <publications>
        <artifact name="my-stuff" type="jar"    ext="jar" conf="*"/>
        <artifact name="my-stuff" type="source" ext="zip" conf="*"/>
    </publications>
    <dependencies>
        <dependency org="javax.servlet"     name="servlet-api" rev="2.4"    conf="provided,test -> master"/>
        <dependency org="org.apache.tomcat" name="tomcat-dbcp" rev="7.0.47" conf="provided,test -> master"/>
        <dependency org="log4j"             name="log4j"       rev="1.2.17" conf="* -> master"/>
        <dependency org="my.org"            name="my-module"   rev="1.2.3"  conf="* -> default"/>
        <dependency org="junit"             name="junit"       rev="4.5"    conf="provided,test -> master"/>
        <dependency org="org.apache.ant"    name="ant"         rev="1.8.4"  conf="provided,test -> master"/>
    </dependencies>
</ivy-module>

So far, so good. I publish the my-stuff jar, and if I try to retrieve its dependencies by configuration, I get what I expect, two dependencies in the runtime configuration, and six each in the provided and test configurations. The trouble starts when I try to retrieve dependencies of something that depends on my-stuff. I use this ivy file:

<?xml version="1.0"?>
<ivy-module version="2.0">
    <info organisation="my.org" module="test-my-stuff" status="release"/>
    <configurations>
        <conf name="runtime"/>
        <conf name="provided" extends="runtime"/>
        <conf name="test" extends="provided"/>
    </configurations>
    <dependencies>
        <dependency org="my.org" name="my-stuff" rev="1.1"/>
    </dependencies>
</ivy-module>

Now if I try to retrieve the runtime configuration, instead of getting the my-stuff jar, log4j and my-module, I get twelve jars, including activation.jar and mail.jar, things I don't get when I use the first ivy file to retrieve. Why is my second ivy file pulling everything into the runtime configuration? What exactly am I doing wrong?

If, on the other hand, I add a configuration mapping to the dependency in the second file, such as runtime->runtime;provided->provided;test->test, resolve will fail, claiming it can't find my-stuff.

Upvotes: 1

Views: 388

Answers (1)

Mark O&#39;Connor
Mark O&#39;Connor

Reputation: 77951

I think your issue is how you declared the configuration of the published artifacts:

<publications>
    <artifact name="my-stuff" type="jar"    ext="jar" conf="*"/>
    <artifact name="my-stuff" type="source" ext="zip" conf="*"/>
</publications>

You're basically saying they should be part of the "runtime", "provided" and "test" configurations. Additionally because the 3 configurations are nested, something in "runtime" will automatically be part of "provided" and "test" as well.

So I suggest restructuring your ivy file as follows:

<configurations>
    <conf name="default" extends="runtime,master"/>
    <conf name="master"/>
    <conf name="sources"/>
    <conf name="provided"/>
    <conf name="runtime"/>
    <conf name="test" extends="runtime"/>
</configurations>
<publications>
    <artifact name="my-stuff" type="jar"    ext="jar" conf="master"/>
    <artifact name="my-stuff" type="source" ext="zip" conf="sources"/>
</publications>

Notes:

  • The main artefact is on a standalone "master" configuration that also gets included on the "default" configuration
  • Additional configuration for "sources". Keeps it isolated from runtime and allows it to be downloaded explicitly
  • "provided" scope is stand-alone. This is important as you do not want it to be accidentally packaged in a war file.

A dependency declaration should now work, but always a good idea to provide an explicit configuration mapping, in this case to our new "default" configuration:

<dependency org="my.org" name="my-stuff" rev="1.1" conf="runtime->default"/>

Upvotes: 2

Related Questions