以前、既存 Java プロジェクトで Scala を使えるようにする方法は確認したので、 Google Web Application プロジェクトを作って、 そこで Scala が使えるようにする方法で行く。
準備
まず Google App Engine の管理コンソールからこのテスト用に Application を作成。
Project Properties から Application ID を設定し Deploy して動作確認。
OK。動いている。
Google Web Application プロジェクトの Scala 化
やることは前回と同じ。Google Web Application プロジェクトをクローズして、.project ファイルと .classpath を編集する。詳しくは上述の記事を参照。
.project : buildCommand の javabuilder を scalabuilder に差し替えて、natures に scalanature を追加する。
... <buildSpec> <buildCommand> <name>org.scala-ide.sdt.core.scalabuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>org.eclipse.wst.common.project.facet.core.builder</name> <arguments> </arguments> </buildCommand> ... <natures> <nature>org.scala-ide.sdt.core.scalanature</nature> <nature>org.eclipse.jdt.core.javanature</nature> ... </natures> </projectDescription>
.classpath : classpath に SCALA_CONTAINER を追加。
<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/> <classpathentry kind="output" path="war/WEB-INF/classes"/> </classpath>
enhancerbuilder の除去
プロジェクトが Scala 化したので Java に加えて Scala ファイルを使えるようになる。
しかし、Scala クラスを追加するとビルド時に以下のようなエラーが出るようになった。
DataNucleus Enhancer (version 1.1.4) : Enhancement of classes ... org.datanucleus.exceptions.ClassNotResolvedException: Class "xawa.appengine.scalatest.Hoge" was not found in the CLASSPATH. Please check your specification and your CLASSPATH. ... at com.google.appengine.tools.enhancer.Enhance.main(Enhance.java:51)
JDO のエンハンサがエラーになる。エンハンサはコンパイルされたクラスに JDO の機能を付加するためのツール。追加した Scala クラスは特に JDO のアノテーションがついているわけではないのだがエラーになってしまうようだ。
ググっていろいろ調べたのだが、やはりエンハンサを動かなくしてしまうしかなさそう。
もちろんエンハンサを除去すると JDO は動かなくなる。
さらば JDO。こんにちは Low Level API。
.project ファイルを編集して BuildSpec から enhancerbuilder を除去する。
... <buildSpec> <!-- <buildCommand> <name>com.google.appengine.eclipse.core.enhancerbuilder</name> <arguments> </arguments> </buildCommand> --> </buildSpec> <natures> ...
scala-library を追加
このままデプロイして実行すると以下のエラーになる。
java.lang.NoClassDefFoundError: scala/ScalaObject at com.google.appengine.runtime.Request.process-698812e72e5425e1(Request.java) ...
Scala 関連の ライブラリがサーバーにアップロードされていないのが原因。
Scala IDE で標準で組み込まれるライブラリは scala-library.jar、scala-dbc.jar、scala-swing.jar の3つ。 App Engine の制約で Swing は使用できないので、scala-swing は入れるだけ無駄。 scala-dbc はJDBCのラッパーなのだが、App Engine 環境で Scala の DBC を使うことはないのでこれもいらない。
scala-library.jar だけ war に含めることにする。
war/WEB-INF/lib に、scala-library.jar をコピーしてデプロイ。
動いた。
JSP
念のため、JSPを使ってみたが問題なく動く。
テストに使ったコードは以下の通り。
AppEngineScalaTestServlet.scala: package xawa.appengine.scalatest import javax.servlet.http.HttpServlet import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse import javax.servlet.RequestDispatcher class AppEngineScalaTestServlet extends HttpServlet { override def doGet(req : HttpServletRequest , resp : HttpServletResponse) { val hoge = new Hoge; req.setAttribute("hoge", hoge); val rd = getServletContext().getRequestDispatcher( "/jsp/AppEngineScalaTest.jsp"); rd.forward(req, resp); } } class Hoge { def test() : String = "This is Scala's Hoge."; } AppEngineScalaTestServlet.jsp: <%@ page import="java.util.*" contentType="text/html; charset=utf-8" %> <jsp:useBean id="message" class="java.lang.String" scope="request"/> <%@ page import="xawa.appengine.scalatest.Hoge" %> <HTML><BODY> message: <%= ((Hoge)request.getAttribute("hoge")).test() %> </BODY> </HTML>
まとめ
まとめておこう。
- .project
- buildCommand の javabuilder を scalabuilder に差し替え
- natures に scalanature を追加
- JDO の enhancerbuilder を除去 ( JDO は使えない )
- .classpath に com.google.appengine.eclipse.core.GAE_CONTAINER を追加
- war/WEB-INF/lib に scala-library.jar をコピー。
0 件のコメント:
コメントを投稿