先日、Google Play servicesを11.6.2から11.8.0に上げたら以下のエラーが出ました。
Exception in thread "main" java.lang.IllegalArgumentException
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:121)
at com.google.devtools.build.android.desugar.DefaultMethodClassFixer$DefaultMethodFinder.visit(DefaultMethodClassFixer.java:535)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:621)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.google.devtools.build.android.desugar.DefaultMethodClassFixer.defaultMethodsDefined(DefaultMethodClassFixer.java:388)
at com.google.devtools.build.android.desugar.DefaultMethodClassFixer.visitEnd(DefaultMethodClassFixer.java:97)
at org.objectweb.asm.ClassVisitor.visitEnd(ClassVisitor.java:339)
at com.google.devtools.build.android.desugar.InterfaceDesugaring.visitEnd(InterfaceDesugaring.java:116)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:702)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:515)
at com.google.devtools.build.android.desugar.Desugar.desugarOneInput(Desugar.java:393)
at com.google.devtools.build.android.desugar.Desugar.desugar(Desugar.java:336)
at com.google.devtools.build.android.desugar.Desugar.main(Desugar.java:816)
Google先生に聞いてもこれだけの情報だとわかりませんでした。
そんな時は、bazelを使ってDesugarの環境を作りましょう。
ちなみにdesugarとは簡単に言うと「javacコンパイラの出力した.class
をさらにバイトコード変換をするツール」です。
https://developer.android.com/studio/write/java8-support.html?hl=ja
bazelとは、googleが開発しているmakeに変わるビルドツールです。iosやandroidアプリのビルドも可能です。
Bazel
インストールします。JDK8が必要なので先にインストールしてください。
その後、homebrewでインストールします。
それ以外の環境はこちらを参照ください。
$ brew install bazel
Desugar
次にソースを取得します。
Bazelのサイトからcloneします。
$ git clone git@github.com:bazelbuild/bazel.git
このソースのルートディレクトリで以下のコマンドを叩きます。
$ bazel build //src/tools/android/java/com/google/devtools/build/android/desugar:Desugar
次にビルドエラー時に表示されているコマンドを書きます。
Desugarのビルドエラーの場合は、エラーメッセージ内にコマンドが記述されているはずです。
自分の場合は以下を入力しました。(以下は長いので省略しています。)
$ bazel-bin/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar --verbose \
--input /Users/ユーザ名/アプリまでのパス/app/build/intermediates/transforms/stackFramesFixer/beta/44.jar \
--output /Users/ユーザ名/アプリまでのパス/app/build/intermediates/transforms/desugar/beta/52.jar \
・・・
--bootclasspath_entry /Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home/jre/lib/charsets.jar \
--min_sdk_version 19 \
--desugar_try_with_resources_omit_runtime_classes \
--desugar_try_with_resources_if_needed \
--desugar_try_with_resources_omit_runtime_classes
このコマンドを実行するとAndroid Studioで出たのと同じようにjava.lang.IllegalArgumentExceptionが出ると思います。
デバッグ
cloneしたbazel/src以下にDesugar.javaがあります。
▾ src/
▸ conditions/
▸ java_tools/
▸ main/
▸ objc_tools/
▸ test/
▾ tools/
▾ android/
▾ java/
▾ com/
▾ google/
▾ devtools/
▾ build/
▾ android/
▾ desugar/
Desugar.java
これにLogを書けば色々わかります。
今回は、エラーメッセージのat com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:515)
にある以下の部分にログを仕込みました。
if (inputFilename.endsWith(".class")) {
System.out.println("----------------------------------------------");
System.out.println(inputFilename);
これでどのクラスでエラーが起きているのかがわかります。
再度、コマンドを実行すると以下のクラスがないことが問題だったことがわかります。
com/google/android/gms/internal/zzcec.class
このクラスは,play-service-location
のクラスのものでした。
以下コマンドで依存しているライブラリを見るとOneSignalに依存しているplay-services-locationが11.6.2のままでした。
$ ./gradlew :app:dependencies
+--- com.onesignal:OneSignal:3.8.1
| +--- com.google.android.gms:play-services-location:[11.6.2)
これを11.8.0が使われるようにbuild.gradle明示的に指定して解決しました。
implementation "com.google.android.gms:play-services-location:11.8.0"