67

One of the dependencies declared in my project has a transitive dependency on 'com.google.guava:guava:15.0'. But my application deployed on WAS/Weblogic doesn't work due to a CDI issue which has been fixed in 'com.google.guava:guava:15.0:cdi1.0'. (same version, but with classifier) I need to tell gradle to use this jar during build and packaging. I am trying to figure out how we can override this transitive dependency with a jar specific version classifier.

Tried the following approaches:

  1. Added the dependency explicitly: compile 'com.google.guava:guava:15.0:cdi1.0'. But both jars got included in the resultant WAR.

  2. Added the dependency explicitly and defined a resolution strategy:

    configurations.all {
        resolutionStrategy {
            force 'com.google.guava:guava:15.0:cdi1.0'
        }
    }
    

Even this didn't work.

  1. Defined a resolution strategy to check and change the version.

    configurations.all {
         resolutionStrategy.eachDependency { DependencyResolveDetails details ->
             if (details.requested.group + ":" + details.requested.name == 'com.google.guava:guava') {
                details.useVersion "15.0:cdi1.0"
                //details.useTarget "com.google.guava:guava:15.0:cdi1.0"
            }
        }
    }
    

Even this didn't work.

Need your suggestions on how this issue can be tackled.

MoxxiManagarm
  • 8,735
  • 3
  • 14
  • 43
dinup24
  • 1,652
  • 3
  • 16
  • 26

9 Answers9

73

Currently classifiers are not yet taken into account when it comes to resolutionStrategies. A workaround for you might excluding the transitive Guava library when declaring your dependencies and adding the Guava cdi1.0 version explicitly:

dependencies {
    compile ("org.acme:someDependency:1.0"){
        exclude group: 'com.google.guava', module: 'guava'
    }       
    compile "com.google.guava:guava:15.0:cdi1.0"
}
informatik01
  • 16,038
  • 10
  • 74
  • 104
Rene Groeschke
  • 27,999
  • 10
  • 69
  • 78
  • 8
    Note that this is no longer the correct answer. See for upgrading (transitive) dependencies: https://docs.gradle.org/current/userguide/dependency_constraints.html and for downgrading or excluding (transitive) dependencies: https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html – Pieter Aug 04 '21 at 15:04
  • @Pieter I would encourage you to submit a new answer, since none of the current answers include the constraints answer. – yshavit Feb 02 '22 at 23:27
42

I came across a more elegant approach which is simply:

compile ("com.google.guava:guava:15.0:cdi1.0") {
  force = true
}

Explanation

Setting force = true for a dependency tells gradle to use the specified version in case of a version conflict

Sobvan
  • 1,376
  • 1
  • 15
  • 24
14
implementation( group: 'commons-codec', name: 'commons-codec'){
      version{
        strictly "[1.15]"
      }
   }

This works for me with gradle 6.6.1

The documentation link for strictly can found here https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints

Pravanjan
  • 698
  • 7
  • 16
6

Gradle 4.5.1 has the function DependencySubstitutions. Here an example to replace a dependency:

configurations.each {
    c -> c.resolutionStrategy.dependencySubstitution {
        all { DependencySubstitution dependency ->
            if (dependency.requested.group == 'org.json') {
                dependency.useTarget 'com.vaadin.external.google:android-json:0.0.20131108.vaadin1'
            }
        }
    }
}
koppor
  • 19,079
  • 15
  • 119
  • 161
3

This will not work if the same dependency is pointed by some other jar. Sureshot way to exclude the dependency

configurations {
 all*.exclude group: 'com.google.guava', module:'guava-jdk5'
}
Abhijit Mazumder
  • 8,641
  • 7
  • 36
  • 44
2

Since force = true is deprecated, relevant solution is to use strictly(...) version, e.g.:

dependencies {
    // no need to exclude transitive spring-data-relational from this dependency
    implementation("org.springframework.data", "spring-data-r2dbc", "1.1.0.RC1")

    implementation("org.springframework.data", "spring-data-relational").version {
        strictly("2.0.0.RC1")
    }
}

P.S. tested on Gradle 6.3

uptoyou
  • 1,427
  • 19
  • 24
  • 1
    is there a documentation?.."strictly" not working in Gradle 6.4.1 – happy Sep 08 '20 at 09:48
  • 1
    @happy The documentation link which I found on strictly https://docs.gradle.org/current/userguide/rich_versions.html#rich-version-constraints implementation( group: 'commons-codec', name: 'commons-codec'){ version{ strictly "[1.15]" } } – Pravanjan Nov 19 '20 at 15:05
1

Try this:

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->

        // https://docs.gradle.org/current/userguide/resolution_rules.html
        if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') {
            details.useVersion '15.0:cdi1.0'
        }
    }
}
logbasex
  • 1,688
  • 1
  • 16
  • 22
1

I fix it by exclude org.bouncycastle from the module which causes this duplicate error.

build.gradle(:app)

implementation(project(Modules.yourModuleName)) {
    exclude group: 'org.bouncycastle'
}
Zhou Haibo
  • 1,681
  • 1
  • 12
  • 32
0

try this its working perfectly in my case in App level in build.gradle file

android {
configurations {
    all*.exclude module: 'conceal'

    all*.exclude module: 'bcprov-jdk15on'
    }
}   
Asif Mehmood
  • 141
  • 1
  • 14