https://d226lax1qjow5r.cloudfront.net/blog/blogposts/the-right-way-of-using-gradle-dynamic-dependencies/blog_gradle-dynamic-dependencies_1200x600.png

Der richtige Umgang mit dynamischen Gradle-Abhängigkeiten

Zuletzt aktualisiert am November 4, 2020

Lesedauer: 9 Minuten

Dieser Artikel wurde im April 2025 aktualisiert.

Gradle ist ein leistungsstarkes und flexibles Build-System, das in der Android-Entwicklung und anderen Java-basierten Projekten weit verbreitet ist. Es bietet ein Abhängigkeitsmanagement, mit dem Sie externe Bibliotheken und Frameworks definieren können, auf die Ihre Anwendung angewiesen ist.

Definieren von Abhängigkeiten in Gradle

Normalerweise definieren Sie Abhängigkeiten in Gradle wie folgt:

dependencies {

    implementation 'com.vonage.client:client-sdk:2.7.0'

}

In dem obigen Beispiel lädt Gradle die spezifische Version 2.7.0 des Vonage Client SDK. Wenn Sie jedoch möchten, dass Gradle Bibliotheksversionen dynamisch verwaltet, können Sie eine dynamische Version verwenden, anstatt eine feste Versionsnummer anzugeben.

Semantische Versionierung verstehen

Die meisten Bibliotheken folgen heute Semantische Versionierung (semver), die ein major.minor.patch Format verwendet (z.B., 2.7.0). Die Regeln für die Versionierung lauten wie folgt:

  • Major: Wird erhöht, wenn es rückwärtskompatible Änderungen in der API gibt (z. B. Änderungen der Methodensignatur).

  • Kleinere: Erhöht, wenn neue Funktionalität auf abwärtskompatible Weise hinzugefügt wird (z. B. Hinzufügen neuer Methoden).

  • Aufnäher: Erhöht für rückwärtskompatible Fehlerkorrekturen (z. B. Behebung von Fehlern ohne Einführung neuer Funktionen).

Dynamische Abhängigkeiten verwenden

Mit Gradle können Sie eine dynamische Versionierung verwenden, die es ermöglicht, automatisch die neueste kompatible Version einer Abhängigkeit abzurufen. Hier erfahren Sie, wie Sie eine dynamische Version definieren können:

dependencies {

    implementation 'com.vonage.client:client-sdk:2.7.+'

}

Im obigen Beispiel holt Gradle die aktuellste Patch-Version von 2.7.x (z.B., 2.7.1, 2.7.2). Sie können auch andere Formen von dynamischen Abhängigkeiten verwenden, wie z.B.:

  • implementation 'com.vonage.client:client-sdk:2.+': Dies holt die neueste Version innerhalb der 2.x Bereich (sowohl Minor- als auch Patch-Versionen).

  • implementation 'com.vonage.client:client-sdk:+': Damit wird die letzte verfügbare Version der Bibliothek abgerufen.

Dynamische Abhängigkeiten stellen zwar sicher, dass Sie immer die neuesten Fehlerkorrekturen und Verbesserungen verwenden, aber sie haben auch ihre Tücken.

Warum Sie mit dynamischen Abhängigkeiten vorsichtig sein sollten

Dynamische Abhängigkeiten können zu unvorhersehbarem Verhalten führen. Nachfolgend sind einige mögliche Probleme und Szenarien aufgeführt, in denen dynamische Abhängigkeiten Probleme verursachen.

Problematisches Szenario 1: Inkonsistente Builds

Stellen Sie sich vor, Ihre Anwendung hat vor einem Monat noch einwandfrei funktioniert, aber nachdem ein Fehler aufgetreten ist, funktioniert sie nicht mehr wie erwartet. Sie checken das Repository von damals aus, bauen die App neu auf, aber das Problem besteht immer noch. Was war passiert?

Das Problem ist, dass der dynamische Abhängigkeitsmechanismus in Gradle die neueste Version der externen Bibliothek abgerufen hat, die nun den Fehler enthält. Obwohl Ihr Quellcode von vor einem Monat war, war die Version der externen Bibliothek nicht gesperrt, so dass die neueste Version heruntergeladen wurde, wodurch das Problem entstand.

Lektion 1: Die Wiederherstellung einer Anwendung mit dynamischen Abhängigkeiten kann unzuverlässig sein, da die Abhängigkeiten im Laufe der Zeit aktualisiert werden, was es schwierig macht, die genaue Umgebung zu reproduzieren, in der Ihre Anwendung erstellt wurde.

Problematisches Szenario 2: Unvorhersehbare Fehler für Benutzer

Wenn Sie eine Bibliothek erstellen und den Benutzern empfehlen, eine dynamische Version Ihrer Bibliothek zu verwenden (z. B., com.vonage.client:client-sdk:2.7.+), könnten sie unwissentlich auf Fehler stoßen, die in neuen Versionen der Bibliothek eingeführt wurden. Sie werden wahrscheinlich Probleme melden, ohne jedoch die genaue Ursache zu kennen - weil sie eine neuere Version als erwartet verwendet haben.

Lektion: Vermeiden Sie es, Benutzern zu raten, dynamische Abhängigkeiten für produktive Anwendungen zu verwenden. Es kann schwierig sein, die Ursache eines Fehlers festzustellen, und die Benutzer können möglicherweise nicht einfach zu einer funktionierenden Version zurückkehren.

Moderne Lösungen für das Management von Abhängigkeiten

Um die durch dynamische Abhängigkeiten verursachten Probleme zu entschärfen, gibt es moderne Werkzeuge und Strategien:

1. Gradle Locking Features verwenden

