Islands in the byte stream

Technical notes by a software engineer

Annotation Processor開発にJava8は使っていいのか

AndroidでJava8は使えるのか? - Islands in the byte stream は実行環境の話で、 Androidアプリ開発にJava8は使えない という話でした。今回は開発環境の話です。

短い答え

Annotation Processor*1はAndroidアプリのコードには含まれないのでJava8で開発してよい。ただし、JDKはなるべく最新*2にすべき。

長い答え

Androidアプリ開発にはいまのところJDKが必須です。JavaソースファイルをJDKの javac(1) でクラスファイルにコンパイルし、それをAndroid SDKに含まれる dx(1) でdexファイルに変換するからです。

ところで、JDK8のコンパイラはJava7以下のバージョンのJavaソースファイルを、Java7以下のバージョンと互換性のあるクラスファイルにコンパイルすることができます。 android.compileOptions で指定しているのがその指示で、つまりこの互換性のためのオプションを指定するかぎりAndroid用のコードをJDK8でビルドするのは問題ありません*3。もちろんその場合、JDK8を使ってJava7のコードを書く、ということになりますし、Java8のクラスライブラリの新機能を使うこともできません。

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

さて、Android開発においてJavaが必要なのは、アプリやライブラリのコードのほか、Annotation ProcessorとGradle Pluginがあります。これらのコードは最終的にdexに含まれないため、アプリのビルドに使えるJDKの最新Javaバージョンで開発できます*4。既に述べたようにアプリのビルドにはJDK8を使っても問題ないため、現在はJava8を使ってAnnotation Processorを開発できるということになります。もちろん、optionalやstreamなどのJava8で導入されたクラスライブラリも使えます。

そういう考えのもと、Ormaのannotation processorはJava8で開発することにしています。しかし現在のところ、Ormaが使えない、またはOrmaのコードをビルドできない、という報告のほとんどは、JDK7やJDK8の初期のバージョンをつかっているためにannotation processorが動かないないしビルドできないということが原因でした。

これはおそらく、「Androidアプリ開発にJDK8は使えない」「Androidアプリ開発でJava8は使えないため、JDKをアップデートする必要はない」という誤解が広まっているからだと思われます。たしかにアプリケーションコードに関してはその通りですが、開発プロセスではJava8が必要になることがあるし、それを認めたほうが利便性もあがります。

またサーバーサイドをJava7 / JDK7で開発している場合でも、Androidアプリ開発でJDK8を使うのは問題ありません。JDKは複数バージョンのインストールができるため、サーバーサイド開発用JDKとAndroidアプリ開発用JDKを別にしてJDKのパスを設定すればいいのです。

そういうわけで、Android開発者でもJDKはアップデートしたほうがいいでしょう*5

*1:アノテーションを処理するためのjavacのプラグイン。JSR-269で規定されている。

*2:このエントリを書いた時点だと 1.8.0_66です。

*3:JDK8の特定のリビジョンのコンパイラにバグがあり、Androidと互換性のないバイトコードを生成する可能性はあります。しかし、これはむしろ特定のJDKのリビジョンの問題なので、JDK8かどうかとは独立した問題です。

*4:バージョン7までのButterKnifeのように、ひとつのjarにランタイムクラスとannotation processorクラス両方をいれる手法もあり、その場合はAnnotation ProcessorでもJava7までしか使えません。しかしこの手法はさまざまな問題があり、ButterKnifeもバージョン8からはランタイムとプロセッサを分離しました。この手法は忘れましょう。

*5:もちろん例外もあって、最低限のメンテナンスだけするフェーズとなったAndroidアプリのビルドを、これまで試したことのないJDKでビルドするのは、これまで経験したことのないjavacのバグを踏む一定のリスクがあります。しかしそれはどんなアプリ開発でも同じことです。