Scala/LiftでSlim3

お題

GAEアプリをScalaで書きたくてですね。
しかも、私としてはどうしてもEclipse上でやりたいんです。
そしてEclipse上で動くなら折角なんでSlim3を使いたいな、と。
Scala/Liftの知識がまだまだ足りないせいで随分といろんなところでハマってしまいましたが、やっと一通り動きました。
現状で最適な構成になっているとは思いませんが、一応一通り動いたところで記録。

やりたいことは、

  • GAE上でScalaでアプリを書きたい
  • そしてLiftのViewを使いたい。(JSPとか使いたくない)
  • 但し、DataStore周りはmapperとか使えないし、Slim3を使いたい
  • EclipseGoogle Plugin上で開発したい
  • Scala IDE for Eclipseが、バージョン2.8になってからわりとまともに動く(っぽい)ので、それも使いたい

Google App Engine/JavaSlim3もそもそも基本的にはEclipse上での開発が想定されているので、やはりEclipse上で開発を進めたいですよね。特に、Slim3の「テストデータを自動的にお掃除してくれる」機能が使えたら超ハッピー!です。

しかもタイミング的に、欲張ってScala 2.8/Lift 2.0という構成にしてみました。
(それもあっていろいろとハマっちゃいました)

まずはLiftプロジェクトを作成

まずは、コンソール上からMaven Pluginを使ってLiftのプロジェクトを作ります。

mvn archetype:generate -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-blank -DarchetypeVersion=2.0-scala280-SNAPSHOT -DremoteRepositories=http://scala-tools.org/repo-snapshots -DgroupId=jp.co.prudence.enquetedemo -DartifactId=enquetedemo

そして、出来上がったプロジェクトツリーをeclipseプロジェクトとして構成します。

cd enquetedemo
mvn eclipse:eclipse

