Wie kann ich Gradle zwingen, dieselbe Version für zwei Abhängigkeiten festzulegen?

73

Ich benutze die folgenden zwei Abhängigkeiten:

compile 'com.google.guava:guava:14.0.1'
compile 'com.google.guava:guava-gwt:14.0.1'

Beide müssen dieselbe Version haben, um korrekt zu funktionieren. Da meine anderen Abhängigkeiten eine höhere Version verwenden, verwendet Gradle für jede Abhängigkeit unterschiedliche Versionen.

Ich fand dies durch Laufen gradle dependencies:

compile - Compile classpath for source set 'main'.
+--- com.google.guava:guava:14.0.1 -> 17.0
+--- com.google.guava:guava-gwt:14.0.1
|    +--- com.google.code.findbugs:jsr305:1.3.9
|    \--- com.google.guava:guava:14.0.1 -> 17.0 

Wie kann ich Gradle zwingen, für diese beiden Abhängigkeiten dieselbe Version festzulegen?

konfile
quelle

Antworten:

17

Eine Ihrer Abhängigkeiten besteht darin, die Guavenversion zum Aktualisieren zu zwingen. Verwenden Sie gradle dependenciesdiese Option, um zu ermitteln, welche Bibliothek Ihre Version entfernt.

Das Problem ist, dass eine andere Bibliothek möglicherweise nicht ordnungsgemäß funktioniert, wenn Sie die Verwendung von 14.0.1 erzwingen. Können Sie nicht einfach die Version 17.0 als Ihre Abhängigkeit verwenden?

Anstatt einzelne Versionsnummern im build.gradle zu verwalten, verwende ich eine dependencies.gradle-Datei, die eine Zuordnung der Versionsnummern enthält, und ziehe diese in das build.gradle. Auf diese Weise muss ich nur die einzelne Guavenversion pflegen. Ihr Beispiel wird also sein:

dependencies.gradle

ext {
    ver = [
        guava: '14.0.1'
    ]
}

und dann in der build.gradle-Datei können Sie haben:

apply from: "dependencies.gradle"

dependencies {
    compile group: 'com.google.guava', module: 'guava', version: ver.guava
    compile group: 'com.google.guava', module: 'guava-gwt', version: ver.guava
}

Wenn ich dann zu 17.0 wechseln möchte, muss ich nur die dependencies.gradle ändern.

Ich bin auch ein definitiver Fan davon, transitive Abhängigkeiten mit false auf false zu setzen

configurations.compile { transitive = false }

Auf diese Weise werden zur Kompilierungszeit einige Abhängigkeiten nicht entfernt, obwohl zur Laufzeit möglicherweise ein Problem auftritt, wenn die Räumungsbibliothek nicht vollständig abwärtskompatibel ist. Seien wir ehrlich, wenn Sie den Code schreiben, sollten Sie wissen, welche Bibliotheken Sie verwenden, und Sie sollten Ihre Abhängigkeiten explizit angeben. Es schützt Sie vor einer Ihrer Abhängigkeiten, die Sie aktualisieren und durcheinander bringen.

Klunk
quelle
102

Fügen Sie diesen Abschnitt der Datei dependencies.gradle hinzu

configurations.all {
        resolutionStrategy { 
            force 'com.google.guava:guava:14.0.1'
            force 'com.google.guava:guava-gwt:14.0.1'
        }
    }
cmcginty
quelle
28
Wo soll dies in die Gradle-Datei eingefügt werden? Am Ende des Blocks?
IgorGanapolsky
1
Ich bekomme immer noch Fehler wie:Execution failed for task ':transformClassesWithJarMergingForDebug'. > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/google/android/gms/gcm/GoogleCloudMessaging$1.class
IgorGanapolsky
1
@IgorGanapolsky Der Ort spielt normalerweise keine Rolle, aber ich würde ihn ganz oben platzieren.
cmcginty
2
Dies geht in dependencies.gradleDatei
Joaquin Iurchuk
1
@cmcginty Was meinst du mit 'Erweiterungstyp'?
Aravinth
62
configurations.all {
  resolutionStrategy.eachDependency { details ->
    if (details.requested.group == 'com.google.guava') {
      details.useVersion "14.0.1"
    }
  }
}

