2009年6月19日金曜日

GAE/JのDevAppServerMainを起動するmaven pluginを作った

2009-07-27追記

SDKのバージョンに合わせてバージョンが変わってますので更新のエントリも参照する事!

今までmaven archetype pluginをいくつか作って来たけど、どれも「Eclipseが前提」となっていて、せっかくarchetype:generateでプロジェクトが作れるし、単体テストもできるのに結局Google Plugin for Eclipseappengine-java-sdkも必要なんだよな〜、mavenを使った開発っぽくないよな〜、というカンジがあった。

mavenを使うんだから、sdkなんていちいち落としてくるなんておかしいよ、プラグインが勝手に解決しろや〜、て思うもんね。そこで、以下のようなMavenプラグインを作った。

  • com.google.appengine.tools.KickStartを使ってcom.google.appengine.tools.development.DevAppServerMainを起動する。
  • 試験のためのプラットフォームとしてSDK本体が必要になるが、公式のダウンロードサイトからダウンロードしてくる事が可能。ダウンロードしてきた場合は例えばtarget/sdkなどに展開し、そこをSDKのルートとして使用する。

つまり、jettyプラグインとかcargoプラグインみたいにselenium等でintegration-testを自動で行ったり、さくっとアプリを起動して動作確認するためのモジュールです。

使い方

pluginRepositoryとしてhttp://gae-j-samples.sourceforge.jp/maven/repositoryを追加し、com.shin1ogawa:gae-maven2-plugin:1.2.1-SNAPSHOT:start(つまり、groupId=com.shin1ogawa, artifactId=gae-maven2-plugin, version=1.2.1-SNAPSHOT, goal=start)を実行してください。stopゴールはパラメータは無しで、startゴールのパラメータは以下の通り。

address(localhost),disableUpdateCheck(true),port(8080),server
これらはDevAppServerMainにそのまま渡すパラメタです。それぞれカッコ内の値がデフォルトの値です。server、って何に使うんだっけ…?
javaHome
javaを起動するためのホームディレクトリです。省略した場合はSystem.getProperty("java.home")の値を使用します。
warDirectory
SDKが使用するアプリケーションのディレクトリです。デフォルトの値はwarが設定されています。この直下にWEB-INFが配置されている必要があります。
sdkRootDirectory
appengine-java-sdkがインストールされたディレクトリを指定しますが、sdkUnZipDirectoryが指定されているとそっちを優先します。
sdkZipFile
SDKのZipファイルの場所。デフォルトの値はhttp://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.1.zipが設定されています。
sdkUnZipDirectory
SDKのZipファイルを展開するディレクトリ。
sdkSaveAs
もしsdkZipFileパラメータがhttpだったりしてローカルじゃない場合に、保存するファイル名。デフォルトの値はappengine-java-sdk-1.2.1.zipが設定されています。sdkUnZipDirectoryで指定したディレクトリ配下に作成されます。もし既に存在していた場合は、リモートからダウンロードしません。
wait
DevAppServerMainを起動した状態で、そのプロセスが終了するのを待ちます。mavenでintegration-testを実行する際はpre-integration-testフェーズでfalseを指定してstartゴールを実行し、post-integration-testフェーズでstopゴールを実行して停止する必要があります。ちなみに、falseで起動してしまうと、プロセスがふたつ(KickStartと、そこから起動されたDevAppServerMain)起動されて、maven実行後にもこのふたつは止まらずに残ってしまいます。この場合は手動でkillする必要があります。

とりあえず細かい事は気にせず、以下の例を見るのが手っ取り早いです。一度でも使用するとローカルリポジトリに入ってくるので、$ mvn help:describe -Dplugin=com.shin1ogawa:gae-maven2-plugin:1.2.1-SNAPSHOT -Ddetailすると説明が表示されるはずです。

例えば、以下のようにpom.xmlintegration-test用のprofileを定義して、$ mvn -P integration-test installのようなカンジでprofileを指定しつつintegration-testフェーズが実行されるようなゴールを実行する。すると以下のように動作する。

  1. 通常のsurefire-testはskipされる。
  2. で、integration-testフェーズの直前にgae-maven2-plugin:startが実行される。
    1. 公式サイトからSDKがダウンロードされる
    2. SDKがtarget/sdkに展開される
    3. そのSDKを利用してKickStart経由でDevAppServerMainを起動する
  3. integration-testフェーズでは**/servlet/*Test.javaにマッチするテストケースが実行される。
  4. integration-testが終了すると、gae-maven2-plugin:stopが実行され、DevAppServerMainも終了する。
ちなみに、ゴールにintegration-testを指定すると、post-integration-testフェーズが実行されない。この挙動は初めて知った!!モチロン、stopゴールも実行されない為、KickStart,DevAppServerMainのふたつのプロセスが残ってしまう。
<profile>
<id>integration-test</id>
<build>
<plugins>
<plugin>
<groupId>com.shin1ogawa</groupId>
<artifactId>gae-maven2-plugin</artifactId>
<version>1.2.1-SNAPSHOT</version>
<configuration>
<sdkUnZipDirectory>target/sdk/</sdkUnZipDirectory>
<sdkSaveAs>appengine-java-sdk-1.2.1.zip</sdkSaveAs>
<wait>true</wait>
</configuration>
<executions>
<execution>
<id>start container</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<wait>false</wait>
</configuration>
</execution>
<execution>
<id>stop container</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>false</skip>
<includes>
<include>**/servlet/*Test.java</include>
</includes>
<excludes>
<exclude>**/*TestEnvironment.java</exclude>
<exclude>**/Abstract*.java</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>shin1ogawa gae-j</id>
<url>http://gae-j-samples.sourceforge.jp/maven/repository</url>
</pluginRepository>
</pluginRepositories>
</profile>

また、このプラグインを動作確認する程度だけれども、WebDriverを使ったintegration-testを行うサンプルを以下のプロジェクトに追加しています。

  • http://sourceforge.jp/projects/gae-j-samples/svn/view/gae-jdo-simple-sample/?root=gae-j-samples

0 件のコメント: