Ivy, what is the master configuration and why is it not pulling jvyaml?

Solution 1:

I would suggest restructuring your configurations as follows:

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="compile" description="Libraries needed only for compilation" />
        <conf name="runtime" description="Libraries only needed at runtime" extends="compile" />
        <conf name="test" description="Libraries only needed for testing" extends="runtime" />
    </configurations>

    <dependencies>
        <dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime->default" />
        <dependency org="org.apache.solr" name="solr-core" rev="3.6.0" conf="runtime->default" />
    </dependencies>

</ivy-module>

Important changes introduced:

  1. Use the more standard "compile" configuration
  2. Configuration inheritance using the "extends" attribute. Compile dependencies can then be automatically included in both the runtime and test configurations.
  3. Use configuration mappings, for example: conf="runtime->default". This makes it obvious which local configuration is associated with which remote configuration.

Configuration mappings explained

Configurations are a powerful ivy feature. When ivy downloads Maven modules it performs an internal translation and assigns a standard set of configurations, listed in this answer:

  • How are maven scopes mapped to ivy configurations by ivy

When declaring a dependency it's a good idea to always make use of a configuration mapping, so that there is no doubt where the dependencies artifacts are assigned.

For example:

<dependency org="??" name="??" rev="??" conf="runtime->default" />

Here we're saying we want the remote module's default dependencies associated with our local runtime configuration.

In practice, there are only two remote configuration mappings you'll actually need:

  • default: The remote module's artifact and all it's runtime transitive dependencies
  • master: The remote module's artifact only (No transitive dependencies)

In conclusion, I think your problem was caused by the fact that the remote Maven module's "runtime" scope does not include Maven module's artifact, instead you were getting the non-existant transitive dependencies of the module jvyaml :-(

Some additional advice

I'd also suggest generating an ivy dependency management report, as follows:

<target name="init" description="Resolve dependencies and populate lib dir">
    <ivy:resolve/>
    <ivy:report todir="${build.dir}/ivy-report" graph="false"/>
    <ivy:retrieve pattern="lib/[conf]/[artifact]-[revision].[ext]"/>
</target>

The report will help explain how each dependency ends up on different configurations. Also really useful for determining how transitive dependencies are being managed.

And finally, here's where the configuration inheritance pays off, creating ivy managed ANT classpaths:

<target name="init" description="Resolve dependencies and set classpaths">
    <ivy:resolve/>
    <ivy:report todir="${build.dir}/ivy-report" graph="false"/>

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

Solution 2:

Notice that the original solr-core is not retrieved either. After your resolve, go the cache and check the ivy.xml files for both modules.

You will see that they publish their artifacts in conf=master only

<artifact name="jvyaml" type="jar" ext="jar" conf="master"/>

<artifact name="solr-core" type="jar" ext="jar" conf="master"/>

Which means, you have to do explicit configuration mapping to denote that your builtime configuration should evoke the 'master' configuration of your dependencies. (check configuration mapping).

HOWEVER, the dependencies of the solr-core, have the configuration mapping as you could see in the ivy.xml file:

<dependency org="org.apache.solr" name="solr-solrj" rev="3.6.0" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>

I think it's the master(*) thingy.

What I usually do is in my own ivy.xml file when I declare dependencies I do the mapping:

  <dependency org="net.java.dev" name="jvyaml" rev="0.2.1" conf="runtime->master" />

This one says the runtime be evoking the master configuration in the designated dependency.

You could do

conf="runtime,test->master"

as well