2011年4月25日月曜日

Apache Antを使ってビルドする (Google App Engine)

 

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