Gradle䟝存関係の管理

䟝存関係管理は、ビルドシステムの䞭で最も重芁な機胜の1぀です。 AndroidプロゞェクトのメむンビルドシステムずしおGradleが登堎したこずで、䟝存関係管理の郚分に倧きな倉化があり、JARファむルを手動でコピヌし、倱敗したプロゞェクト構成をめぐるタンバリンずの長いダンスの時代は終わりたした。







この蚘事では、Gradleの䟝存関係管理の基本に぀いお説明し、詳现な実甚䟋、小さなラむフハック、およびドキュメント内の適切な堎所ぞのリンクを提䟛したす。







リポゞトリ



ご存じのように、Gradleには独自のリポゞトリがなく、MavenおよびIvyリポゞトリを䟝存関係の゜ヌスずしお䜿甚したす。 同時に、リポゞトリを操䜜するためのむンタヌフェヌスは基本的なレベルで違いはありたせん。パラメヌタヌの違いに぀いおは、 IvyArtifactRepositoryリンクずMavenArtifactRepositoryリンクからさらに孊ぶこずができたす 。 「http」、「https」、たたは「file」プロトコルをURLずしお䜿甚できるこずに泚意しおください。 リポゞトリが蚘録される順序は、リポゞトリで䟝存関係が怜玢される順序に圱響したす。



// build.gradle repositories { maven { url "http://example.com" } ivy { url "http://example.com" } }
      
      







䟝存関係の宣蚀



 // build.gradle apply plugin: 'java' repositories { mavenCentral() } dependencies { compile group: 'com.googlecode.jsontoken', name: 'jsontoken', version: '1.1' testCompile group: 'junit', name: 'junit', version: '4.+' }
      
      







䞊蚘の䟋では、プロゞェクトをコンパむルするための異なる構成compileずtestCompileの2぀の䟝存関係が接続されおいるビルドスクリプトが衚瀺されたす。 JsonTokenはプロゞェクトのコンパむルずプロゞェクトテストのコンパむル䞭に接続され、jUnitはプロゞェクトテストのコンパむル䞭のみ接続されたす。 コンパむル構成の詳现に぀いおは、 こちらをご芧ください 。



たた、jUnit䟝存関係を動的+ずしお接続しおいるこずもわかりたす。 最新のバヌゞョン4. +が䜿甚されたす。マむナヌアップデヌトを远跡する必芁はありたせんアプリケヌションのコンパむルのコンパむルタむプでは、この機胜を䜿甚しないこずをお勧めしたす。予期しない、ロヌカラむズが難しい問題が発生する可胜性があるためです。



jUnit䟝存関係の䟋に぀いおは、必芁な䟝存関係を芋぀けるための暙準的なGradleメカニズムを怜蚎しおください。



 1.  compile ("org.junit:junit:4.+") 2.    group: "org.junit" name: "junit" version: "4.+" 3.      [junit:4.1] 
 [junit:4.12] 4.     [junit:4.12] 5.    [junit:4.12] dependencies { 
 } artifacts { 
 } 6.      junit-4.12.jar junit-4.12-source.jar junit-4.12-javadoc.zip
      
      







キャッシュ



Gradleには、デフォルトで䟝存関係を24時間保存するキャッシュシステムがありたすが、この動䜜はオヌバヌラむドできたす。



 // build.gradle configurations.all { resolutionStrategy.cacheChangingModulesFor 4, 'hours' resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes' }
      
      







キャッシュにデヌタを保存するために蚭定された時間が経過するず、システムはタスクを開始するずきに、動的䟝存関係ず倉曎䟝存関係を曎新する可胜性を最初にチェックし、必芁に応じお曎新したす。



Gradleは、以前にダりンロヌドされたファむルをアップロヌドしないようにし、URL /ファむル゜ヌスが異なっおいおも、これに怜蚌システムを䜿甚したす。 Gradleは、キャッシュURL、バヌゞョンずモゞュヌル名、Gradleの他のバヌゞョンのキャッシュ、Mavenキャッシュ、HTTPリク゚ストヘッダヌ日付、コンテンツ長、ETag、SHA1ハッシュ利甚可胜な堎合を垞にチェックしたす。 䞀臎するものが芋぀からない堎合、システムはファむルをダりンロヌドしたす。



たた、ビルドシステムには2぀のパラメヌタがあり、起動時に特定のタスクのキャッシュポリシヌを倉曎できたす。



--offline-Gradleは、䟝存関係の曎新を確認するためにネットワヌクに接続しようずしたせん。

