Best Practice Resolving Version Conflicts within Thirdparty Libraries


i just added grgit to my project and my build got broken

> Could not resolve all dependencies for configuration ':mach-build-tools:compileClasspath'.
   > A conflict was found between the following modules:
      - com.jcraft:jsch:0.1.54
      - com.jcraft:jsch:0.1.49

The dependency tree points out that the transitive dependencies of grgit cause the conflict

compileClasspath - Compile classpath for source set 'main'.
\--- org.ajoberstar:grgit:2.3.0
     +--- org.eclipse.jgit:org.eclipse.jgit:
     |    +--- com.jcraft:jsch:0.1.54
     |    +--- com.jcraft:jzlib:1.1.1
     |    +--- com.googlecode.javaewah:JavaEWAH:1.1.6
     |    +--- org.apache.httpcomponents:httpclient:4.5.2
     |    |    +--- org.apache.httpcomponents:httpcore:4.4.4
     |    |    +--- commons-logging:commons-logging:1.2
     |    |    \--- commons-codec:commons-codec:1.9
     |    \--- org.slf4j:slf4j-api:1.7.2
     +--- org.eclipse.jgit:org.eclipse.jgit.ui:
     |    \--- org.eclipse.jgit:org.eclipse.jgit: (*)
     +--- com.jcraft:jsch.agentproxy.core:0.0.9
     +--- com.jcraft:jsch.agentproxy.jsch:0.0.9
     |    +--- com.jcraft:jsch:0.1.49 -> 0.1.54
     |    \--- com.jcraft:jsch.agentproxy.core:0.0.9
     +--- com.jcraft:jsch.agentproxy.pageant:0.0.9
     |    +--- com.jcraft:jsch.agentproxy.core:0.0.9
     |    +---
     |    \---
     |         \---
     +--- com.jcraft:jsch.agentproxy.sshagent:0.0.9
     |    \--- com.jcraft:jsch.agentproxy.core:0.0.9
     +--- com.jcraft:jsch.agentproxy.usocket-jna:0.0.9
     |    +--- com.jcraft:jsch.agentproxy.core:0.0.9
     |    +---
     |    \--- (*)
     +--- com.jcraft:jsch.agentproxy.usocket-nc:0.0.9
     |    \--- com.jcraft:jsch.agentproxy.core:0.0.9
     \--- com.jcraft:jsch:0.1.54

Is there any better approach than excluding group and module of the conflicting library and then explicitly adding the dependeny:

implementation ('org.ajoberstar:grgit:2.3.0'){
    exclude group: 'com.jcraft', module: 'jsch'
implementation 'com.jcraft:jsch:0.1.54'

I also tried the following but it didnt do the trick

implementation ('org.ajoberstar:grgit:2.3.0')
constraints {
		because 'Grgit contains transitive conflict'

Obviously, I misunderstand the concept :-/

By default, gradle will silently pick the latest version if it encounters more than one version of a dependency. Your error suggests you have the following in your build

configurations.all {
  resolutionStrategy {

So now the build fails instead of picking the latest.

I’d suggest one of the following:

  1. Remove failOnVersionConflict()
  2. Force a particular version
configurations.all {
    resolutionStrategy { 
        force 'com.jcraft:jsch:0.1.54'

We have a large code base and use many, many libraries. Thus, we need full control of the transitive libraries and disable failOnVersionConflict is not an option. In fact, it is a very valuable feature of gradle.

Additionally, using force as resolution strategie will cause that gradle will not give us any note when we include another library which brings jsch in a newer version. I would like to get this notification such that we can analyse the differences (and potential side effects) and explicitly decide which version suits best for us.
(I hope I expressed my intention correctly :slight_smile: ).

I guess my first attempt is still the only one which covers our need.

A perfect solution for my problem would be something like this

implementation ('org.ajoberstar:grgit:2.3.0'){
    force version '0.1.54' for 'com.jcraft:jsch' in all transitive libraries of grgit 

Thanks for the efforts,

You might be interested in this code where all the version choices are available in a collection per groupId/artifactId. The sample code uses a custom comparator to select the best version, you could tweak the logic to do whatever you like