Ivy resolve downloads but ignores some artifacts (though not modules)
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
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:
- notice that the number of provided modules is 1 but provided artifacts is 0
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:
- 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!
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">