Scala2.10.x bytecode problems in Android

2,787 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,787
On SlideShare
0
From Embeds
0
Number of Embeds
1,809
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Scala2.10.x bytecode problems in Android

  1. 1. Scala2.10 bytecode problem hemplant Inc. @OE_uia / Taisuke Oe13年3月14日木曜日
  2. 2. Q.以下のソースコードをコンパイルした際の bytecode、Scala2.10と2.9で 違うってご存知でしたか?13年3月14日木曜日
  3. 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. 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日木曜日
  5. 5. Scala2.9.xでは子クラス(Duck)のメソッドとして呼び出すbytecodeを生成するのに対し 7:invokevirtual#15; //Method Duck.fly:()VScala 2.10.xではメソッドを実装した親クラス(Bird)のメソッドとして呼び出すbytecodeが生成される。 7:invokevirtual#18; //Method Bird.fly:()V13年3月14日木曜日
  6. 6. 何か問題でも? Android 4.1以上のライブラリ + Scala2.10.x  + Android4.0以下の端末 de NoSuchMethodError13年3月14日木曜日
  7. 7. 前提として • Android APIのクラスファイルは実行ファイ ル(apk)には含まれず、Android端末内のも のを参照する。 • AndroidのtargetSDKversionより、 minSDKversionが低いことはよくありま す。 (例: Android 4.1以上の場合は4.1で 追加された「ほげほげView」を使うけど、 Android 2.3では他のViewで代替する、な ど。)13年3月14日木曜日
  8. 8. 何か問題でも? Android 4.1以上のライブラリ + Scala2.10.x  + Android4.0以下の端末 だと....13年3月14日木曜日
  9. 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. 10. Why? SQLiteDatabase ・Android1.5からcloseメソ ッドを持っている。 ・closeメソッドを実装している クラスが、Android4.1から変 更された。13年3月14日木曜日
  11. 11. Android4.0までは、SQLiteDatabaseで closeメソッドが実装されていた。13年3月14日木曜日
  12. 12. Android4.1からはSQLiteDatabaseの親クラス SQLiteClosableでcloseメソッドが実装 され、SQLiteDatabaseは継承したcloseメソッドを 使用するように変更された。13年3月14日木曜日
  13. 13. 逆に言えばAndroid4.0までは、 SQLiteDatabaseの親クラス SQLiteClosableにcloseメソッドは無かった。 (名前がClosableなのに!)13年3月14日木曜日
  14. 14. closeメソッドの実装まとめ ~Android 4.0 Android4.1~ SQLiteClosable × ⃝ .close SQLiteDatabase ⃝ 継承 .close13年3月14日木曜日
  15. 15. ここでもう一度13年3月14日木曜日
  16. 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:()V13年3月14日木曜日
  17. 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:()V13年3月14日木曜日
  18. 18. まとめ • Scala2.10からは、そのメソッドを実装したクラス(当該インス タンスのクラスor親クラス)のメソッドとしてinvokevirtualす るbytecodeが生成される。 • 実行環境と開発環境のクラスファイルが一致しないケースで、かつ メソッドを実装したクラスに違いがあると、一見イミフな NoSuchMethodErrorを吐き出すので注意。 • 具体的には、Android4.1以上をtarget SDK versionにし たら、Scala2.10.xを使わないか、minSdkVersionも4.1 以上を指定すること。13年3月14日木曜日
  19. 19. 最後に• Scala2.10.xで、なぜこんな変更をされたの か、経緯をご存知の方教えてください! (当面 codegenしてissuesに上げつつ、ソースの diff追います。)• 再現用プロジェクトLink:• https://github.com/taisukeoe/scala_2_10_android_error13年3月14日木曜日

×