2009年7月16日木曜日

#appengine for java sdk1.2.2への対応方法

14日の日本時間の午前中にGoogle App Engine BlogにてGoogle App Engine for Java 1.2.2をリリースしたという公式のアナウンスがあった。その日の夜くらいに確認すると、mvnsearchのリポジトリにも1.2.2対応のモジュールがアップロードされているのが確認できたので、動作確認を行っていた。が!!単体テスト周りが結構動かなくて苦労したw やっぱり、mavenとeclipse両方で動作させる事ができなきゃツライんで、そこを目指す人向けにメモを書いておく。

公式のアナウンスより

リリースノートのURLはhttp://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes。目玉としては、pythonのSDKにあるローカル環境でのDatastoreの確認を行う機能が搭載された事。これはありがたい。他にもdatanucleusの不具合対応の取り込みとか。あと、

Better emulate datastore transaction support in the DevAppServer.
ってのがあるので、Low-Level APIでのTransactionがそろそろサポートされたはずだと期待。Task Queue APIは入ってない。

Eclipseのプラグインは、メニューから[Help][Software Updates]で[Software Updatesand Add-ons]画面を開き、[Installed Software]からGoogle関連のモジュールを選択して[Update]すればおk。プロジェクト毎にSDKのバージョンを設定する事も出来るが、設定の[Google][App Engine]でデフォルトをどれにするか?を選択する事も出来る。ついでに書いておくと、Galileo対応のGoogle Plugin for Eclipseは来週くらいにリリースされそうなカンジだ。

sdk単体でのダウンロードURLは http://googleappengine.googlecode.com/files/appengine-java-sdk-1.2.2.zip日本語のダウンロードサイトは未だに1.2.0へのリンクがあるよぅだw

com.google.apphosting.api.ApiProxy.Environmentのインターフェースが変わっている

public void setDefaultNamespace(String s)が無くなって、Map getAttributes()ってのが増えてる。この件はappengine-java MLでも話題になっていたけど、中の人の返信があって、その内容で落ち着いたみたい。

JDOのEntityの状態が変わった

Query#execute()した直後のEntityの状態
  • 1.2.1: ObjectState.PERSISTENT_NONTRANSACTIONAL_DIRTY
  • 1.2.2: ObjectState.HOLLOW_PERSISTENT_NONTRANSACTIONAL
Transaction開始後に値を操作したEntityの状
    1.2.1: ObjectState.PERSISTENT_NONTRANSACTIONAL_DIRTY
  • 1.2.2: ObjectState.PERSISTENT_DIRTY

変わった、といぅよりは「正しくなった」という事なんでしょね。

低レベルAPIでTransactionがサポートされた

例えば、1.2.1までは次のように無理矢理transaction.rollback()してもロールバックは効かなかったが、1.2.2でよぅやく正しくロールバックされるよぅになっていた。

maven対応は…?

ちゃんとできる。が、ちょっと納得いかない点もある。まずは作業結果のリンクを貼っておく。

自分のJDOの動作確認用プロジェクトではJPAは使っていないんだけど、JPAのモジュールを含めておかないと次のようなExceptionが投げられる。

java.lang.RuntimeException: Unable to replace JPACallbackHandler.
at org.datanucleus.store.appengine.DatastorePluginRegistry.getExtensionPoint(DatastorePluginRegistry.java:66)
at org.datanucleus.plugin.PluginManager.getExtensionPoint(PluginManager.java:65)
at org.datanucleus.plugin.PluginManager.getConfigurationElementForExtension(PluginManager.java:113)
at org.datanucleus.plugin.PluginManager.getAttributeValueForExtension(PluginManager.java:230)
...

で、org.datanucleus:datanucleus-jpa:1.1.4:providedを追加する。maven的にはコレでokだけど、この状態で$ mvn eclipse:eclipseしてしまうと、eclipse側でテストを実行した時に次のようなExceptionが投げられる(根っこの原因を抜粋)。

org.datanucleus.exceptions.NucleusException: Plugin (Bundle) "org.datanucleus.jpa" is already registered. Ensure you dont have multiple JAR versions of the same plugin in the classpath. The URL "file:/dropins.ganymede/google/plugins/com.google.appengine.eclipse.sdkbundle_1.2.2.v200907131030/appengine-java-sdk-1.2.2/lib/user/orm/datanucleus-jpa-1.1.4.jar" is already registered, and you are trying to register an identical plugin located at URL "file:/Users/shin1/.m2/repository/org/datanucleus/datanucleus-jpa/1.1.4/datanucleus-jpa-1.1.4.jar."

これを回避する為に、pom.xmlのmaven-eclipse-pluginの定義で、configuration/excludes/excludeの値に org.datanucleus:datanucleus-jpaを追加してやるとおk。

mavenから実行する時のエンハンサとして使用するmaven-datanucleus-pluginのバージョンが1.1.3しか見つからなかったので1.1.3を使っていて、とりあえずそれでも問題は起こっていない。が、他のモジュールに合わせて1.1.4がリリースされるんじゃないかな。

2009-07-27追記

UnitTest中にUserServiceを使いたい場合は、TestEnvironment.javagetAuthDomain(), isLoggedIn(), getEmail()が値を返す必要があるので注意〜。

コメントを投稿