Play Frameworkのバージョンを 2.6から2.7に上げていてEvolutionsが動かなくなるパターンがあるので共有です。
限定的な条件なんですが、私はとてもハマったので次にハマった人のために情報を残しておこうと思います。 :sob:
TL;DR
- Play Framework 2.6以下 + HTTP Request Handlersを拡張している + Evolutionsを使っている場合にEvolutionsが実行されなくなる
- DefaultHttpRequestHandlerの書き方が変更になり2.6までのコンストラクターがDeprecatedになったのが原因
- 2.7で追加されたコンストラクタを追加するように変更する必要がある
起こったこと
- Play Framework 2.6以下 + HTTP Request Handlersを拡張している + Evolutionsを使っている場合にEvolutionsが実行されなくなる
- 正確にいうとPlay Frameworkでローカルで開発用にDEVモードで実行した時に
play_evolutions
テーブルが作られるが、 d.sql
(dには数字が入る)が実行されなくなる
原因詳細
Play2.6で DefaultHttpRequestHandler
を拡張していて、2.7に上げてビルドするとこんなwarningが出る。
19:50:51 [warn] /app/modules/CustomRequestHandler.scala:14:11: constructor DefaultHttpRequestHandler in class DefaultHttpRequestHandler is deprecated (since 2.7.0): Use the main DefaultHttpRequestHandler constructor
19:50:51 [warn] ) extends DefaultHttpRequestHandler(
www.playframework.com
www.playframework.com
抜粋して変更点をかくと
2.6
class VirtualHostRequestHandler @Inject() (errorHandler: HttpErrorHandler,
configuration: HttpConfiguration, filters: HttpFilters,
fooRouter: foo.Routes, barRouter: bar.Routes
) extends DefaultHttpRequestHandler(
fooRouter, errorHandler, configuration, filters
) {
2.7
class VirtualHostRequestHandler @Inject() (
webCommands: WebCommands,
optionalDevContext: OptionalDevContext,
errorHandler: HttpErrorHandler,
configuration: HttpConfiguration, filters: HttpFilters,
fooRouter: foo.Routes, barRouter: bar.Routes
) extends DefaultHttpRequestHandler(
webCommands, optionalDevContext, fooRouter, errorHandler, configuration, filters
) {
この時2.6のドキュメントで触れられている方のコンストラクタを使うとこんなコードになる
playframework/HttpRequestHandler.scala at master · playframework/playframework · GitHub
def this(router: Router, errorHandler: HttpErrorHandler, configuration: HttpConfiguration, filters: HttpFilters) = {
this(new DefaultWebCommands, None, router, errorHandler, configuration, filters.filters)
}
そう、この場合optionalDevContext がNoneになってしまう。
playframework/HttpRequestHandler.scala at master · playframework/playframework · GitHub
val webCommandResult: Option[Result] = optDevContext.flatMap { devContext: DevContext =>
webCommands.handleWebCommand(request, devContext.buildLink, devContext.buildLink.projectPath)
}
そう、この場合webCommandResultがNoneになってしまうのが原因でEvolutionsが起動しなくなっていました。
Evolutionsは Play FrameworkのWebCommandを使って実行されているため、影響を受けてしまったようです。
というわけで ここはdeprecatedなwarningが出ないように変更してやれば無事Evolutionsが実行されるようになります。
class VirtualHostRequestHandler @Inject() (
webCommands: WebCommands,
optionalDevContext: OptionalDevContext,
errorHandler: HttpErrorHandler,
configuration: HttpConfiguration, filters: HttpFilters,
fooRouter: foo.Routes, barRouter: bar.Routes
) extends DefaultHttpRequestHandler(
webCommands, optionalDevContext, fooRouter, errorHandler, configuration, filters
) {
気づいてしまえばすぐに直せるんですが、ちょっとわかりづらいですね。。Play Frameworkのバージョンを上げるとdeprecatedなwarningが出がちなのですが、きちんと確認した方がハマりどころをへらせそうですね。
さらに詳細
サンプル
github.com