More Related Content Similar to Scala2.10.x bytecode problems in Android Similar to Scala2.10.x bytecode problems in Android (20) More from Taisuke Oe (10) Scala2.10.x bytecode problems in Android1. Scala2.10
bytecode problem
hemplant Inc. @OE_uia / Taisuke Oe
13年3月14日木曜日
3. Scala2.9.x
javap -c Hello$delayedInit$body
------
public final class Hello$delayedInit$body extends scala.runtime.AbstractFunction0
implements scala.ScalaObject{
public final java.lang.Object apply();
Code:
0:new#7; //class Duck
3:dup
4:invokespecial#12; //Method Duck."<init>":()V
7:invokevirtual#15; //Method Duck.fly:()V
10:getstatic#21; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
13:areturn
......
}
13年3月14日木曜日
4. Scala2.10.x
javap -c Hello$delayedInit$body
------
public final class Hello$delayedInit$body extends scala.runtime.AbstractFunction0{
public final java.lang.Object apply();
Code:
0:new#9; //class Duck
3:dup
4:invokespecial#13; //Method Duck."<init>":()V
7:invokevirtual#18; //Method Bird.fly:()V
10:getstatic#24; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
13:areturn
.....
}
13年3月14日木曜日
6. 何か問題でも?
Android 4.1以上のライブラリ
+
Scala2.10.x
+
Android4.0以下の端末
de
NoSuchMethodError
13年3月14日木曜日
7. 前提として
• Android APIのクラスファイルは実行ファイ
ル(apk)には含まれず、Android端末内のも
のを参照する。
• AndroidのtargetSDKversionより、
minSDKversionが低いことはよくありま
す。 (例: Android 4.1以上の場合は4.1で
追加された「ほげほげView」を使うけど、
Android 2.3では他のViewで代替する、な
ど。)
13年3月14日木曜日
8. 何か問題でも?
Android 4.1以上のライブラリ
+
Scala2.10.x
+
Android4.0以下の端末
だと....
13年3月14日木曜日
9. SQLiteDatabaseを閉じれない!!
threadid=1: thread exiting with uncaught exception (group=0x40abd210)
FATAL EXCEPTION: main
java.lang.NoSuchMethodError: android.database.sqlite.SQLiteClosable.close
at com.hemplant.demo.no_such_method_in_2_10.DemoActivity.onCreate(DemoActivity.scala:18)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
....
13年3月14日木曜日
10. Why? SQLiteDatabase
・Android1.5からcloseメソ
ッドを持っている。
・closeメソッドを実装している
クラスが、Android4.1から変
更された。
13年3月14日木曜日
13. 逆に言えばAndroid4.0までは、
SQLiteDatabaseの親クラス
SQLiteClosableにcloseメソッドは無かった。
(名前がClosableなのに!)
13年3月14日木曜日
14. closeメソッドの実装まとめ
~Android 4.0 Android4.1~
SQLiteClosable
× ⃝
.close
SQLiteDatabase
⃝ 継承
.close
13年3月14日木曜日
16. Scala2.9.xでは子クラス(Duck)のメソッドとして
呼び出すbytecodeを生成するのに対し
7:invokevirtual#15; //Method Duck.fly:()V
Scala 2.10.xではメソッドを実装した親クラス
(Bird)のメソッドとして呼び出すbytecodeが生成さ
れる。
7:invokevirtual#18; //Method Bird.fly:()V
13年3月14日木曜日
17. (Android4.1以上をtargetにすると)
Scala2.9.xだとSQLiteDatabaseのメソッドとして
呼び出すbytecodeを生成するのに対し、
58:invokevirtual#55;
//Method android/database/sqlite/SQLiteDatabase.close:()V
Scala 2.10.xだとSQLiteClosable(closeを実装した
親クラス)のメソッドとして呼び出すbytecodeを生成。
=> Android4.0以下には無い!!
=> NoSuchMethodError
58:invokevirtual#55;
//Method android/database/sqlite/SQLiteClosable.close:()V
13年3月14日木曜日
18. まとめ
• Scala2.10からは、そのメソッドを実装したクラス(当該インス
タンスのクラスor親クラス)のメソッドとしてinvokevirtualす
るbytecodeが生成される。
• 実行環境と開発環境のクラスファイルが一致しないケースで、かつ
メソッドを実装したクラスに違いがあると、一見イミフな
NoSuchMethodErrorを吐き出すので注意。
• 具体的には、Android4.1以上をtarget SDK versionにし
たら、Scala2.10.xを使わないか、minSdkVersionも4.1
以上を指定すること。
13年3月14日木曜日
19. 最後に
• Scala2.10.xで、なぜこんな変更をされたの
か、経緯をご存知の方教えてください! (当面
codegenしてissuesに上げつつ、ソースの
diff追います。)
• 再現用プロジェクトLink:
• https://github.com/taisukeoe/scala_2_10_android_error
13年3月14日木曜日