LoginSignup
8
7

More than 5 years have passed since last update.

Android/ScalaでNoSuchMethodErrorのデバッグ - sbt編

Last updated at Posted at 2014-03-22

LogCatで下の様にNoSuchMethodErrorが出るときのデバッグ方法メモ。
環境はこちらで準備したsbt。NoClassDefFoundErrorも同様にできるはず。

03-21 14:28:46.023: E/AndroidRuntime(7507): java.lang.NoSuchMethodError: com.fasterxml.jackson.core.JsonFactory.createParser

上はJsonFactory.createParser が見つからない、という例。

1. クラスファイルにメソッドがあるか調べる

./target/に生成されるjarファイルを下の様にunzipで展開し、

$ cd ./target
$ unzip classes-myapp1-compile-0.1.min.jar
...
  inflating: com/fasterxml/jackson/core/JsonFactory$Feature.class
  inflating: com/fasterxml/jackson/core/JsonFactory.class
...

javapコマンドでそのメソッドがあるかをチェックする。

$ javap com.fasterxml.jackson.core.JsonFactory
...
    public com.fasterxml.jackson.core.JsonParser createJsonParser(java.lang.String) ...;
    public com.fasterxml.jackson.core.JsonParser createJsonParser(java.io.File)...;
...

メソッド名がみつからない場合、3. 依存しているライブラリのjarファイルが古くないかをチェックし、それでもだめなら 4. proguard でそのメソッドを保持するように設定してみる。

2. dexファイルにメソッドがあるか調べる

1とは別に、dexdumpを使ってメソッド名があるかを調べることもできる。

$ cd ./target
$ $ANDROID_HOME/build-tools/19.0.0/dexdump classes-myapp1-compile-0.1.dex|grep createParser

上はcreateParserを調べる例。grep -20 ...として前後を表示してみるなどする。

1.と同様に、メソッド名がみつからない場合は下の 3. or 4. を当たってみる。

3. 依存しているライブラリのバージョンを調べる

  1. or 2.でメソッド名が見つからない場合、依存ライブラリのバージョンを調べる。下の様にsbtのコンソールで依存ライブラリのパスが取得できるので、バージョン番号を確認し古ければ更新する。
$ sbt
> show dependency-classpath

4. proguardでメソッドが取り除かれないようにする

3.が問題ない場合、proguardに-keepオプションを追加する。
ただし、-keepの範囲を増やすと下のようなエラーに遭遇することがある。

trouble writing output: excess write of ...

その時は、sbtを立ち上げ直すか、こちらのようにanalysisBudgetを大きな値にすると解消することが多い。なぜかは良く分かっていない。

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7