Google App EngineをScalaで使ってみる。

久しぶりのScalaだったので少し忘れているところもあって苦労しましたが、なんとか動かすことができました。
方法を書いておきます。

http://code.google.com/intl/ja/appengine/docs/java/gettingstarted/creating.html
http://code.google.com/intl/ja/appengine/docs/java/tools/ant.html
http://www.scala-lang.org/node/98
この三つのページなどを参考にしてやってみました。

ちなみに、JREJDK、GAEのSDKScala以外にも、antが必要です。

まずはディレクトリを作る

GaeTest/
  src/
    META-INF/
  war/
    WEB-INF/
      lib/
      classes/

こんな感じになるように、適当にディレクトリを作っておきます。

ビルド設定ファイルを書く

GaeTestディレクトリの中に、

<project>
  <property name="sdk.dir" location="/home/ユーザー名/appengine-java-sdk" />
  <property environment="env" />
  <import file="${sdk.dir}/config/user/ant-macros.xml" />
  <path id="project.classpath">
    <pathelement path="war/WEB-INF/classes" />
    <fileset dir="war/WEB-INF/lib/">
      <include name="**/*.jar" />
    </fileset>
    <fileset dir="${sdk.dir}/lib">
      <include name="shared/**/*.jar" />
    </fileset>
  </path>
  <target name="copyjars" description="Copies the App Engine JARs to the WAR.">
    <copy
      todir="war/WEB-INF/lib"
      flatten="true">
      <fileset dir="${sdk.dir}/lib/user">
        <include name="**/*.jar" />
      </fileset>
    </copy>
    <copy
      todir="war/WEB-INF/lib"
      flatten="true">
      <fileset dir="${env.SCALA_HOME}/lib">
        <include name="scala-library.jar" />
      </fileset>
    </copy>
  </target>
  <target name="compile" depends="copyjars" description="Compile program">
    <taskdef
      resource="scala/tools/ant/antlib.xml"
      classpath="tools/scala-compiler.jar">
      <classpath>
        <pathelement location="${env.SCALA_HOME}/lib/scala-compiler.jar" />
        <pathelement location="${env.SCALA_HOME}/lib/scala-library.jar" />
      </classpath>
    </taskdef>
    <mkdir dir="war/WEB-INF/classes" />
    <copy todir="war/WEB-INF/classes">
      <fileset dir="src">
        <exclude name="**/*.java" />
      </fileset>
    </copy>
    <scalac
      srcdir="src"
      destdir="war/WEB-INF/classes"
      classpathref="project.classpath" />
  </target>
  <target name="datanucleusenhance" depends="compile"
    description="Performs JDO enhancement on compiled data classes.">
    <enhance_war war="war" />
  </target>
  <target name="runserver" depends="datanucleusenhance"
    description="Starts the development server.">
    <dev_appserver war="war" />
  </target>
</project>

こんな感じのXMLファイルを、「build.xml」という名前で置いておきます。

プログラムを書く

srcディレクトリの中に「gaetest」というディレクトリを作り、
その中に「TestServlet.scala」という名前でこんなプログラムを書きました。

package gaetest

import java.io.IOException
import javax.servlet.http._

class TestServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, resp: HttpServletResponse) = {
    resp.setContentType("text/plain")
    resp.getWriter().println("Hello, Scala world!")
  }
}

設定ファイルを書く

warディレクトリの中にあるWEB-INFディレクトリの中に、二つのファイルを作ります。
まずはweb.xmlです。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
  <servlet>
    <servlet-name>gaetest</servlet-name>
    <servlet-class>gaetest.TestServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>gaetest</servlet-name>
    <url-pattern>/gaetest</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

こんな感じです。次は、appengine-web.xmlです。

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
  <application></application>
  <version>1</version>
</appengine-web-app>

こんな感じのファイルを置いておきます。

ビルドして実行

最後に、GaeTestディレクトリに戻り、
「ant compile」というコマンドを実行してビルドします。
そして、「ant runserver」というコマンドを実行すると、開発用サーバーが起動します。
ブラウザで「http://localhost:8080/gaetest」にアクセスすると、「Hello, Scala world!」と表示されます。