Jack は Java ソースを Android dex バイトコードにコンパイルする Android ツールチェーンです。Jack を使用するために特別なことをする必要はありません。標準の makefile コマンドを使用して、ツリーやプロジェクトをコンパイルできます。Jack を使用する最後のリリースは、Android 8.1 です。
Jack について
Jack は図 1 のように動作します。
Jack ライブラリ形式
Jack は、独自の .jack
ファイル形式を使用します。このファイルには、ライブラリ用にあらかじめコンパイルされた dex コードが格納されており、高速にコンパイルできます(pre-dex)。
Jill
Jill ツールは、以下のように、既存の .jar
ライブラリを新しいライブラリ形式に変換します。
.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 変換されます。
コンパイル時に圧縮や難読化、再パッケージ化を使用する場合、ライブラリ内の 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 を有効化するをご覧ください。