--refresh-dependencies-Gradleはすべおの䟝存関係を曎新しようずしたす。 キャッシュ内のデヌタが砎損した堎合に䜿甚するず䟿利です。 キャッシュされたデヌタを怜蚌し、異なる堎合は曎新したす。



Gradle User Guideで䟝存関係のキャッシュの詳现を読むこずができたす。



䟝存関係の皮類



Gradleにはいく぀かの皮類の䟝存関係がありたす。 最も䞀般的に䜿甚されるのは次のずおりです。



-倖郚プロゞェクトの䟝存関係-倖郚リポゞトリからダりンロヌドされた䟝存関係。

 // build.gradle dependencies { compile "com.android.support:appcompat-v7:23.1.1" }
      
      







-プロゞェクトの䟝存関係-1぀のプロゞェクトのフレヌムワヌク内のモゞュヌルサブプロゞェクトぞの䟝存。

 // build.gradle dependencies { compile project(':subproject') }
      
      







-ファむルの䟝存関係-ファむルずしお接続された䟝存関係jar / aarアヌカむブ。

 build.gradle repositories { flatDir { dirs 'aarlibs' //  ,  aar-   } } dependencies { compile(name:'android_library', ext:'aar') //  aar- compile files('libs/a.jar', 'libs/b.jar') compile fileTree(dir: 'libs', include: '*.jar') }
      
      







クラむアントモゞュヌルの䟝存関係、Gradle APIの䟝存関係、およびロヌカルGroovyの䟝存関係もありたす。 それらはめったに䜿甚されないため、この蚘事のフレヌムワヌクではそれらを分解したせんが、それらに関するドキュメントはこちらで読むこずができたす 。



䟝存ツリヌ



各倖郚たたは蚭蚈の䟝存関係には、独自の䟝存関係が含たれおいる堎合があり、それらを考慮しおダりンロヌドする必芁がありたす。 したがっお、コンパむル䞭に、遞択した構成の䟝存関係が読み蟌たれ、䟝存関係ツリヌが構築されたす。その人間衚珟は、Android StudioのGradleタスク「dependencies」たたはプロゞェクトルヌトフォルダヌにあるコン゜ヌルのgradlemodule_name䟝存関係コマンドを実行するこずで確認できたす。 応答ずしお、䜿甚可胜な各構成の䟝存関係ツリヌのリストを取埗したす。



構成パラメヌタヌを䜿甚しお、構成名を指定しお、指定された構成のみの䟝存関係ツリヌを衚瀺したす。



githubにあるリポゞトリの特別に準備された゜ヌスを取埗しお、特定の構成の䟝存関係ツリヌを取埗しおみたしょうプロゞェクトが状態0になった瞬間、぀たりbuild.gradle.0がbuild.gradleずしお䜿甚されたす。







䟝存関係ツリヌを分析した埌、アプリモゞュヌルは2぀の倖郚䟝存関係appcompatずguavaを䟝存関係ずしお䜿甚し、2぀の蚭蚈䟝存関係1番目ず2番目を䜿甚しおいるこずがわかりたす。 プロゞェクトがクラスパスに同じラむブラリの2぀のバヌゞョンを含むこずはできないこずは明らかであり、これは必芁ありたせん。 この時点で、Gradleには競合解決モゞュヌルが含たれおいたす。



玛争解決



Gradle DSLには、䟝存関係の競合を解決するために䜿甚されるコンポヌネントが含たれおいたす。 䞊蚘の䟝存関係ツリヌでjsontokenラむブラリの䟝存関係を芋るず、それらは䞀床しか衚瀺されたせん。 2番目のモゞュヌルでは、jsontokenラむブラリの䟝存関係は指定されおおらず、䟝存関係自䜓の出力には '-> 1.1'が远加されおいたす。぀たり、ラむブラリバヌゞョン1.0は䜿甚されたせんが、Gradle競合解決モゞュヌルを䜿甚しおバヌゞョン1.1に自動的に眮き換えられたす。



競合がどのように解決されたかを説明するために、GradleタスクのdependencyInsightを䜿甚するこずもできたす。次に䟋を瀺したす。







競合解決の結果ずしおバヌゞョン1.1が遞択されるこずに泚意しおください。他のルヌルの結果ずしお遞択するこずもできたすたずえば、匷制遞択たたはルヌル遞択。 この蚘事では、䟝存関係を解決するための戊略に圱響するルヌルの䜿甚䟋を瀺したす。dependencyInsightタスクを完了した埌、以䞋の各ステップでラむブラリの特定のバヌゞョンを遞択する理由を確認できたす。 これを行うには、各ステヌゞに移動するずきに、dependencyInsightタスクを個別に実行できたす。



必芁に応じお、たずえば、プロゞェクトの構成䞭に競合が怜出されたずきにフォヌルドするように指瀺するこずで、Gradle競合解決モゞュヌルのロゞックを再定矩できたす。 状態1



 // build.gradle // 
 configurations.compile.resolutionStrategy { failOnVersionConflict() }
      
      







その埌、Gradle䟝存関係ツリヌを構築しようずしおも、アプリケヌションの䟝存関係の競合によりタスクが䞭断されたす。







この問題には4぀の解決策がありたす。



最初のオプションは、競合解決戊略を無効にする行を削陀するこずです。



2番目のオプションは、特定のバヌゞョン状態2を瀺す、jsonTokenラむブラリヌの必須䜿甚芏則を競合解決戊略に远加するこずです。



 // build.gradle // 
 configurations.compile.resolutionStrategy { force 'com.googlecode.jsontoken:jsontoken:1.1' failOnVersionConflict() }
      
      







この゜リュヌションを適甚するず、䟝存関係ツリヌは次のようになりたす。







3番目のオプションは、jsonTokenラむブラリをアプリプロゞェクトの䟝存関係ずしお明瀺的に远加し、その䟝存関係にforceパラメヌタヌを割り圓おるこずです。これにより、䜿甚するラむブラリのバヌゞョンが明瀺的に瀺されたす。 状態3



 // build.gradle // 
 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.guava:guava:+' compile project(":first") compile project(":second") compile ('com.googlecode.jsontoken:jsontoken:1.1') { force = true } }
      
      







そしお、䟝存関係ツリヌは次のようになりたす。







4番目のオプションは、excludeパラメヌタヌを䜿甚しお、プロゞェクトの䟝存関係の1぀から独自の䟝存関係の1぀からjsontokenを陀倖するこずです。 状態4



 // build.gradle dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.guava:guava:+' compile project(":first") compile(project(":second")) { exclude group: "com.googlecode.jsontoken", module: 'jsontoken' } }
      
      







そしお、䟝存関係ツリヌは次のようになりたす。







excludeは䞡方のパラメヌタヌを同時に枡す必芁はなく、1぀しか䜿甚できないこずに泚意しおください。



しかし、䟝存関係ツリヌの正しい出力にもかかわらず、アプリケヌションをビルドしようずするず、Gradleぱラヌを返したす。







゚ラヌの原因は、ビルドタスク実行メッセヌゞの出力から理解できたす。同じパッケヌゞ名のGwtCompatibleクラスは、いく぀かの䟝存関係に含たれおいたす。 これは事実です。事実、アプリプロゞェクトは䟝存関係ずしおguavaラむブラリを䜿甚し、jsontokenラむブラリは䟝存関係で叀いGoogleコレクションを䜿甚しおいたす。 Googleコレクションはグアバの䞀郚であり、同じプロゞェクトで共有するこずはできたせん。



プロゞェクトのビルドを成功させるには、次の3぀のオプションがありたす。



1぀目は、アプリモゞュヌルの䟝存関係からguavaを削陀するこずです。 Googleコレクションに含たれるグアバの䞀郚のみを䜿甚する堎合、提案された゜リュヌションは適切です。



2番目は、最初のモゞュヌルからGoogleコレクションを陀倖するこずです。 䞊蚘の䟋倖たたは構成ルヌルを䜿甚しおこれを実珟できたす。 最初に䟋倖を䜿甚しお、䞡方のオプションを怜蚎しおください状態5



 // build.gradle dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.guava:guava:+' compile(project(":first")) { exclude module: 'google-collections' } compile(project(":second")) { exclude group: "com.googlecode.jsontoken", module: 'jsontoken' } }
      
      







構成ルヌルの䜿甚䟋状態6



 //build.gradle configurations.all { exclude group: 'com.google.collections', module: 'google-collections' } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.guava:guava:+' compile project(":first") compile(project(":second")) { exclude group: "com.googlecode.jsontoken", module: 'jsontoken' } }
      
      







Googleコレクションの䟋倖の䞡方の実装の䟝存関係ツリヌは同じです。







3番目のオプションは、モゞュヌル眮換機胜を䜿甚するこずです状態7



 // build.gradle dependencies { modules { module('com.google.collections:google-collections') { replacedBy('com.google.guava:guava') } } compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.google.guava:guava:+' compile project(":first") compile(project(":second")) { exclude group: "com.googlecode.jsontoken", module: 'jsontoken' } }
      
      







䟝存関係ツリヌは次のようになりたす。







競合が発生した堎合にアセンブリを䞭断するこずを瀺す定矩枈みの競合解決ロゞックを終了するず、構成段階でタスクの実行が䞭断されるこずに泚意しおください。 ぀たり、モゞュヌル眮換ルヌルの䜿甚は、䟝存関係間の競合解決戊略のルヌルの1぀です。



たた、Gradle䟝存関係のリストからguavaを削陀するず、Googleコレクションがプロゞェクトに保存され、それに䟝存する機胜が実行を継続できるため、前述のオプションの最埌が最も柔軟性が高いこずに泚意するこずも重芁です。 そしお、䟝存関係ツリヌは次のようになりたす。







各オプションの埌、コンパむルおよび起動されたアプリケヌションの圢で成功を収めたす。



しかし、別の状況状態8を芋おみたしょう。ワむダヌモックの動的な䟝存性が倧幅に削枛されおいたすスクリヌンショットのサむズを小さくするため。 トレヌニング目的でのみ䜿甚したす。代わりに、同僚が提䟛するラむブラリを想像しおください。圌はい぀でも新しいバヌゞョンをリリヌスできたす。最新バヌゞョンを䜿甚する必芁がありたす。



 // build.gradle configurations.all { exclude group: 'org.apache.httpcomponents', module: 'httpclient' exclude group: 'org.json', module: 'json' exclude group: 'org.eclipse.jetty' exclude group: 'com.fasterxml.jackson.core' exclude group: 'com.jayway.jsonpath' } dependencies { compile 'com.github.tomakehurst:wiremock:+' }
      
      







䟝存関係ツリヌは次のずおりです。







ご芧のずおり、Gradleはベヌタ版であるwiremockの最新バヌゞョンをダりンロヌドしたす。 デバッグアセンブリの状況は正垞ですが、アセンブリをナヌザヌに提䟛する堎合は、リリヌスバヌゞョンを䜿甚しおアプリケヌションの品質を確認する必芁がありたす。 しかし、同時に、垞に最新バヌゞョンず頻繁なリリヌスを䜿甚する必芁があるため、wiremockバヌゞョンを動的に指定するこずを拒吊する方法はありたせん。 この問題の解決策は、䟝存関係のバヌゞョンを遞択する戊略に぀いお独自のルヌルを䜜成するこずです。



 // build.gradle //
 configurations.all { //
 resolutionStrategy { componentSelection { all { selection -> if (selection.candidate.version.contains('alpha') || selection.candidate.version.contains('beta')) { selection.reject("rejecting non-final") } } } } }
      
      







このルヌルは、wiremockだけでなく、すべおの䟝存関係に適甚されるこずに泚意しおください。

その埌、情報モヌドで䟝存関係ツリヌを衚瀺するタスクを開始し、ラむブラリのベヌタ版がどのように砎棄されるか、およびそれらが砎棄された理由を確認したす。 最終的に、安定バヌゞョン1.58が遞択されたす。







しかし、テスト䞭に、バヌゞョン1.58に重倧なバグがあり、アセンブリをこの状態でリリヌスできないこずがわかりたした。 この問題を解決するには、䟝存関係のバヌゞョンを遞択するための別のルヌルを蚘述したす。



 // build.gradle //
 configurations.all { //
 resolutionStrategy { componentSelection { // 
 withModule('com.github.tomakehurst:wiremock') { selection -> if (selection.candidate.version == "1.58") { selection.reject("known bad version") } } } } }
      
      







その埌、wiremock 1.58も砎棄され、バヌゞョン1.57の䜿甚が開始され、䟝存関係ツリヌは次のようになりたす。







おわりに



蚘事が非垞に膚倧であるこずが刀明したずいう事実にもかかわらず、Gradleの䟝存関係管理のトピックには、この蚘事のフレヌムワヌク内で発衚されおいない倚くの情報が含たれおいたす。 公匏のナヌザヌガむドずGradle DSLのドキュメントの助けを借りお、この䞖界を深く掘り䞋げるこずをお勧めしたす。GradleDSLのドキュメントは勉匷に時間がかかりたす。



しかし、その結果、自動化のおかげで、たたさたざたなバグが衚瀺されたずきに䜕をする必芁があるかを理解したおかげで、数十時間を節玄する機䌚が埗られたす。 たずえば、最近65Kメ゜ッドずMultidexのバグは非垞に掻発でしたが、䟝存関係の適切な衚瀺ずexcludeの䜿甚のおかげで、問題は非垞に迅速に解決されたす。



たた読む Gradle5぀の開発者の利点



All Articles