Jack は、Android 6.0~8.1 では、デフォルトの Android ビルド ツールチェーンです。
Jack は Java ソースを Android dex バイトコードにコンパイルする Android ツールチェーンです。Jack を使用するために特別なことをする必要はありません。標準の makefile コマンドを使用して、ツリーやプロジェクトをコンパイルできます。Jack を使用する最後のリリースは、Android 8.1 です。
Jack について
Jack は図 1 のように動作します。
図 1. Jack の概要
Jack ライブラリ形式
Jack は、独自の .jack
ファイル形式を使用します。このファイルには、ライブラリ用にあらかじめコンパイルされた dex コードが格納されており、高速にコンパイルできます(pre-dex)。
図 2. Jack のライブラリ ファイルの内容
Jill
次の図に示すように、Jill ツールは既存の .jar
ライブラリを新しいライブラリ形式に変換します。
図 3. 既存の .jar
ライブラリをインポートするワークフロー
Jack コンパイル サーバー
初めて Jack を使用すると、コンピュータ上でローカル Jack コンパイル サーバーが起動します。このサーバーは次のような特長を備えています。
- 新しいホスト JRE JVM の起動や、Jack コードのロード、Jack の初期化、コンパイルごとの JIT のウォームアップを避けられるため、本質的な高速化が可能になります。また、増分モードなど、小規模なコンパイルの場合に、コンパイル時間を大幅に短縮できます。
- 並列 Jack コンパイルの数を制御できる短期的ソリューションです。このサーバーは、並列コンパイル数を制限するため、コンピュータ(メモリやディスク)への過負荷を避けることができます。
Jack サーバーは、コンパイル処理のないアイドル時間が続くと、自動でシャットダウンします。localhost インターフェース上で 2 つの TCP ポートを使用し、外部からは利用できません。$HOME/.jack
ファイルを編集することで、すべてのパラメータ(並列コンパイル数、タイムアウト、ポート番号など)を編集できます。
$HOME/.jack ファイル
$HOME/.jack
ファイルには、Jack サーバー変数に関する以下の設定が完全な bash 構文で指定されています。
SERVER=true
は、Jack のサーバー機能を有効にします。SERVER_PORT_SERVICE=8072
は、コンパイル用のサーバー TCP ポート番号を設定します。SERVER_PORT_ADMIN=8073
は、管理用のサーバー TCP ポート番号を設定します。SERVER_COUNT=1
は、未使用です。SERVER_NB_COMPILE=4
は、並列コンパイルの最大数を設定します。SERVER_TIMEOUT=60
は、コンパイル処理のないアイドル状態になった後、サーバーが自動でシャットダウンするまで待機する秒数を設定します。SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log}
は、サーバーログを書き込むファイルを設定します。デフォルトでは、この変数は環境変数によってオーバーロードされます。JACK_VM_COMMAND=${JACK_VM_COMMAND:=java}
は、ホスト上で JVM を起動する際に使用するデフォルト コマンドを設定します。デフォルトでは、この変数は環境変数によってオーバーロードされます。
Jack コンパイルに関するトラブルシューティング
問題 | アクション |
---|---|
コンパイル中にコンピュータが応答しなくなった、あるいは、メモリ不足によるエラーで Jack コンパイルが失敗する | $HOME/.jack を編集して SERVER_NB_COMPILE を低い値に変更することで、同時 Jack コンパイルの数を減らします。 |
コンパイルに失敗し、バックグラウンド サーバーを起動できない | 最も可能性が高い原因として、コンピュータ上の TCP ポートがすでに使用されていることが考えられます。$HOME/.jack (SERVER_PORT_SERVICE 変数および SERVER_PORT_ADMIN 変数)を編集してポートを変更します。状況を打開するには、$HOME/.jack を編集して SERVER を false にすることで、Jack コンパイル サーバーを無効にします。これにより、残念ながらコンパイルが大幅に遅くなるため、負荷制御(make の -l オプション)を使用した make -j の起動が必要となる場合があります。 |
コンパイルがスタックして進まない | 状況を打開するには、jack-admin kill-server を使用して Jack バックグラウンド サーバーを強制終了します。その後、ユーザーの一時ディレクトリ(/tmp または $TMPDIR )内の jack-$USER に含まれている一時ディレクトリを削除します。 |
Jack ログを見つける
dist ターゲットを指定して make
コマンドを実行した場合、Jack ログは $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
にあります。それ以外の場合は、jack-admin server-log
を実行することで、ログを見つけることができます。Jack エラーが再現可能な場合、次の変数を設定すると、詳細なログを取得できます。
export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"
標準の makefile コマンドを使用してツリー(またはプロジェクト)をコンパイルし、標準の出力とエラーをアタッチします。詳細なビルドログを削除するには、次のコマンドを実行します。
unset ANDROID_JACK_EXTRA_ARGS
Jack に関する制限
デフォルトでは、Jack サーバーを使用できるのは 1 台のコンピュータ上の 1 人のユーザーだけに限られます。ユーザーの追加をサポートするには、ユーザーごとに異なるポート番号を選択し、それに応じて SERVER_NB_COMPILE
を調整します。また、$HOME/.jack
内で SERVER=false
を設定することで、Jack サーバーを無効にできます。現在のところ、vm-tests-tf
統合により CTS コンパイルは低速です。バイトコード操作ツール(JaCoCo など)はサポートされていません。
Jack を使用する
Jack は Java プログラミング言語 1.7 をサポートしており、以下で説明する追加機能を備えています。
pre-dex をかける
Jack ライブラリ ファイルを生成すると、ライブラリの .dex
が生成され、.jack
ライブラリ ファイル内に pre-dex として保存されます。Jack は、コンパイル時に各ライブラリの pre-dex を再利用します。ライブラリはすべて pre-dex 変換されます。
図 4. pre-dex を格納する Jack ライブラリ
コンパイル時に圧縮や難読化、再パッケージ化を使用する場合、ライブラリ内の pre-dex は再利用されません。
増分コンパイル
増分コンパイルとは、前回コンパイルした後に変更されたコンポーネント(およびその依存関係)だけを再コンパイルすることです。変更の対象が一部のコンポーネント セットだけに限られる場合、増分コンパイルは、フルコンパイルに比べて大幅な高速化が可能です。
増分コンパイルは、デフォルトでは無効になっています。また、圧縮や難読化、再パッケージ化、旧式 multidex を有効にすると、自動的に無効化されます。増分ビルドを有効にするには、増分ビルドを行うプロジェクトの Android.mk
ファイルに次の行を追加します。
LOCAL_JACK_ENABLED := incremental
圧縮と難読化
Jack は、ProGuard 構成ファイルを使用して、圧縮や難読化の有効化を行います。
一般的なオプションは次のとおりです。
@
-include
-basedirectory
-injars
-outjars
(サポートされる出力 jar は 1 つのみ)-libraryjars
-keep
-keepclassmembers
-keepclasseswithmembers
-keepnames
-keepclassmembernames
-keepclasseswithmembernames
-printseeds
圧縮には次のようなオプションがあります。
-dontshrink
難読化には次のようなオプションがあります。
-dontobfuscate
-printmapping
-applymapping
-obfuscationdictionary
-classobfuscationdictionary
-packageobfuscationdictionary
-useuniqueclassmembernames
-dontusemixedcaseclassnames
-keeppackagenames
-flattenpackagehierarchy
-repackageclasses
-keepattributes
-adaptclassstrings
以下のオプションは無視されます。
-dontoptimize
(Jack は最適化を行いません)-dontpreverify
(Jack は事前検証を行いません)-skipnonpubliclibraryclasses
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keepdirectories
-target
-forceprocessing
-printusage
-whyareyoukeeping
-optimizations
-optimizationpasses
-assumenosideeffects
-allowaccessmodification
-mergeinterfacesaggressively
-overloadaggressively
-microedition
-verbose
-dontnote
-dontwarn
-ignorewarnings
-printconfiguration
-dump
再パッケージ化
Jack は、jarjar 構成ファイルを使用して、再パッケージ化を行います。Jack は「rule」ルールタイプと互換性がありますが、「zap」ルールタイプや「keep」ルールタイプとは互換性がありません。
Multidex のサポート
Jack は組み込み式および従来の multidex をサポートしています。dex ファイルは 65K メソッドの制限があるため、65K メソッドを超えるアプリの場合、複数の dex ファイルに分割する必要があります。詳細については、64K を超えるメソッドを使用するアプリ向けに multidex を有効化するをご覧ください。