The Holy Java

Building the right thing, building it right, fast

Ivy resolve downloads but ignores some artifacts (though not modules)

Posted by Jakub Holý on December 23, 2010

I’ve had a strange issue with Apache Ivy‘s resolve task – it resolved and downloaded all my dependencies but didn’t put some of them to the classpath (via ivy:cachepath) and certainly wouldn’t copy them either (via ivy:retrieve). An indicia was that in the resolve report the number of “artifacts” was zero while the number of “modules” matched the number of the dependencies. The issue was caused by my defaultconfmapping=”*->compile” – it turned out that most modules, as interpreted by Ivy, produce their artifacts only for the configuration “master” and not for compile.

In my case, with ivy.xml (definition of the configurations compile, provided, and test not shown) containing

...
<dependencies defaultconf="compile">
   <dependency conf="provided" org="log4j" name="log4j" rev="1.2.14" />
   <dependency conf="test" org="net.jakubholy.testing" name="dbunit-embeddedderby-parenttest" rev="1.1.0" />
    <dependency conf="test" org="org.mockito" name="mockito-all" rev="1.8.5" />
 </dependencies>
...

the test-scoped dependencies net.jakubholy.testing:dbunit-embeddedderby-parenttest:1.1.0 and org.mockito:mockito-all:1.8.5 were included in the classpath together with their dependencies as expected while log4j:log4j:1.2.14 was ignored no matter what I did (even changing its conf to test).

The problem was indicated by <ivy:resolve /> producing an output like:

[ivy:resolve] :: resolution report :: resolve 951ms :: artifacts dl 20ms
	---------------------------------------------------------------------
	|                  |            modules            ||   artifacts   |
	|       conf       | number| search|dwnlded|evicted|| number|dwnlded|
	---------------------------------------------------------------------
	|      compile     |   0   |   0   |   0   |   0   ||   0   |   0   |
	|       test       |   13  |   0   |   0   |   1   ||   10  |   0   |
	|     provided     |   1   |   0   |   0   |   0   ||   0   |   0   |
	|      runtime     |   0   |   0   |   0   |   0   ||   0   |   0   |
	---------------------------------------------------------------------

- notice that the number of provided modules is 1 but provided artifacts is 0

Troubleshooting

Checking the resolve report in <user home>/.ivy2/cache/resolved-<org>-<artifact>-<revision>.xml revealed the full definition of configurations (included from another file), dependencies and especially dependencies/defaultconfmapping, which was rather useful later. The defaultconfmapping

...
<dependencies defaultconf="compile" defaultconfmapping="*->compile">
...

seemed to be OK but was not, as further exploration revealed.

Next I’ve checked the Ivy descriptor for the log4j “module” generated by Ivy from its pom.xml in .ivy2/cache/log4j/log4j/ivy-1.2.14.xml and its publications tag caught my eye:

...
<publications>
   <artifact name="log4j" type="jar" ext="jar" conf="master"/>
   <artifact name="log4j" type="source" ext="jar" conf="sources" m:classifier="sources"/>
</publications>
...

- notice that the JAR artifact (i.e. log4j.jar) is produced only for the configuration ‘master’! But due to the innocently looking default mapping of “*->compile” we are taking into account only artifacts produced in the configuration “compile”, which is zero. Mystery solved!

Fix

The fix (not necessarily the best one) is to include all configurations of interest in the default mapping (either on dependencies or on configurations in ivy.xml):

<dependencies defaultconf="compile" defaultconfmapping="*->compile,master,default">
About these ads

Sorry, the comment form is closed at this time.

 
%d bloggers like this: