2009年11月10日火曜日

Slim3 Datastoreに乗り換える(2)

前回は思想ばかり書いたので、今回はSlim3 Datastoreの導入手順などを書いてみようかと思います。 Mavenizeされたプロジェクト構成はまだ敷居が高いうえに、エントリがかぶりそうなのでEclipseのGoogle Pluginを使った方法を紹介していきます。

なお、導入手順としてはSlim3本家サイトのほうが楽です。どちらかというと、これまでに作成したプロジェクトをマイグレーションするひと向けになりそうです。

App Engineに対応したプロジェクトの作成

Google Plugin for Eclipse の使用という本家ページを参考しにしてEclipseプロジェクトを作成してください。 ただ、エントリを書いているタイミングではEclipse 3.5に関する情報が書いていなかったため、英語版も参考になると思います。 ちなみに、紙媒体のものでは第3章あたりを参考にするとよいかと思います。

まず最初にやること

作成したプロジェクトのコンテキストメニューから"Properties"を選択し、ダイアログの左メニューから"Builders"を選びます。

ここにEnhancerというアイテムがあるので、チェックを外してしまってください。これはJDOを利用する際にモデルクラスを拡張するプロセスで、ソースコードをコンパイルするときに自動的に実行されます。実際にJDOを使わなくてもこのBuilderがいるだけで余計な処理をするため、早めにつぶしておきます。 同様に、プロジェクト内の"src/META-INF/jdoconfig.xml"も不要になるので、削除してしまってかまいません。

Slim3のダウンロード

現在のSlim3はEarly Accessという扱いで、ビルドされた個々のライブラリとして配布されていないようです。 ということで、Downloads - slim3からSlim3用の空のプロジェクトをダウンロードしてきます。

今見たところ、"slim3-blank-EA1-SNAPSHOT-11022009.zip "というバージョンが最新だったので、それをダウンロードして展開しておきます。

ライブラリの追加

次に、Slim3関連のライブラリを先ほどダウンロードしたアーカイブから、作成したプロジェクトへとコピーしていきます。

App Engineで作成するアプリケーションは、標準のJavaサーバアプリケーションと同じ形態ですので、WEB-INF/libディレクトリの直下にライブラリを配置していきます。 WEB-INFディレクトリ自体はプロジェクトのwarディレクトリの直下にあります。

ダウンロードして展開したSlim3のアーカイブから、Slim3のライブラリである"slim3-blank/war/WEB-INF/lib/slim3-EA1-SNAPSHOT.jar"をコピーし、Eclipseプロジェクトの "war/WEB-INF/lib/"にコピーします。 コピーしたら、そのファイルのコンテキストメニューから"Build Path > Add to Build Path"を選択し、Eclipseから見えるクラスパスにも同ライブラリを追加しておきます。

だいたい上記のようになると思います。

フィルタの登録

コメントにてご指摘をいただいて追加。 また、Slim3には完了していないトランザクションをロールバックするフィルタが付属しているようです。 "org.slim3.datastore.DatastoreFilter"というクラスがそれにあたりますので、下記のようにweb.xmlを編集してフィルタを追加しておくと幸せになれそうです。

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
    <!-- ... -->

    <filter>
        <filter-name>datastoreFilter</filter-name>
        <filter-class>org.slim3.datastore.DatastoreFilter</filter-class>
    </filter>   
    <filter-mapping>
        <filter-name>datastoreFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <!-- ... -->
</web-app>

Slim3のブランクプロジェクトには他にもいくつかのフィルタが登録されていますので、Slim3 Datastoreだけでなくコントローラ部なども利用する方は、そちらも登録しておいたほうがよさそうです。

ジェネレータライブラリの追加

Slim3 Datastoreは前回紹介した通り、コンパイル時にいくつかのコードを生成します。先ほどコピーしてきたのはSlim3のランタイムライブラリだけですので、次はSlim3のジェネレータに関する設定を行います。

まず、作成したEclipseプロジェクトにlibという名前のディレクトリを作成します。他の名前でもかまいませんが、ここではlibという名前で作成したものとして話を進めます。

次に、ダウンロードして展開したSlim3のアーカイブからジェネレータライブラリの"slim3-blank/lib/slim3-gen-EA1-SNAPSHOT.jar"というファイルを、先ほど作成したEclipseプロジェクトのlibディレクトリにコピーします。

こんな感じになります。

ジェネレータの設定

ジェネレータライブラリをプロジェクト上にコピーしたら、Eclipseプロジェクトがそれを使うようにするための設定を行います。ランタイムライブラリとは違い、ビルドパスに追加しただけでは動作しないので注意が必要です。

プロジェクトのコンテキストメニューから"Properties"を選択し、ダイアログの左メニューから"Java Compiler > Annotation Processing"を選びます。このページでは"Enable project specific settings"にチェックを入れたのち、ジェネレータの出力先である"Generated source directory"の設定を"generated"などに書き換えておきます。これは、標準の出力先が".apt_generated"とドットファイルになっており、Eclipseの通常設定だと表示されないためです。

次に、ダイアログの左メニューから"Java Compiler > Annotation Processing > Factory Paths"を選びます。このページでは先ほど同様に"Enable project specific settings"にチェックを入れたのち、"Add JARs"ボタンでコピーしてきたSlim3のジェネレータライブラリを指定します。

動作確認

以上で設定は終わりですので、次のようなプログラムを書いてみることにします。

package com.example;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Model;

import com.google.appengine.api.datastore.Key;

@Model
public class Example {
    
    @Attribute(primaryKey = true)
    private Key key;

    private String message;

    public Key getKey() {
        return this.key;
    }

    public void setKey(Key key) {
        this.key = key;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

このプログラムを保存すると、プロジェクトの"generated"ディレクトリに、"com/example/ExampleMeta.java"というファイルが自動作成されます。 これは低レベルAPIのエンティティ表現を、先ほど作成したExampleクラスのオブジェクトと相互に変換するためのクラスで、エンティティのメタデータ的な振る舞いをします。

以上でSlim3の最低限の設定は終わりです。 次回はSlim3 DatastoreでApp Engineのデータストアを利用するサンプルと、Slim3 Datastoreのモデリングで私が気をつけている点などを紹介していく予定です。

2 件のコメント:

  1. Webから使うときには、DatastoreFilterをweb.xmlに登録しておいたほうが、例外が発生したときでもきちんとロールバックしてくれるので安心です。
    毎回、トランザクション周りをtry finallyで囲むのはうざったいので。
    登録しなくても、Googleのほうで自動的にFilterが登録されてロールバックしてくれるのですが、ワーニングが出ます。

    返信削除
  2. ご指摘ありがとうございます。
    移植時に漏れてしまったようで、追記しておきます。

    返信削除