Scala 3が正式リリースされてからしばらく経っているので、以前作成したPlay FrameworkのサンプルプログラムをScala 3に移行できるか調べました。
目次
Scala 3 への移行ツール
プロジェクトが依存しているプラグインがScala 3に対応しているかどうかを確認できるプラグインがあるため、それを利用します。
https://scalacenter.github.io/scala-3-migration-guide/docs/tooling/scala-3-migrate-plugin.html
plugin.sbtに以下を追加すると、migrate-libsコマンドでScala 3 Migrate Pluginが利用できます。
addSbtPlugin("ch.epfl.scala" % "sbt-scala3-migrate" % "0.4.2") addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.5.3")
プラグインを実行すると、大まかに分けて「Scala 3では使えない(Scala 3対応のバージョンがない)」「そのままScala 3で使える」「Scala 3対応版のバージョンに上げる必要がある」の3種類のどれかが出力されます。
実際に使ってみる
実際にサンプルプロジェクトに対して使用してみます。
サンプルプロジェクトの元のplugin.sbtは以下。
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.8") addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.13.1") addSbtPlugin("org.wartremover" % "sbt-wartremover" % "2.4.16") addSbtPlugin("com.github.tototoshi" % "sbt-slick-codegen" % "1.4.0") libraryDependencies += "org.postgresql" % "postgresql" % "42.2.23"
build.sbtは以下。
name := """PlayScalaSample""" organization := "com.example" version := "1.0-SNAPSHOT" lazy val root = (project in file(".")).enablePlugins(PlayScala, CodegenPlugin) scalaVersion := "2.13.6" libraryDependencies += guice libraryDependencies += "com.google.inject" % "guice" % "5.1.0" libraryDependencies += "com.google.inject.extensions" % "guice-assistedinject" % "5.1.0" libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.1.0" % Test libraryDependencies += "org.typelevel" %% "discipline-scalatest" % "2.1.5" libraryDependencies += "com.typesafe.play" %% "play-slick" % "5.0.0" libraryDependencies += "com.typesafe.slick" %% "slick" % "3.3.3" libraryDependencies += "com.typesafe.slick" %% "slick-hikaricp" % "3.3.3" libraryDependencies += "com.typesafe.slick" %% "slick-codegen" % "3.3.3" libraryDependencies += "org.postgresql" % "postgresql" % "42.3.1" libraryDependencies += "org.typelevel" %% "cats-core" % "2.7.0" libraryDependencies += "org.typelevel" %% "cats-laws" % "2.7.0" routesGenerator := InjectedRoutesGenerator wartremoverErrors ++= Seq() wartremoverWarnings ++= Warts.unsafe ++ Warts.all wartremoverExcluded ++= (Compile / routes).value wartremoverExcluded += (Compile / baseDirectory).value / "target" Compile / sourceGenerators += slickCodegen slickCodegenDatabaseUrl := "jdbc:postgresql://localhost:5432/mydb" slickCodegenDatabaseUser := "postgres" slickCodegenDatabasePassword := "postgres" slickCodegenDriver := slick.jdbc.PostgresProfile slickCodegenJdbcDriver := "org.postgresql.Driver" slickCodegenOutputPackage := "entities" slickCodegenExcludedTables := Seq("schema_version")
plugin.sbtにScala 3 Migrate Pluginを追加して、migrate-libs <プロジェクトの変数>を実行すると結果が出力されます。(今回なら'migrate-libs root')
ただ、今回はこれだけだとsbtの起動時に以下のエラーが出ました。
[error] stack trace is suppressed; run 'last update' for the full output [error] stack trace is suppressed; run 'last ssExtractDependencies' for the full output [error] (update) sbt.librarymanagement.ResolveException: Error downloading org.scalameta:semanticdb-scalac_2.13.6:4.4.10
SemanticDBというライブラリのバージョンがsbtに依存しているらしく、使用しているScalaのバージョンのアーティファクトが存在しないバージョンを参照しようとしているみたいです。 SemanticDBのバージョンをbuild.sbtで指定できるので、以下を追加します。
semanticdbVersion := "4.4.33"
プラグインの出力結果は以下のとおりでした。
[info] com.typesafe.slick:slick:3.3.3 -> X : Contains Macros and is not yet published for 3.0.0 [info] org.wartremover:wartremover:2.4.16:plugin->default(compile) -> X : Scala 2 compiler plugins are not supported in scala 3.0.0. You need to find an alternative [info] org.postgresql:postgresql:42.3.1 -> Valid [info] com.google.inject.extensions:guice-assistedinject:5.1.0 -> Valid [info] com.google.inject:guice:5.1.0 -> Valid [info] com.typesafe.play:twirl-api:1.5.1 -> "com.typesafe.play" % "twirl-api_2.13" % "1.5.1" [info] com.typesafe.play:play-docs:2.8.8:docs -> "com.typesafe.play" % "play-docs_2.13" % "2.8.8" % "docs" [info] com.typesafe.play:play-logback:2.8.8 -> "com.typesafe.play" % "play-logback_2.13" % "2.8.8" [info] org.typelevel:cats-laws:2.7.0 -> "org.typelevel" % "cats-laws_2.13" % "2.7.0" [info] com.typesafe.play:play-slick:5.0.0 -> "com.typesafe.play" % "play-slick_2.13" % "5.0.0" [info] com.typesafe.play:play-guice:2.8.8 -> "com.typesafe.play" % "play-guice_2.13" % "2.8.8" [info] com.typesafe.play:play-test:2.8.8:test -> "com.typesafe.play" % "play-test_2.13" % "2.8.8" % "test" [info] org.scalatestplus.play:scalatestplus-play:5.1.0:test -> "org.scalatestplus.play" % "scalatestplus-play_2.13" % "5.1.0" % "test" [info] org.typelevel:discipline-scalatest:2.1.5 -> "org.typelevel" % "discipline-scalatest_2.13" % "2.1.5" [info] com.typesafe.slick:slick-hikaricp:3.3.3 -> "com.typesafe.slick" % "slick-hikaricp_2.13" % "3.3.3" [info] com.typesafe.slick:slick-codegen:3.3.3 -> "com.typesafe.slick" % "slick-codegen_2.13" % "3.3.3" [info] org.typelevel:cats-core:2.7.0 -> "org.typelevel" % "cats-core_2.13" % "2.7.0" [info] com.typesafe.play:filters-helpers:2.8.8 -> "com.typesafe.play" % "filters-helpers_2.13" % "2.8.8" [info] com.typesafe.play:play-server:2.8.8 -> "com.typesafe.play" % "play-server_2.13" % "2.8.8" [info] com.typesafe.play:play-akka-http-server:2.8.8 -> "com.typesafe.play" % "play-akka-http-server_2.13" % "2.8.8"
Slick(DBライブラリ)はScala 2のマクロを使用しているため、Scala 3では使用できないようです。(Scala 2とScala 3ではマクロの互換性がないらしい)
また、WartRemoverはScala 2用のプラグインなので使用できません。
その他は、そのまま使えるか、もしくは2.13用のアーティファクトをScala 3でも使用できるようです。
おわり
SlickがScala 3で使えないとのことなので、しばらくはまだ移行できなさそうです。
SlickのScala 3サポート自体は、着々と進められているようでした。
https://github.com/slick/slick/pull/2187
参考文献
New in Scala 3 | Scala Documentation
https://docs.scala-lang.org/ja/scala3/new-in-scala3.html
Scala 3への道
https://www.infoq.com/jp/news/2021/05/scala3/
Scala 3 Migrate Plugin · Scala 3 Migration guide
https://scalacenter.github.io/scala-3-migration-guide/docs/tooling/scala-3-migrate-plugin.html
業務アプリケーションのScala 3アップデートを試してみた - FLINTERS Engineer's Blog
https://labs.septeni.co.jp/entry/2021/07/05/110000
Error downloading org.scalameta:semanticdb-scalac_2.13.8:4.4.28 · Issue #1560 · scalacenter/scalafix · GitHub
https://github.com/scalacenter/scalafix/issues/1560