# Something fishy with transitive dependencies

**URL:** https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297
**Category:** Old Forum Archive
**Created:** [May 16, 2014, 12:45am UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297 "2014-05-16T00:45:00Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Kevin4](https://avatars.discourse-cdn.com/v4/letter/k/a3d4f5/32.png) [@Kevin4](https://discuss.gradle.org/u/Kevin4)
#### Post date: [May 16, 2014, 12:45am UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297/1 "2014-05-16T00:45:00Z")

</div>

I’ve been struggling with this for a few hours and it has just got me stumped how transitive dependency resolution is working in Gradle.

I am in the process of converting a project from Maven to Gradle. The end result is to generate a .war with the same versions as the Maven build. Simple enough, right?

Here is the problem that has me stumped. I need to remove ‘org.apache.geronimo.specs:geronimo-javamail\_1.4\_spec:1.7.1’ from the runtime configuration. However, I have two cxf libraries which declare it as a dependency and the seem to exclusions fail.

So my dependencies declared like this:

```gradle
dependencies {
 compile(group: 'org.apache.cxf', name: 'cxf-rt-core', version: '2.6.10')
}

```

The runtime dependency tree looks like this:

```gradle
runtime - Runtime classpath for source set 'main'.
+--- org.apache.cxf:cxf-rt-core:2.6.10
|
  +--- org.apache.cxf:cxf-api:2.6.10
|
  |
  +--- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:1.7.1
|
  |
  \--- wsdl4j:wsdl4j:1.6.3
|
  +--- org.apache.ws.xmlschema:xmlschema-core:2.0.3
|
  \--- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:1.7.1

```

When I declare an exclusion in my dependencies:

```gradle
dependencies {
 compile(group: 'org.apache.cxf', name: 'cxf-rt-core', version: '2.6.10') {
  exclude(module: 'geronimo-javamail_1.4_spec')
 }
}

```

All is good:

```gradle
runtime - Runtime classpath for source set 'main'.
+--- org.apache.cxf:cxf-rt-core:2.6.10
|
  +--- org.apache.cxf:cxf-api:2.6.10
|
  |
  \--- wsdl4j:wsdl4j:1.6.3
|
  \--- org.apache.ws.xmlschema:xmlschema-core:2.0.3

```

I don’t run into problems until I add an additional cxf dependency.

```gradle
dependencies {
 compile(group: 'org.apache.cxf', name: 'cxf-rt-core', version: '2.6.10') {
  exclude(module: 'geronimo-javamail_1.4_spec')
 }
 compile(group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxws', version: '2.6.10')
}

```

The dependency tree now looks like this:

```gradle
runtime - Runtime classpath for source set 'main'.
+--- org.apache.cxf:cxf-rt-core:2.6.10
|
  +--- org.apache.cxf:cxf-api:2.6.10
|
  |
  +--- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:1.7.1
|
  |
  \--- wsdl4j:wsdl4j:1.6.3
|
  +--- org.apache.ws.xmlschema:xmlschema-core:2.0.3
|
  \--- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:1.7.1
+--- org.apache.cxf:cxf-rt-frontend-jaxws:2.6.10
|
  +--- org.apache.cxf:cxf-api:2.6.10 (*)
|
  +--- org.apache.cxf:cxf-rt-core:2.6.10 (*)
|
  +--- org.apache.cxf:cxf-rt-bindings-soap:2.6.10

```

I’m confused by the report. Since my exclusion is on the ‘cxf-rt-core’, it seems like the report is incorrect or at least somewhat deceiving in helping me track down my problem. However, I just want to solve my issue, so I’ll ignore the where the report identifies the dependency on ‘geronimo’.

Since both cxf-rt-core’ in ‘cxf-rt-frontend-jaws’ declare a dependency on 'cxf-api, it is unclear whether the dependency on ‘geronimo’ is coming from ‘cxf-rt-core’ or ‘cxf-rt-frontend-jaws’. So as a test, I intentionally exclude ‘cxf-api’ from both dependencies.

```gradle
dependencies {
 compile(group: 'org.apache.cxf', name: 'cxf-rt-core', version: '2.6.10') {
  exclude(module: 'geronimo-javamail_1.4_spec')
  exclude(module: 'cxf-api')
 }
 compile(group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxws', version: '2.6.10') {
  exclude(module: 'cxf-api')
        }
}

```

The dependency tree now looks like this:

```gradle
runtime - Runtime classpath for source set 'main'.
+--- org.apache.cxf:cxf-rt-core:2.6.10
|
  +--- org.apache.ws.xmlschema:xmlschema-core:2.0.3
|
  \--- org.apache.geronimo.specs:geronimo-javamail_1.4_spec:1.7.1
+--- org.apache.cxf:cxf-rt-frontend-jaxws:2.6.10
|
  +--- org.apache.cxf:cxf-rt-core:2.6.10 (*)
|
  +--- org.apache.cxf:cxf-rt-bindings-soap:2.6.10

```

I’m not sure what I’m missing here, but this seems fishy to me. I would expect the dependency for ‘cxf-rt-core’ explicitly declared in my dependencies to take precedence over the transitive dependency ‘cxf-rt-core’ declared by ‘cxf-rt-frontend-jaxws’.

Just to make sure that there was not yet another dependency somewhere in ‘cxf-rt-frontend-jaxws’, I excluded the ‘cxf-rt-core’.

```gradle
compile(group: 'org.apache.cxf', name: 'cxf-rt-core', version: '2.6.10') {
  exclude(module: 'geronimo-javamail_1.4_spec')
  exclude(module: 'cxf-api')
 }
 compile(group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxws', version: '2.6.10') {
  exclude(module: 'cxf-api')
  exclude(module: 'cxf-rt-core')
 }

```

The dependency tree now looks like what I would expect:

```gradle
runtime - Runtime classpath for source set 'main'.
+--- org.apache.cxf:cxf-rt-core:2.6.10
|
  \--- org.apache.ws.xmlschema:xmlschema-core:2.0.3
+--- org.apache.cxf:cxf-rt-frontend-jaxws:2.6.10
|
  +--- org.apache.cxf:cxf-rt-bindings-soap:2.6.10

```

Here is the question: How the reconciliation of attributes resolved when the dependency with identical version numbers occurs multiple times in the dependency tree? Do I need to insure that each dependency only occurs once within the dependency tree if I declare any additional attributes on a dependency? Which dependency is actually used? The first one declared? The last one declared? The nearest dependency?

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [May 16, 2014, 2:58pm UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297/2 "2014-05-16T14:58:00Z")

</div>

As far as I know, a per-dependency exclude only affects the subtree of that direct dependency. In most cases, it’s more useful to exclude a dependency from a whole configuration (‘configurations.compile { exclude module: ‘geronimo-javamail\_1.4\_spec’ }’), or even from all configurations (‘configurations.all { exclude module: ‘geronimo-javamail\_1.4\_spec’ }’).

---

<div class="post-metadata">

### Author: ![Kevin4](https://avatars.discourse-cdn.com/v4/letter/k/a3d4f5/32.png) [@Kevin4](https://discuss.gradle.org/u/Kevin4)
#### Post date: [May 16, 2014, 5:26pm UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297/3 "2014-05-16T17:26:00Z")

</div>

Conceptually I understand that Gradle recommends you declare exclusions on a per-configuration basis. In fact, the Gradle documentation in _50.4.7. Excluding transitive dependencies_ states:

> Should you exclude per-dependency or per-configuration? It turns out that in majority of cases you want to **use the per-configuration exclusion**.

However, dependencies exclusions are transitive and configuration exclusions are not. In other words, if the right answer is to declare the exclusion in the configuration, I can only do those in the final consumer of a project rather than the project itself where I think it belongs.

---

<div class="post-metadata">

### Author: ![Peter\_Niederwieser](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@Peter\_Niederwieser](https://discuss.gradle.org/u/Peter_Niederwieser)
#### Post date: [May 16, 2014, 9:03pm UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297/4 "2014-05-16T21:03:00Z")

</div>

> However, dependencies exclusions are transitive and configuration exclusions are not.

How did you come to this conclusion? Both should be transitive.

---

<div class="post-metadata">

### Author: ![Kevin4](https://avatars.discourse-cdn.com/v4/letter/k/a3d4f5/32.png) [@Kevin4](https://discuss.gradle.org/u/Kevin4)
#### Post date: [May 16, 2014, 10:43pm UTC](https://discuss.gradle.org/t/something-fishy-with-transitive-dependencies/6297/5 "2014-05-16T22:43:00Z")

</div>

You are right. Please excuse the error.

I was observing the dependency tree of the end state war project and a core library project. What I failed to realize was a very similarly-named, intermediate project between the two. The intermediate project was also including some cxf dependencies and therefore pulling in the geronimo dependencies.

I ran further tests and confirmed your statement. The configuration is in fact transitive.

THANKS!