eclipseには、Scala IDE for Eclipseをインストールしておきます。
(アップデートサイト:http://download.scala-ide.org/update-current
今回用いた環境は、Eclipse 3.5 (galileo) のMac版(64bit)です。ちなみにMacSnow Leopardです。
また、Eclipseは起動時のヒープメモリを増やしておきましょう。(Eclipse.appを右クリックして「パッケージの内容を表示」、Contents/MacOS/eclipse.iniを開いて -Xms128m -Xmx768m とかに変更します)

Eclipseを起動して、ワークスペースに先程作ったプロジェクトをインポートします。
するとプロジェクトにビルドエラーの赤い×がついていると思いますが、このくらいで怯んじゃいけません。

EclipseClasspath Variableに「M2_REPO」を定義し、Maven 2のリポジトリを指定します。(環境設定⇒Java/Build Path/Classpath Variables⇒new)通常は「~/.m2/repository」だと思います。

この時点で、とりあえずビルドエラーは消えると思います!


さて、それはそれとして。

別途、Slim3プロジェクトを作成

先述したように、Google App Engine/JavaSlim3Eclipse上での開発が想定されています。ので、Eclipse上での開発を行うには、まずはSlim3のプロジェクトを用意して、そこに上記のLiftプロジェクトを載せるのが自然ですよね。

なので、別途Slim3のプロジェクトを作ります。ここは、@shin1ogawaさんが作ってくれたGoogle グループを使ってやってみます。

mvn archetype:generate -DarchetypeCatalog=http://slim3.googlecode.com/svn/branches/issue16/repository/

質問に答えて行くとプロジェクトツリーがが出来上がりますので、先程と同じようにmvn eclipse:eclipseを実行してEclipse上にインポートします。さらに、Slim3で開発を進めるのに必要な設定を、Slim3公式ページの「Getting Started」にあるGetting a blank project - Slim3を参考にして進めます。

  • Java/Code Style/Organize Imports」の設定
  • Java/Editor/Content Assist/Favorites」の設定
  • 「General/Workspace/Refresh Automatically」の設定
  • Java Compiler/Annotation Processing」の設定⇒「Generated Source Directory」には「src/main/java」を指定します。警告は出ますが知りません。「Factory Path」の設定はどうやら@shin1ogawaさんがやってくれているみたいです。

(web.xmlSlim3.RootPackageの設定は後からやります)
ここまで設定すると、Annotation Processingが働いてSlim3ModelMeta.javaが自動的に生成されますね。

ということで、マージ作業に入ります。

LiftプロジェクトをSlim3プロジェクトにマージ

基本的な方針は以下のようになります。

  • 今回Slim3で使おうと思っているのはデータストアと、あとできればテスト環境くらいです。ですので、Slim3のControllerは使いません。また、Serviceに該当する部分はScalaで記述したいです。
  • Liftプロジェクトのツリー構成とGAEプロジェクトのツリー構成が異なるため(特にwar/webappディレクトリ)どちらかに合わせる必要があります。今回、ビルド周りはLiftの構成が中心となるため、基本的にLiftプロジェクトの構成に合わせます
  1. Liftプロジェクトのsrc以下をSlim3プロジェクトのsrc以下にコピーします。(※但し、テストクラスについては後で考えます。とりあえず今回は放置)
  2. pom.xmlをマージします。基本的にはLiftプロジェクトのpom.xmlをベースに、定義を追加していきます。
  3. web.xmlをマージします。これに関しては、slim3プロジェクトのファイルに先程コピーしてきた/src/main/webapp/WEB-INF/web.xmlの内容を追加する方が速いでしょう。
  4. /war/WEB-INF/appengine-web.xml及びqueue.xmlを/src/main/webapp/WEB-INFにコピーします。appengine-web.xmlには、Google App Engine/JavaによるScala/Liftアプリケーション開発(前編) (3/6):CodeZine(コードジン)にあるように、LiftをGoogle AppEngineで動かす為の設定を追加します。
  5. プロジェクトのプロパティで、Google/Web Applicationの「WAR Directory」を「/src/main/webapp」に変更します。

⇒ていうか、通常のGoogle Pluginと同じように開発を進めるのであれば、別にmavenでビルドとかしないですよね。つまり、うまくいけば実は結局pom.xmlとかいらなくね?
⇒結論は追って検証!

Scala/Liftプロジェクトとしての構成

先程は、「mvn eclipse:eclipse」というコマンドで自動的にLiftプロジェクトとして必要な構成が行われたのですが、pom.xmlに手を入れている関係上、再度これをやってしまうと特にSlim3周りの構成が壊れてしまう可能性があります。ですので、今回は手動でプロジェクトの構成をしてみます。

まず、いよいよScala IDE for Eclipseの発動です。出来上がったプロジェクトを右クリックして、「Configure => Add Scala Nature」とやります。さらに、先程コピーしてきたScalaのソースパス(src/main/scala)をソースパスに追加してやります。
コピーしてきたScalaのファイルがパッケージ上に載り、Scalaエディタで開けるようになります。但し、まだライブラリ構成ができていないためいくつかエラーが発生すると思います。そこで、手動でライブラリを追加していきます。

M2_REPOをClasspath Variableから参照する方法もあるのですが、最終的には結局Google App Engineにアップロードしなければならないこともあり、ここは直接/src/main/webapp/WEB-INF/libに追加することにします。
追加するjarファイルは以下の通り。maven2リポジトリからコピーします。

  • commons-fileupload-1.2.1.jar
  • joda-time-1.6.jar
  • lift-actor-2.0-scala280-SNAPSHOT.jar
  • lift-common-2.0-scala280-SNAPSHOT.jar
  • lift-util-2.0-scala280-SNAPSHOT.jar
  • lift-webkit-2.0-scala280-SNAPSHOT.jar
  • log4j-1.2.14.jar
  • scala-library-2.8.0.RC6.jar
  • slf4j-api-1.5.11.jar
  • slf4j-log4j12-1.5.11.jar

逆に、Slim3ベースなので、JDO/JPA関連のライブラリは必要なくなります。
即ち、以下のjarファイルは取り除きます。

  • datanucleus-appengine-1.0.7.final.jar
  • datanucleus-core-1.1.5.jar
  • datanucleus-jpa-1.1.5.jar
  • jdo2-api-2.3-eb.jar

そして、ここまで来れば、もともとSlim3のプロジェクトにあった「war」ディレクトリは必要なくなりますね。
これはもう、「src/main/webapp」に切り替えちゃってあるので、削除しちゃって大丈夫です。

とりあえずこの状態で、プロジェクトを選択して「Run As => Web Application」を実行すると、LiftのWebアプリケーションが動作するはずです。http://localhost:8888で確認してみてください。

もう疲れたので続きは後日。