App EngineのアプリのビルドはEclipseプラグインを使うと簡単だが、Antを使うこともできる。
以下、Google App Engineのドキュメントに沿って説明する。コード例などはドキュメントから引用。
プロジェクトのディレクトリ構成
App Engineアプリの典型的なディレクトリ構成は次のとおり。これ以降このディレクトリ構成を前提にする。
プロジェクトルート/
src/
パッケージ/Javaソースコード
META-INF/
設定ファイルなど
war/
Web用のファイル (JSP, 画像などの静的ファイル)
WEB-INF/
アプリの設定ファイルなど
classes/
classファイル
lib/
ライブラリのJAR
ビルドファイル
build.xmlには以下の設定をする。
App EngineのSDKの場所。自分の環境に合わせて設定する。
<property name="sdk.dir" location="../appengine-java-sdk" />
Antマクロのインポート。
<import file="${sdk.dir}/config/user/ant-macros.xml" />
コンパイルのためのクラスパスの定義
コンパイルに必要なJARをクラスパスに追加する。以下の場所をクラスパスに追加する。
- プロジェクトに自分で追加したjarファイル
- App Engine SDKのJARファイル
<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="**/*.jar" />
</fileset>
<fileset dir="${sdk.dir}/lib">
<include name="shared/**/*.jar" />
</fileset>
</path>
JARのコピー
App Engine SDKのJARをwar/WEB-INF/libにコピーする。
<target name="copyjars"
description="Copies the App Engine JARs to the WAR.">
<copy
todir="war/WEB-INF/lib"
flatten="true">
<fileset dir="${sdk.dir}/lib/user">
<include name="**/*.jar" />
</fileset>
</copy>
</target>
ソースファイルのコンパイル
普通にコンパイルするだけ。
まず、コンパイルしたclassファイルを入れるディレクトリを作成。次に出力ディレクトリにリソースをコピー(Javaのソースファイルはコピーから除外)。そしてコンパイル。
<target name="compile" depends="copyjars"
description="Compiles Java source and copies other source files to the WAR.">
<mkdir dir="war/WEB-INF/classes" />
<copy todir="war/WEB-INF/classes">
<fileset dir="src">
<exclude name="**/*.java" />
</fileset>
</copy>
<javac
srcdir="src"
destdir="war/WEB-INF/classes"
classpathref="project.classpath"
debug="on" />
</target>
JDOファイルの拡張
JDOを使わないならこのプロセスは不要。
JDOを使うためにはJDOアノテーションをつけたクラスに対してコンパイル後のclassファイルに後処理が必要。
App EngineのAntマクロ<enhance_war>を使う。
<target name="datanucleusenhance" depends="compile"
description="Performs JDO enhancement on compiled data classes.">
<enhance_war war="war" />
</target>
開発用サーバの起動
開発用サーバもAntマクロで起動できる。
<target name="runserver" depends="datanucleusenhance"
description="Starts the development server.">
<dev_appserver war="war" />
</target>
より詳細な設定もできる。サーバの起動ポート、JavaVMの引数を指定する方法はドキュメントによると以下のとおりだが、このデバッグオプションを指定するとなぜか正常にJettyが起動しなかった。
<dev_appserver war="war" port="8888" >
<options>
<arg value="--jvm_flag=-Xdebug"/>
<arg value="--jvm_flag=-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9999"/>
</options>
</dev_appserver>
サーバを停止するには Ctrl + C を押すとドキュメントにはあるが、これではAndのプロセスが止まるだけでサーバのプロセスは止まっていないようなので、Windowsの場合ならタスクマネージャーでプロセスを終了させる必要がある。
App Engine へのアップロード
<appcfg>マクロを使う。これはApp Engine SDKのツールAppCfgを呼び出すためのマクロ。パラメータなど詳細はAppCfgのドキュメントを参照。
<target name="update" depends="datanucleusenhance"
description="Uploads the application to App Engine.">
<appcfg action="update" war="war" />
</target>
AppCfgタスク
アプリのアップデート以外のAppCfgは次のとおり。
datastoreのインデックスを更新する。アプリをアップデートする前にインデックスだけ更新するときに使う。
<target name="update_indexes" depends="datanucleusenhance"
description="Uploads just the datastore index configuration to App Engine.">
<appcfg action="update_indexes" war="war" />
</target>
ロールバック。アプリの更新が部分的に完了した場合に元に戻す。
<target name="rollback" depends="datanucleusenhance"
description="Rolls back an interrupted application update.">
<appcfg action="rollback" war="war" />
</target>
ログのダウンロード。
<target name="request_logs"
description="Downloads log data from App Engine for the application.">
<appcfg action="request_logs" war="war">
<options>
<arg value="--num_days=5"/>
</options>
<args>
<arg value="logs.txt"/>
</args>
</appcfg>
</target>
ターゲットの依存関係
ここまでの説明で登場したターゲットの実行順は次のようになっている。
copyjars → compile → datanucleusenhance → runserver
[省略] → datanucleusenhance → update
[省略] → datanucleusenhance → update_indexes
[省略] → datanucleusenhance → rollback
request_logs