読者です 読者をやめる 読者になる 読者になる

C Sharpens you up

http://qiita.com/yuba に移しつつあります

Play! 2.1 アプリを Play! 2.2 に移行した作業の覚え書き

Play! 2.x Play framework 2.x Java and 1.x Advent Calendar 2013

Play framework 2.x Java and 1.x Advent Calendar 2013*1の15日目(4日ぶり3回目)です。

Play! 2.1(Java)で作り始めたWebアプリなのですが、まだ作り始めたばっかりのうちに2.2系列のPlay!が出て来たので、どうせなら今のうちにと乗り換えを敢行しました(BoneCPのコネクションリーク問題が解決したバージョン0.8.0が、Play! 2.2.1でやっと標準搭載されたからというのが直接のきっかけです)。
結論から言うと乗り換えはできたのですが、設定ファイルの名前も書式も変わっているなど一本道ではなかったので覚え書きをここに。

どうやって作業したかと言いますと、2.1と2.2とでそれぞれplay newして、できあがったプロジェクトディレクトリを差分取って差分を今のプロジェクトに反映して(手動)などとやっておりました。

設定ファイル

ビルドファイル Build.scala → build.sbt

2.1まではconfディレクトリ内のBuild.scalaで依存設定をしていたのが、ルートディレクトリのbuild.sbtに変わりました。書式も変わっているので単純にコピーしただけではだめ。
また、プラグインに与えるオプションの書き方が公式ドキュメントになかったのですが、これは当てずっぽでなんとかなりました。

  • import宣言は基本的にいらなくなります。ただし、サードパーティプラグインを設定する場合は必要。
  • object ApplicationBuild extends Buildという宣言とブロックがいらなくなります。
  • appName, appVersion, appDependencies というフィールドがname:=, version:=, libraryDependency++=という宣言文に変わります。
  • プラグインの設定は、.settingsメソッドで追加していた内容をそのまま一行に書くことで追加できます。
  • 一行一行を空行で区切る必要があります。

Build.scala

import sbt._
import Keys._
import play.Project._
import com.github.play2war.plugin._

object ApplicationBuild extends Build {

  val appName         = "bems_app"
  val appVersion      = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    // Add your project dependencies here,
    "postgresql" % "postgresql" %"9.1-901.jdbc4",
    "org.apache.axis2" % "axis2-java2wsdl" % "1.6.2",
    "org.apache.axis2" % "axis2-adb" % "1.6.2",
    "com.jolbox" % "bonecp" % "0.8.0.RELEASE", // フレームワークをPlay 2.2.1以降にアップグレードしたらこの行は不要になります
    "org.projectlombok" % "lombok" % "0.11.4",
    javaCore,
    javaJdbc,
    javaEbean
  )

  val main = play.Project(appName, appVersion, appDependencies)
    .settings(Play2WarPlugin.play2WarSettings: _*)
    .settings(
    // Add your own project settings here
    Play2WarKeys.servletVersion := "3.0"
  )
}

build.sbt

import com.github.play2war.plugin._

name := "bems_app"

version := "1.0-SNAPSHOT"

libraryDependencies ++= Seq(
    "postgresql" % "postgresql" %"9.1-901.jdbc4",
    "org.apache.axis2" % "axis2-java2wsdl" % "1.6.2",
    "org.apache.axis2" % "axis2-adb" % "1.6.2",
    "org.projectlombok" % "lombok" % "0.11.4",
    cache,
    javaJdbc,
    javaEbean
)     

play.Project.playJavaSettings

Play2WarPlugin.play2WarSettings

Play2WarKeys.servletVersion := "3.0"
build.properties

正直このファイルの意味はよくわかってない。
2.1

sbt.version=0.12.2

2.2

sbt.version=0.13.0
plugins.sbt

書き換えた部分だけ。sbt-pluginの宣言が、バージョンだけでなく名前空間も変わっています。
play2warプラグインはバージョン1.2を使う必要があります(play2warがバージョン1.2でPlay! 2.2に対応したのも今回の乗り換えのきっかけの1つでした)。
2.1

addSbtPlugin("play" % "sbt-plugin" % "2.1.1")

addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.0.1")

2.2

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.1")

addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.2-beta2")

EBeanまわり

Play! 2.1はEBean 2.6.0を使っていました。2.2ではEBeanが3.2.2になっています。ひとっ飛びすぎはしないか。しかもPlay! 2.3ではEBeanやめてJPAに戻すとかで、伸び盛りのフレームワークってのはほんとに怖いですね。

使えなくなったメソッド

テストのセットアップコードにこんな感じのコードを書いていることがあったと思います。
2.1

ServerConfig config = new ServerConfig();
config.setDebugSql(true);
ddl = new DdlGenerator((SpiEbeanServer) server, new H2Platform(), config);

このコードですが、

  1. setDebugSqlメソッドがなくなりました。
  2. DdlGeneratorのコンストラクタが引数なしになり、setupメソッドであとから詳細設定するようになりました。

というわけでこうなります。
2.2

ServerConfig config = new ServerConfig();
final DdlGenerator ddlGenerator = new DdlGenerator();
ddlGenerator.setup((SpiEbeanServer) server, new H2Platform(), config);

setDebugSqlメソッドは、実際に発行されたSQL文を画面出力するかどうかという設定でして、これがなくなった場合どうなるんですかというあたりは未確認です。いまEBeanの動作はテストに含んでいないので…

@NotNullアノテーションがなくなった

@NotNullアノテーションがなくなってしまって代わりはどうすればいいのかどこにも情報が出ていないので目下探索中なのですが、どなたかご存知ありませんでしょうか。
とは言え、今回のプロジェクトではDDL生成を使っていないので@NotNullは静的解析用のマークぐらいの意味しかありません。コンパイルが通ってくれさえすれば文句はないので、最低限の労力で回避ってことでimport宣言を全文置換してJavaの同名のアノテーションだったことにしてしまいました。
2.1

import com.avaje.ebean.validation.NotNull;

2.2

import javax.validation.constraints.NotNull;

同名のクラスだからってこれでいいの? 実験してみるとですね、このJava標準のNotNullアノテーションでもDDL自動生成ではみごとにnot null制約が付加されます。
これはどうも、あれですね。「Java標準にちゃんと定義されてるクラスを自作しちゃったてへぺろ」で削除したものなんでしょう。

というわけで

ディレクトリdiffからの見よう見まねで一応移行はできました。
でもEBeanユニットテスト周りはよくわからないままえいやなところがあって、ここらへんは各自情報収集よろしくです。

*1:Advent Calendarとはクリスマスまでのカウントダウン日めくりのことで、それになぞらえて12/1から12/25まで日替わりで参加者がブログ記事を寄稿するイベントです。