MoTLab -GO Inc. Engineering Blog-MoTLab -GO Inc. Engineering Blog-

AndroidアプリのJCenter閉鎖の影響調査と暫定対応

Android
February 17, 2021

こんにちは。 車載システム第二グループの空中です。Twitter等では @soranakk で活動しているのでそちらの方がわかるかもしれません。 普段はタクシー車両に搭載された専用端末上で動作するAndroidアプリ開発をしています。

さて、唐突ですがJCenterが閉鎖されます。

https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/

概要についてはこちらの記事が参考になると思います。 https://bps-tomoya.hateblo.jp/entry/2021/02/04/184317

Androidアプリ開発ではほぼほぼ100%ぐらいのアプリがJCenterを参照しているのでJCenterからMavenCentralに移行して大丈夫かどうかを調べる必要があります。 これの影響調査と暫定対応をやったので備忘録として残しておきます。


JCenter閉鎖の影響を調べる

現時点でAndroid Gradle Plugin(AGP)はtrove4jへの依存があり、これがJCenterにあるためAndroidアプリのビルドができません。 https://www.reddit.com/r/androiddev/comments/lbssfn/now_that_bintray_and_jcenter_are_shutting_down/glww2jk/?utm_source=reddit&utm_medium=web2x&context=3 AGP4.2で対応される予定で、4.1にもバックポートされるかもしれません。 現在のAndroid Studioの最新版でもAGPは4.1.2なので、「JCenter閉鎖は自分のプロジェクトにどんな影響があるかな?」って調べようとしてもまずここで詰まってしまいます。

Android Gradle Plugin 7.0.0-alpha05を使う

Android Studioのベータ版のArctic FoxならAGP7.0.0を使えるため、trove4jの問題も回避できます。 ただし、AGPのバージョンアップが必要でGradleもバージョンが上がるため、プロジェクトによってはマイグレーションが必要です。 私のプロジェクトでもマイグレーションが必要になって、「うへぇ」となったので、この方法は途中で切り上げました。 (一度に二つのことに手を出さない)

trove4jだけJCenterから持ってきて使う

https://twitter.com/takke/status/1359357898950778882?s=20

このツイートで知ったのですが、

jcenter().mavenContent {
  includeGroup("org.jetbrains.trove4j")
}

ってやっておけば特定のjarだけJCenterから参照できるので、これをやってAGPの問題をクリアして影響を調べることができます。 私もこの方法を知ったときに「お!いいじゃん、これでやろ!」って思ったのですが、 移行しないといけないライブラリの調査と暫定対応が同時にできる方法が見つかったので、そっちにしました。

MavenCentralにないjarをローカルリポジトリに配置する

プロジェクトのrootに local-repository って名前のフォルダを作ります。 そしてbuild.gradleに

repositories {
    google()
    mavenCentral()
    maven { url "https://plugins.gradle.org/m2/" }
    maven { url = rootProject.file('local-repository') }
}

って感じで優先順位を一番低くして登録します。 そしてlocal-repositoryの下にrepositoryのurl構造と同じようにフォルダを切って、MavenCentralにないライブラリのpomファイルとjarファイルを配置します。

こうするとローカルに置いてあるpomとjarを参照して依存関係を解決してくれるようになります。

また優先順位を一番低くしておくことで、対象のライブラリがMavenCentralに移行されたら自動的にMavenCentralのライブラリを参照するようになります。

repositoryのurl構造の調べ方

こちらのツイートを参考にして、一旦JCenterの依存を消してビルドしてみます。

https://twitter.com/sys1yagi/status/1357509730713829378?s=20

  • build.gradleにローカルリポジトリを追加する
  • build.gradleから jcenter()maven { url "http://dl.bintray.com... を削除する
  • ./gradlew --refresh-dependencies する
  • ./gradlew assemble --stacktrace --info する

そうするとエラーが発生して止まりますので、その時のログを見ます。

Searched in the following locations:
    https://dl.google.com/dl/android/maven2/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.pom
    https://dl.google.com/dl/android/maven2/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.jar
    https://repo.maven.apache.org/maven2/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.pom
    https://repo.maven.apache.org/maven2/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.jar

って感じでgoogleのリポジトリやMavenCentralのリポジトリを参照した時のログを探します。 そして、これに従って local-repository/org/jetbrains/trove4j/trove4j/20160824/ にpomとjarを配置したらいいです。

pomとjarの探し方

まずは一回、JCenterを参照した状態でビルドしてgradleのキャッシュにjarやpomをDLしておきます。(普段ビルドしているPCならすでにキャッシュに保存されているはず) そうすると ~/.gradle/caches/modules-2/files-2.1/ の中にjarやpomファイルがDLされてきます。(パスの数字部分は環境によって変わるかも) この中から目当てのjarやpomを探してくればよいです。 もしjarやpomが見つからない場合、 ~/.gradle/caches~/.gradle/caches2 とかにリネームしてからビルドすると再DLしてくれるかも(私の環境では一度起きました)

最終的にキャッシュから見つからなかったら、普通に上で見つけたgoogleやMavenCentralリポジトリのurlを叩いてDLしちゃった方が早いです。

最終的にキャッシュから見つからなかったら、普通に上で見つけたgoogleやMavenCentralリポジトリのurlのリポジトリホーム部分( https://dl.google.com/dl/android/maven2/ とか https://repo.maven.apache.org/maven2/ )をJCenter( https://jcenter.bintray.com/ )に書き換えてDLしちゃった方が早いです。(2021/02/19 修正)

まとめ

JCenterが閉鎖されるのでそれの影響調査と暫定対応を行いました。

プロジェクトrootにローカルリポジトリを作成して優先度最低で参照するようにしました。

ローカルリポジトリのjarはMavenCentralにアップロードされれば優先順位が一番低いので自動的に参照されなくなりますが、これから定期的に各ライブラリの状態をウォッチして適宜消していく予定です。

とりあえず「うわ!ビルドできない!」を回避する状態にしておきました。

追記

ほぼ同じことをやっている人を見つけたので、こちらも参考になると思います。

https://zenn.dev/onozaty/articles/java-local-maven-repository