エンジニア男

勉強したことの忘備録としてつらつら書いていきます。

play framework2.0 → 2.4 へ移行

play2.0 → 2.4へ移行した時のまとめ。

 

【playのバージョンを上げる理由】
jdk1.8で動かすことが目的。
play2.1, play2.2はjdk1.8がサポート対象外。
play2.3からjdk1.8をサポート。
当初はplay2.3に上げる予定だったがビルドが通らず、play2.4に上げることにした。

 

【play framework バージョンアップガイド(公式)】

https://www.playframework.com/documentation/2.4.x/Migration21

公式ガイドを読むと、いきなりplay2.0 → play2.4へバージョンアップすることは推奨していない。
play2.0 → play2.1 → play2.2 → play2.3 → play2.4 と段階を踏んでバージョンアップすることに決める。

 

【play frameworkのビルドツール】
・sbt         → play2.5 ~ play2.8(最新) sbtでビルドする際は、build.sbtファイルを使用する。
・activator → play2.3 ~ play2.4
・play        → play1.0 ~ play2.2

※playのバージョンによってビルドツールが違うこと、sbtを使用する際はbuild.sbtを使うことが分からず時間を取られた。

 

【バージョンアップを通じて分かったこと】
・バージョンを上げる時はplugins.sbt, build.properties, Build.scala(build.sbt)の設定ファイルを編集する。
・バージョンが上がるとライブラリのパッケージが変更していることがある。※コード量が多いとここで時間が取られそう。
scalaの基礎構文
・play frameworkの基本的な実装、ディレクトリ構造

 

【最初にやったこと】
まずplay2.0をローカルで起動できるか確認した。
ローカルで↓2つをインストールすることで動かすことが出来た。
JDK1.7
play2.0.8
※play2.2より古いバージョンはzipファイルにパッケージ化されている。
公式DLページ: https://www.playframework.com/releases

 

【play2.0 → play2.1のまとめ】▽修正した設定ファイル
Build.scala → PlayProjectをplay.Project._に変更  ※ビルド定義ファイル。Mavenでいうpom.xml
plugins.sbt → playのバージョンを変更  ※ビルドで使用されるsbtプラグインを宣言するファイル
build.properties → sbtのバージョンを変更  ※使用するsbtバージョンを宣言するファイル

★ビルドした時に起きたエラー

①sbt.PlayExceptions$CompilationException: Compilation error[object db is not a member of package play.api]
オブジェクトDBはplay.apiパッケージにありませんよ。というエラー。
play2.0ではJDBCドライバがプラグインに同封されているが、play2.1ではlibraryDependenciesに追加して上げる必要がある。
↓Build.scala

// libraryDependencies = 外部ライブラリを追加する所
libraryDependencies += jdbc

 

②not found: object anorm
Anormというオブジェクトがありませんよ。というエラー。※Anorm = DBアクセスのためのライブラリ。
play2.0では、import anorm._ で使用できたが、play2.1ではlibraryDependenciesに追加して上げる必要がある。

↓Build.scala

// libraryDependenciesにanormを追加
libraryDependencies ++= Seq(jdbc,anorm)

 

③Overloaded method value [apply] cannot be applied to (play.api.mvc.Action[play.api.mvc.AnyContent])
オーバーロードしたメソッド値は適用できませんよ。というエラー。
メソッドの戻り値の型が違うことが原因。戻り値を修正することで解決。
Actionはリクエストを処理してクライアントへのレスポンスを生成する。
Action[AnyContent]はContent-Typeの内容に応じて、レスポンスボディを何として処理すべきか決定する。(text/plain, application/json ...etc)

https://www.playframework.com/documentation/ja/2.4.x/ScalaBodyParsers

↓Model.scala

