CubbyとScalaを連携してみた

最近、TopHatenarHatenarMapsScalaに移行したいと思っているんですが、Liftはハードルが高すぎると判断して、試しにCubby上でScalaを動かしてみました。以下、その手順です。

プロジェクトの雛形を作成

まず以下のように入力して、Cubbyプロジェクトの雛形を作成します。

mvn archetype:generate -DarchetypeCatalog=http://cubby.seasar.org

pom.xmlScala用の記述を追加

作成されたpom.xmlを開いて、Scalaリポジトリロケーションを追加します。

<repositories>
  <repository>
    <id>maven.seasar.org</id>
    <name>The Seasar Foundation Maven2 Repository</name>
    <url>http://maven.seasar.org/maven2</url>
  </repository>
  <repository>
    <id>scala-tools.org</id>
    <name>Scala-Tools Maven2 Repository</name>
    <url>http://scala-tools.org/repo-releases</url>
  </repository>
</repositories>

<pluginRepositories>
  <pluginRepository>
    <id>scala-tools.org</id>
    <name>Scala-Tools Maven2 Repository</name>
    <url>http://scala-tools.org/repo-releases</url>
  </pluginRepository>
</pluginRepositories>

次に、要素内に以下を追加します。これで、Mavenのcompileフェーズで.scalaファイルがコンパイルされるようになります。

<plugin>
  <groupId>org.scala-tools</groupId>
  <artifactId>maven-scala-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

最後に、Scala用のを追加します。

<dependency>
  <groupId>org.scala-lang</groupId>
  <artifactId>scala-library</artifactId>
  <version>2.7.4</version>
</dependency>

Eclipseにプロジェクトをインポート

  1. プロジェクトの雛形をEclipseにインポートします。僕はm2eclipseやq4eを使っていないので、手動でmvn eclipse:eclipseしてからインポートしました。
  2. プロジェクトルートを右クリックしてScala Natureを追加します。
  3. EclipseScalaプラグインScalaのクラスパスを追加してくれますが、すでにpom.xmlベースのクラスパスがあるので、重複分を削除します。

Scalaでコーディング

後は、アクションやロジックを適当にScalaでコーディングしていきます。ここではとりあえず、ScalaActionというアクションを書いてみました。


package com.kaiseh.scalawebapp.action

import scala.reflect._
import org.seasar.cubby.action._

class ScalaAction extends Action {
  @RequestParameter
  @BeanProperty
  var name: String = _
  
  def hello = new Json("Hello " + name)
}

ScalaJavaフレームワークを連携させるとき、@BeanPropertyアノテーションが重要になります。

上のコードでvar宣言されたnameは、一見Javaのpublicフィールド相当に思えますが、実際にはJavaからは以下のアクセサしか見えません。

public String name(); // getter
public void name_$eq(String name); // setter

ここでnameに@BeanPropertyアノテーションを付けると、上記のgetter / setterに加えてgetName() / setName()も生成されるので、JavaBeanを使う既存のフレームワークと連携しやすくなります(この例の場合、Cubbyがリクエストパラメータをバインドしてくれる)。

テスト

WTPでサーバを起動して、上で作成したScalaActionにアクセスしてみます。

http://localhost:8080/scalawebapp/scala/hello?name=Scala

おおおおお!!表示されましたね!(JavaでHello World風)

EclipseScalaプラグインが.scalaファイルを自動コンパイルしてくれるし、HOT deployも使えるので、Javaと同じ感覚でサクサク開発できます。もちろん、Mavenでもビルドできます。

感想

想像していたよりもずっと簡単に、JavaのWebフレームワークとScalaを連携できました。EclipseScalaエディタがまだ不安定な点を除けば、非常に快適な環境だと思いました。TopHatenarなど既存のWebアプリを、これからどんどんScalaに移植していこうと思います。