dependencies {
  compile 'com.google.guava:guava'
  compile 'com.google.guava:guava-gwt'
}
Vyacheslav Shvets
quelle
Aus irgendeinem Grund hat die Force-Methode nicht verhindert, dass andere Versionen der Bibliothek zur JAR-Datei hinzugefügt wurden, aber mit Ihrer Methode erhalte ich mehrere exakte Versionen derselben Bibliothek in der JAR-Datei. Einen Schritt näher. Vielen Dank!
Reith
1
DependencyResolveDetails nicht in androidsudio 3.3.0 gefunden
Mr X
@ MrX Ich habe unnötige Erwähnungen von DependencyResolveDetails aus dem Code entfernt. Bitte versuchen Sie es erneut
Vyacheslav Shvets
40

Ich hatte eine ähnliche Situation, in der eine der Abhängigkeiten Spring-Web 4.2.4 verwendete, das defekt war. Sie müssen eine bestimmte Bibliotheksversion erzwingen, die Sie möchten. Wie in einem anderen Kommentar erwähnt, kann dies zu Kompatibilitätsproblemen führen, ist jedoch manchmal erforderlich.

Die am wenigsten aufdringliche Möglichkeit, eine von mir gefundene Bibliotheksversion zu erzwingen, war die Verwendung

compile "org.springframework:spring-web:4.2.3.RELEASE"

Angeben der Abhängigkeitskonfiguration als erzwungen:

compile("org.springframework:spring-web:4.2.3.RELEASE"){
    force = true
}

Ich habe es verwendet, als ich die Spring-Version vorübergehend (bis zur nächsten Version) herunterstufen musste.

Pijusn
quelle
4

Eine weitere Option ist die Verwendung der Abhängigkeitsbeschränkung: https://docs.gradle.org/current/userguide/dependency_constraints.html

dependencies {
    implementation 'org.apache.httpcomponents:httpclient'
    constraints {
        implementation('org.apache.httpcomponents:httpclient:4.5.3') {
            because 'previous versions have a bug impacting this application'
        }
        implementation('commons-codec:commons-codec:1.11') {
            because 'version 1.9 pulled from httpclient has bugs affecting this application'
        }
    }
}
sendon1982
quelle
2

Alternativ können Sie die Unterstützung von dependencySets (oder mavenBom, wenn BOM POM verfügbar ist) im Gradle-Plugin für das Spring-Dependency-Management verwenden . Beachten Sie, dass dieses Plugin auch automatisch mit dem Spring-Boot- Gradle-Plugin angewendet wird . Weitere Details finden Sie hier .

plugins {
  id 'io.spring.dependency-management' version '1.0.1.RELEASE'
}

dependencyManagement {
  dependencies {
    dependencySet(group: 'com.google.guava', version: '14.0.1') {
      entry 'guava'
      entry 'guava-gwt'
    }
  }
}

dependencies {
  compile 'com.google.guava:guava'
  compile 'com.google.guava:guava-gwt'
}
Stevo Slavić
quelle
1

Wenn es in Ordnung ist, nur die neuere Version für beide Abhängigkeiten zu verwenden, können Sie Ihr Problem am einfachsten beheben, indem Sie Ihre Abhängigkeiten aktualisieren:

compile 'com.google.guava:guava:17.0'
compile 'com.google.guava:guava-gwt:17.0'

Dadurch wird sichergestellt, dass beide auf 17.0 sind. Es ist einfacher als zu versuchen, beide der älteren Version aufzuzwingen, und als zusätzlichen Bonus erhalten Sie eine neuere Version, die (wahrscheinlich) Fehlerbehebungen und neue Funktionen enthält.

Um fair zu sein, erwähnt @Klunk dies in seiner Antwort mit der Frage "Können Sie nicht einfach die 17.0-Version als Ihre Abhängigkeit verwenden?", Aber es ist nur nebenbei und leicht zu übersehen, daher hielt ich es für sinnvoll, als separate Antwort zu posten .

Marcin Koziński
quelle