Das in Gradle eingebaute Dependency Locking ermöglicht es Ihnen, die Versionen von Abhängigkeiten zu kontrollieren, auch wenn Sie dynamische Versionierung verwenden. Dies stellt sicher, dass der Versionsspezifizierer in der build.gradle Datei dynamisch sein kann, die tatsächliche Version, die während des Builds verwendet wird, gesperrt ist.

Zum Aktivieren Sperren von Abhängigkeitenzu aktivieren, können Sie folgendes zu Ihrer build.gradle Datei hinzufügen:

dependencyLocking {
    lockAllConfigurations()
}

Führen Sie dann eine Sperrdatei aus, um eine Sperrdatei zu erzeugen:

./gradlew dependencies --write-locks

Die generierte dependencies.lock Datei stellt sicher, dass jeder in Ihrem Team dieselben Versionen von Abhängigkeiten verwendet, wodurch Builds deterministisch werden und die Wahrscheinlichkeit von Fehlern verringert wird.

2. Verwendung des Gradle Dependency Lock Plugins

Für Teams, die erweiterte Funktionen benötigen, ist das gradle-versions-plugin kann helfen, veraltete Abhängigkeiten zu verfolgen. Führen Sie den folgenden Befehl aus, um nach Updates zu suchen:

./gradlew dependencyUpdates

Führen Sie dann eine Sperrdatei aus, um eine Sperrdatei zu erzeugen:

./gradlew dependencyUpdates

Mit diesem Befehl wird ein Bericht erstellt, der alle veralteten Abhängigkeiten in Ihrem Projekt auflistet. Bei großen Projekten können Sie so sicherstellen, dass Ihre Abhängigkeiten auf dem neuesten Stand sind, ohne jede einzelne manuell überprüfen zu müssen.

3. Sperren bestimmter Versionen mitstrictly

Wenn Sie eine feinkörnige Kontrolle darüber benötigen, welche Versionen einer Abhängigkeit verwendet werden (sogar mit dynamischer Versionierung), können Sie Gradles strictly Funktion verwenden:

dependencies {
    implementation('com.vonage.client:client-sdk:2.7.+') {
        strictly '2.7.1'
    }
}

Dies ermöglicht eine dynamische Versionierung, sperrt aber die Version auf 2.7.1und verhindert, dass neuere Versionen unerwartet verwendet werden.

4. IDE-Warnungen

Moderne IDEs wie IntelliJ IDEA oder Android Studio warnen Sie, wenn Sie dynamische Abhängigkeiten verwenden, wodurch es einfacher wird, potenzielle Probleme zu erkennen, bevor sie entstehen. Außerdem bieten sie oft einfache Aktionen zum Aktualisieren oder Sperren von Abhängigkeitsversionen.

Bewährte Praktiken für die Verwaltung von Abhängigkeiten

  1. Explizite Definition von Versionen in Produktionsumgebungen: Geben Sie im Produktionscode immer die genaue Version an, um unerwartete Probleme durch neue Bibliotheksversionen zu vermeiden.

  2. Sperren von Abhängigkeiten verwenden: Sperren Sie Abhängigkeiten auf bestimmte Versionen, um sicherzustellen, dass Ihre Builds in allen Umgebungen reproduzierbar sind.

  3. Aktualisierungen mit Tools automatisieren: Erwägen Sie den Einsatz von Tools wie Dependabot für die automatische Verwaltung von Abhängigkeiten in Ihrem Repository. Dies hilft Ihnen, den Überblick über Updates zu behalten, ohne jede Abhängigkeit manuell überprüfen zu müssen.

  4. Changelogs überprüfen: Bevor Sie die Abhängigkeiten aktualisieren, sollten Sie die Änderungsprotokolle überprüfen, um sicherzustellen, dass Sie über alle Änderungen und neuen Funktionen informiert sind.

  5. Ausführlicher Test: Wenn Sie dynamische Abhängigkeiten verwenden, stellen Sie sicher, dass Sie eine gute Testabdeckung haben, um Probleme zu erkennen, die durch Änderungen in Ihren Abhängigkeiten entstehen können.

Schlussfolgerung

Dynamische Abhängigkeiten in Gradle bieten zwar Komfort, können aber auch Risiken mit sich bringen, wie zum Beispiel inkonsistente Builds und unvorhersehbare Bugs. Es ist am besten, Abhängigkeiten mit den in Gradle eingebauten Locking-Funktionen oder mit Plugins wie dem gradle-versions-plugin. Bei produktiven Applikationen empfiehlt es sich, genaue Versionen anzugeben, um unerwartete Probleme zu vermeiden und die Reproduzierbarkeit zu gewährleisten. Mit den richtigen Strategien und Werkzeugen können Sie Ihre Abhängigkeiten sicher verwalten und Ihre Builds stabil halten.

Haben Sie eine Frage oder möchten Sie etwas mitteilen? Beteiligen Sie sich am Gespräch auf dem Vonage Community Slackund bleiben Sie auf dem Laufenden mit dem Entwickler-Newsletter, folgen Sie uns auf X (früher Twitter), abonnieren Sie unseren YouTube-Kanal für Video-Tutorials, und folgen Sie der Vonage Entwickler-Seite auf LinkedInein Raum für Entwickler, um zu lernen und sich mit der Community zu vernetzen. Bleiben Sie in Verbindung, teilen Sie Ihre Fortschritte und halten Sie sich über die neuesten Nachrichten, Tipps und Veranstaltungen für Entwickler auf dem Laufenden!

Teilen Sie:

https://a.storyblok.com/f/270183/384x384/8ae5af43bb/igor-wojda.png
Igor WojdaVonage Ehemalige