// play2.0
def insert(id: Int, type: String, word: String) = Action {

// play2.1
def insert(id: Int, type: String, word: String): Action[AnyContent] = {

 

④Cannot find any HTTP Request Header here
httpリクエストヘッダーが見つかれませんよ。というエラー。
play2.0 → play2.1でJavaScriptRoutingの仕方が変更している。
テンプレートファイル内の@javascriptRouterの記述方法が変更し、テンプレートスコープにRequestHeaderを含める。
またJavaScriptRoutingを呼び出すコントローラーのActionには、implicit requestを指定してリクエストを暗黙的な引数として渡す必要がある。
https://www.playframework.com/documentation/2.1.x/ScalaJavascriptRouting

↓view.scala.html

// play2.0
@()
@javascriptRotuer("jsRoutes")(
View.getList,
View.insert
)

// play2.1
@()(implicit request: RequestHeader)
@helper.javascriptRouter("jsRoutes")(
routes.javascript.View.getList,
routes.javascript.View.insert
)

 

【play2.1 → play2.2のまとめ】▽修正した設定ファイル
plugins.sbt → playのバージョン、playのプラグインを変更
build.properties → sbtのバージョンを変更
Build.scala → キャッシュモジュールを変更
※上記の設定ファイルの修正でバージョンアップを行うことが出来た。play2.2.6 のビルドツールを使用

 

【play2.2 → play2.3のまとめ】▽修正した設定ファイル
plugins.sbt → playのバージョンを変更
build.properties → sbtのバージョンを変更
Build.scala → PlayProjectをplay.Project._に変更

↓ビルドした時に起きたエラーログ

Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
[info] Loading project definition from C:\env\eclipse-workspace\kirecle-sp-tools\kirecleSpTools\project
[error] Server access Error: Connection reset url=http://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.play/sbt-plugin/scala_2.10/sbt_0.13/2.3.10/ivys/ivy.xml
[error] Server access Error: Connection reset url=http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.play/sbt-plugin/scala_2.10/sbt_0.13/2.3.10/ivys/ivy.xml
[error] SERVER ERROR: HTTPS Required url=http://repo1.maven.org/maven2/com/typesafe/play/sbt-plugin_2.10_0.13/2.3.10/sbt-plugin-2.3.10.pom
[warn]  module not found: com.typesafe.play#sbt-plugin;2.3.10
[warn] ==== typesafe-ivy-releases: tried
[warn]   http://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.play/sbt-plugin/scala_2.10/sbt_0.13/2.3.10/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/com.typesafe.play/sbt-plugin/scala_2.10/sbt_0.13/2.3.10/ivys/ivy.xml
[warn] ==== local: tried
[warn]   C:\Users\0FRZ21038\.ivy2\local\com.typesafe.play\sbt-plugin\scala_2.10\sbt_0.13\2.3.10\ivys\ivy.xml
[warn] ==== local-preloaded-ivy: tried
[warn]   file:/C:/Users/0FRZ21038/.sbt/preloaded/com.typesafe.play/sbt-plugin/2.3.10/ivys/ivy.xml
[warn] ==== local-preloaded: tried
[warn]   file:/C:/Users/0FRZ21038/.sbt/preloaded/com/typesafe/play/sbt-plugin_2.10_0.13/2.3.10/sbt-plugin-2.3.10.pom
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/com/typesafe/play/sbt-plugin_2.10_0.13/2.3.10/sbt-plugin-2.3.10.pom
[warn] ==== Typesafe repository: tried
[warn]   https://repo.typesafe.com/typesafe/releases/com/typesafe/play/sbt-plugin_2.10_0.13/2.3.10/sbt-plugin-2.3.10.pom
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  ::          UNRESOLVED DEPENDENCIES         ::
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]  :: com.typesafe.play#sbt-plugin;2.3.10: not found
[warn]  ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn]  Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.[warn]          com.typesafe.play:sbt-plugin:2.3.10 (scalaVersion=2.10, sbtVersion=0.13)
[warn]sbt.ResolveException: unresolved dependency: com.typesafe.play#sbt-plugin;2.3.10: not found
        at sbt.IvyActions$.sbt$IvyActions$$resolve(IvyActions.scala:217)
        at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:126)
        at sbt.IvyActions$$anonfun$update$1.apply(IvyActions.scala:125)
        at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:115)
        at sbt.IvySbt$Module$$anonfun$withModule$1.apply(Ivy.scala:115)
        at sbt.IvySbt$$anonfun$withIvy$1.apply(Ivy.scala:103)
        at sbt.IvySbt.sbt$IvySbt$$action$1(Ivy.scala:48)
        at sbt.IvySbt$$anon$3.call(Ivy.scala:57)
        at xsbt.boot.Locks$GlobalLock.withChannel$1(Locks.scala:93)
        at xsbt.boot.Locks$GlobalLock.xsbt$boot$Locks$GlobalLock$$withChannelRetries$1(Locks.scala:78)
        at xsbt.boot.Locks$GlobalLock$$anonfun$withFileLock$1.apply(Locks.scala:97)
        at xsbt.boot.Using$.withResource(Using.scala:10)
        at xsbt.boot.Using$.apply(Using.scala:9)
        at xsbt.boot.Locks$GlobalLock.ignoringDeadlockAvoided(Locks.scala:58)
        at xsbt.boot.Locks$GlobalLock.withLock(Locks.scala:48)
        at xsbt.boot.Locks$.apply0(Locks.scala:31)
        at xsbt.boot.Locks$.apply(Locks.scala:28)
        at sbt.IvySbt.withDefaultLogger(Ivy.scala:57)
        at sbt.IvySbt.withIvy(Ivy.scala:98)
        at sbt.IvySbt.withIvy(Ivy.scala:94)
        at sbt.IvySbt$Module.withModule(Ivy.scala:115)
        at sbt.IvyActions$.update(IvyActions.scala:125)
        at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1223)
        at sbt.Classpaths$$anonfun$sbt$Classpaths$$work$1$1.apply(Defaults.scala:1221)
        at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$74.apply(Defaults.scala:1244)
        at sbt.Classpaths$$anonfun$doWork$1$1$$anonfun$74.apply(Defaults.scala:1242)
        at sbt.Tracked$$anonfun$lastOutput$1.apply(Tracked.scala:35)
        at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1246)
        at sbt.Classpaths$$anonfun$doWork$1$1.apply(Defaults.scala:1241)
        at sbt.Tracked$$anonfun$inputChanged$1.apply(Tracked.scala:45)
        at sbt.Classpaths$.cachedUpdate(Defaults.scala:1249)
        at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1214)
        at sbt.Classpaths$$anonfun$updateTask$1.apply(Defaults.scala:1192)
        at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)
        at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:42)
        at sbt.std.Transform$$anon$4.work(System.scala:64)
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
        at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
        at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
        at sbt.Execute.work(Execute.scala:244)
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
        at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
        at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
        at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
