Scala で Google App Engine

以前ScalaでGoogle App Engineが使えないかと思って,試してみた.そのときには,サーブレットは普通に動くけど,JDOのエンハンサが動いてくれなくて,JDOが使えなかった.今回,ちょっといじってみたらJDOを含めて動かすことができたので書いておく.

コマンドラインでの操作

要するに,Eclipseの外でエンハンサだけ動かせばよい.それには,SDKに含まれているbuild.xmlを使うと簡単.

SDKが1.3.0だとすると,

appengine-java-sdk-1.3.0/demos/jdoexamples/build.xml 

にbuild.xmlがある.これをEclipseのプロジェクトホームディレクトリ(warとかsrcがあるディレクトリ)にコピーしてくる.で,このファイルの冒頭にある

 <property name="sdk.dir" location="../.." />

の../..の部分を編集して,自分のSDKを指すようにする.

あとは,

ant

とするだけ.簡単だ.JDOのモデルクラスを書き直すたびに実行しなければならないのがちょっと面倒だが...

Scalaで書くJDOのモデル

Scalaで書くとJDOのモデルはかなりすっきりする.というのは,あんまり本質的な話しではなくて,Beanのgetter, setterを自動生成してくれるアノテーションがあるから.なんでJavaにはないのか,そっちのほうが不思議だが.

import java.util.Date
import javax.jdo.annotations.IdGeneratorStrategy
import javax.jdo.annotations.IdentityType
import javax.jdo.annotations.PersistenceCapable
import javax.jdo.annotations.Persistent
import javax.jdo.annotations.PrimaryKey
import com.google.appengine.api.users.User
import scala.reflect.BeanProperty 

@PersistenceCapable{val identityType = IdentityType.APPLICATION}
class  Memo {
    @PrimaryKey
    @Persistent{val valueStrategy = IdGeneratorStrategy.IDENTITY}
    @BeanProperty  
    private var id: java.lang.Long = null

    @Persistent @BeanProperty private var author: User = null
    @Persistent @BeanProperty private var content: String = null
    @Persistent @BeanProperty private var date:    Date = null

    def this(author: User, content: String, date: Date) {
      this()
      this.author = author
      this.content = content
      this.date = date
    }
}

PMFはclassではなくobjectで書いてやる.いわゆるシングルトン.

import javax.jdo.JDOHelper
import javax.jdo.PersistenceManagerFactory

object PMF {
  var pmfInstance: PersistenceManagerFactory = 
        JDOHelper.getPersistenceManagerFactory("transactions-optional")
  def get(): PersistenceManagerFactory = pmfInstance
}

所感

App Engine上でJRubyを使ってRuby on Railsなどを動かしたりする話しもあるようだが,かなり大規模なクラスロードになるためスピンアップ時間がバカにならないと聞く.

Scalaの場合は,手元でclassファイルになっているので,App Engineのスピンアップ時間があまりかからない,んじゃないだろうか.どうだろう?