JDK7でAndroidアプリをリリースビルドする方法

AndroidアプリはJava/JDKを使ってビルドしますが、少し前までJDK7ではリリースビルドできませんでした。

2013/02/05追記: 既に最新のAndroid SDK (r21で確認)ではこの記事に書いてあることをやらなくてもJDK7でビルドできるようになっています。

AndroidアプリはJava/JDKを使ってビルドしますが、少し前までJDK7ではリリースビルド(ant release)できませんでした。正確にはビルド自体はできるけど実機にインストールできないバイナリができてしまっていたのです。しかしあれから半年がたち、気がついたらリリースビルドするための条件が揃っていたのでちょっとやってみましょう。

必要なもの

まずrequirementsですが、まぁ私が試した各ソフトウェアのバージョンです。

  • Android SDK r19 (r18をDL後SDK managerでupdate)
  • Apache Ant 1.8.3 (この記事のキーポイント。1.8.2以前だと絶対にできません)

あとは適当なAndroidアプリのソースが要りますね。

手順

Android SDKの tools/ant/build.xml に次のパッチを当てましょう。

--- tools/ant/build.xml.orig  2012-05-09 08:54:03.105827000 +0900
+++ tools/ant/build.xml 2012-05-09 09:00:23.602590200 +0900
@@ -1052,6 +1052,8 @@
                         storepass="${key.store.password}"
                         alias="${key.alias}"
                         keypass="${key.alias.password}"
+                        sigalg="SHA1withRSA"
+                        digestalg="SHA1"
                         verbose="${verbose}" />

さぁ、たったこれだけで ant release できるようになりましたよ。

解説

あとはこのパッチが機能する理由を解説するだけですから、単にJDK7でリリースビルドしたいだけの人はここで読むのを止めてよいでしょう。

さてこのパッチが機能する理由を知るには、なぜJDK7でリリースビルドできなくなったか知る必要があります。それを以下に示します。

  • Androidアプリには署名が必要である
  • 署名にはいつくかの方式があるが、sigalg(署名アルゴリズム)とdigestalg(ダイジェストアルゴリズム)の2つのパラメータで選択する
    • Androidアプリの署名にはsigalgにSHA1withRSAを、digestalg=SHA1を使う
  • Androidアプリはリリースビルド時はAntの signjarタスク を使って署名する
    • signjarタスクにはsigalgとdigestalgを指定する方法がなかった(Ant 1.8.2まで)
  • AntのsignjarタスクはJDKに付属するjarsignerと同等である
  • jarsignerではsigalgとdigestalgをそれぞれ省略した場合にはデフォルト値が使われる
  • jarsignerの署名方式のデフォルト値が JDK6までJDK7以降で 変わってしまった

以上の事実の積み重ねによりJDK7ではリリースビルドできなくなっていたのです。

で、今回のポイントは太字でも示した「signjarタスク」です。本来こいつにsigalgとdigestaltを指定できないのがおかしいわけでして、やはりAntのほうでも指摘を受けて1.8.3にて追加されていました。前述のパッチではsignjarタスクにsigalgとdigestalgを利用するようにしたのです。

結論

これでAndroidアプリをJDK7でリリースビルドできるようになりました。