[error] (*:update) sbt.ResolveException: unresolved dependency: com.typesafe.play#sbt-plugin;2.3.10: not found

com.typesafe.play#sbt-plugin;2.3.10: が見つかりませんよ。というエラー。
このエラーが解決できなくて、一旦play2.4で動かせるか確認してみることにする。
play2.4に上げた後、activatorでビルドをしたら通ったので、sbtを使ってビルドしていたのが原因かもしれない。

 

【play2.3(play2.2) → play2.4のまとめ】▽修正した設定ファイル
plugins.sbt → playのバージョンを変更
build.properties → sbtのバージョンを変更
Build.scala → PlayProjectをplay.Project._に変更

★ビルドした時に起きたエラー
①object Html is not a member of package play.api.templates
HTMLオブジェクトはplay.api.templatesパッケージにありませんよ。というエラー。
play.api.templates.Htmlはplay2.3で非推奨になり、2.4で削除された。
play.api.templates.Html → play.twirl.api.Html に修正することで解決。

↓AdHit.scala

// play2.3
import play.api.templates.Html

// play2.4
import play.twirl.api.Html

 

②object templates is not a member of package play
templatesオブジェクトはplayパッケージにはありませんよ。というエラー。
play.templates.BaseScalaTemplateはplay2.3で非推奨になり、2.4で削除された。
play.templates.BaseScalaTemplate → play.twirl.api.BaseScalaTemplate に修正することで解決。

↓AdHit.scala

// play2.3
import play.templates.BaseScalaTemplate

// play 2.4
import play.twirl.api.BaseScalaTemplate

 

③not found: object anorm
Anormというオブジェクトがありませんよ。というエラー。
play2.4からanormをプロジェクトに追加する際は、"groupId", "artifactId", "revision" が必要になった。

↓Build.scala

val appDependencies = Seq(jdbc, "com.typesafe.play" %% "anorm" % "2.4.0")

 

④object twitterBootstrap is not a member of package views.html.helper
twitterBootstrapはviews.html.helperパッケージにはありませんよ。というエラー。
twitterBootstrapはplay2.3で非推奨、play2.4で削除となった。
キレクルツールではtwitterBootstrapがimportされていたが、使用されていなかったので削除で解決
https://www.playframework.com/documentation/2.3.3/Migration23#Twitter-Bootstrap
https://www.playframework.com/documentation/ja/2.4.x/ModuleDirectory#Play-Bootstrap3-(Java-and-Scala)



⑤エラーログ

play.api.Configuration$$anon$1: Configuration error[Cannot connect to database [default]]
Caused by: play.api.Configuration$$anon$1: Configuration error[Exception during pool initialization]
Caused by: com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
Caused by: java.sql.SQLException: JDBC4 Connection.isValid() method not supported, connection test query must be configured

JDBC4 Connection.isValid()メソッドはサポートされていません。接続テストクエリを設定する必要がありまよ。というエラー。
play2.4からJDBCドライバーを使う際は、接続テストクエリが必要になる。
applicatino.confに接続テストクエリを追加することで解決。
https://www.playframework.com/documentation/2.8.x/Migration24#JDBC-connection-pool
↓application.conf

db.default.hikaricp.connectionTestQuery="SELECT TRUE"

 

⑥c.z.h.p.HikariPool - Exception during keep alive check, that means the connection (oracle.jdbc.driver.T4CConnection@77eefa5f) must be dead.
[ORAエラー] ORA-00923: FROMキーワードが指定の位置にありません。
SQLのFROMの位置が違いますよ。というエラー。
⑤で追加した接続確認のためのクエリが間違っていたのが原因。ORACLEのダミーテーブルを参照するようにSQLを修正することで解決。

↓application.conf

// 誤:
db.default.hikaricp.connectionTestQuery="SELECT TRUE"

// 正:
db.default.hikaricp.connectionTestQuery="SELECT 1 FROM DUAL"