発火後忘失

FIRE AND FORGET

Androidアプリ開発でMySQL Connector/Jを追加してビルドしようとするとエラーになる

ネタ元:

AndroidJDBCドライバを直接使うっていうのが「その発想は無かったわ!」てな感じでかなり衝撃を受けたのですが、ググってみるとそれなりに事例はありそうです。
まあ、いわゆるDBアプリが今全部Webアプリに置き換わったわけでもないですし、Androidをクライアントに使うとなるとさもありなん、てな感じなんでしょう。

本題です。
Androidアプリビルド時に mysql-connector-java-5.1.37-bin.jar を依存関係に入れていると、次のようなエラーメッセージが出力されます。

Caused by: com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)

クラスファイル解析しようとしたけどファイル形式がおかしいので失敗した、ということなんですが、大抵の場合はAndroidが対応していないバージョンのライブラリを追加した場合にこのエラーになります。

で、その大抵の場合、見るべきポイントは version (0034.0000) の部分で、今回は数値が 34 となっています。
WikipediaのJavaクラスファイル のページ内をこの 34 で検索すると、Java8向けのファイルであることがわかり、AndroidではJava8未対応なので無理なんだな、と納得できます。

なぜ5.1.37(以降)はJava8向けなんだろう、という点については、おそらくJDBC4.2対応のためでしょう:

It is also the first release of MySQL Connector/J to support the Java Database Connectivity (JDBC) 4.2 API.

MySQL :: MySQL Connector/J Release Notes :: Changes in MySQL Connector/J 5.1.37 (2015-10-15)

補足すると、おそらく通常のJava上で使用する分にはJava8は要求されません。なぜなら、Java8未満で使用する分には、JDBC4.2関連のクラスをロードする必要がないためです。JDBC4.2関連クラス以外はJava5向けにビルドされているようです。

javap コマンドを.classファイルに対して実行すればバージョンがわかりますので試してみましょう:

$ javap -v VersionFSHierarchyMaker.class |grep "major version"
  major version: 49

(Androidコンパイラは16進表記でしたが、こちらは10進表記ですね)

Androidコンパイラがエラーを出すのは、実際に使用している/していないにかかわらず、jarの中の.classを全て解析しているからです。
コンパイル時にはまだ実際に必要かどうかは判断できないですからね。