Transitive dependency behaviour for dependent projects


(dev) #1

I have a multi-project build. In my root build.gradle I declare default dependencies in subprojects { } like this:

dependencies {
      compile("log4j:log4j:1.2.15") {
        transitive = false
      }
 }

I have 2 projects A & B. If I use the “dependencies” task on project A, I see:

compile - Classpath for compiling the main sources.
+--- log4j:log4j:1.2.15

Project B depends on project A. If I use the “dependencies” task on project B, I see:

compile - Classpath for compiling the main sources.
+--- log4j:log4j:1.2.15
|
  +--- javax.mail:mail:1.4 -> 1.4.4
|
  |
  \--- javax.activation:activation:1.1 -> 1.1.1
|
  +--- javax.jms:jms:1.1
|
  +--- com.sun.jdmk:jmxtools:1.2.1
|
  \--- com.sun.jmx:jmxri:1.2.1

Log4j is pulling in the transitive dependencies. What’s going on?


(dev) #2

The only other reference to log4j is in a jaxen dependency:

|
  +--- jaxen:jaxen:1.1.3
|
  |
  +--- xml-apis:xml-apis:1.3.02 -> 1.3.03 (*)
|
  |
  +--- xerces:xercesImpl:2.6.2 -> 2.8.1
|
  |
  |
  \--- xml-apis:xml-apis:1.3.03 (*)
|
  |
  +--- maven-plugins:maven-cobertura-plugin:1.3
|
  |
  |
  +--- cobertura:cobertura:1.8
|
  |
  |
  |
  +--- oro:oro:2.0.8
|
  |
  |
  |
  +--- asm:asm:2.2.1 -> 3.2
|
  |
  |
  |
  \--- log4j:log4j:1.2.9 -> 1.2.15 (*)
|
  |
  |
  +--- oro:oro:2.0.8 (*)
|
  |
  |
  +--- asm:asm:2.2.1 -> 3.2 (*)
|
  |
  |
  +--- log4j:log4j:1.2.9 -> 1.2.15 (*)
|
  |
  |
  \--- commons-jelly:commons-jelly-tags-log:1.0

Interestingly the jaxen dependency is declared as transitive = false in both projects A and B.


(Peter Niederwieser) #3

I think that ‘transitive = false’ isn’t passed on to further configurations. As far as I know, Gradle inherited this behavior from Ivy. Try this instead: ‘compile “log4j:log4j:1.2.15@jar”’


(dev) #4

I think that transitive = false isn’t passed on to further configurations.

This seems to be the case. It seems to be a bit worse though. If I specify the following config in both projects:

compile(group: 'log4j', name: 'log4j', version:'1.2.15') {
        transitive = false
    }

Project B still fails to build.

Artifact 'javax.jms:jms:1.1@jar' not found.

As soon as I make one project dependent on another then they won’t build. Am I missing something?


(Peter Niederwieser) #5

Same thing. The ‘transitive = false’ isn’t passed on. I always use ‘@jar’ instead of ‘transitive = false’, and haven’t had any such problems.


(dev) #6

The problem is that a dependency is overriding what I am explicitly specifying e.g. “transitive = false”. It seems transitive = false is unusable for a multi-project build.

Can you explain a bit more what @jar is actually doing that fixes it?


(Peter Niederwieser) #7

@jar’ just refers to the module’s Jar artifact, which also means that it doesn’t include transitive dependencies. In contrary to ‘transitive = false’, it is carried over to other configurations as expected. I’m not sure though how a conflict is resolved where a configuration’s dependency graph contains the same module twice, once with and once without ‘@jar’.