Java 9が広まってきて、しかし多少古いScalaやsbtのままやろうとしてハマっている人を見かけることが多くなってきたので、簡単にまとめておきます。
(追記) Java 9となっているところは、Java 10やJava11と置き換えても大体当てはまります。つまりJava8からJava9のclasspath関連の変更が一番重大で、逆にJava9で動けばJava10や11でも動く場合が多いので。
Java 9 で動くScala(のコンパイラやREPL)
- 2.9系以前は不可能
- 2.10系はScala 2.10.7以降なら可
- 2.11系はScala 2.11.12以降なら可
- 2.12系はScala 2.12.1以降なら可 *1
- 2.13系はマイルストーン含めて全部可
Java 9 で動くsbt
- sbt 0.12系以前は不可能(0.12系はScala 2.9系なため)
- sbt 0.13系はsbt 0.13.17-RC1以降(Scala 0.13.17はScala 2.10.7でビルドされたため。ただしそれ以前でも特殊な引数与えると動かなくもない)
- sbt 1 系は1.0.0以降全部動く(1.0.3だけバグって動かないという例外はある)
ただし、あくまで最低限動く境目のversionを記述しただけなので、Java 9関連や、それに関連しないこと含めて、一般的な話として最新安定版のほうがバグがある確率が少ないはずなので、上記と全く同じversion使うのではなく、最新安定版を使いましょう。2.12系は特に2.12.1, 2.12.2, 2.12.3 あたりの細かいversionでも、Java 9関連の細かい変更がされていたはずです(例えば、最適化のオプション有効化するとScala 2.12.1ではJava 9で動かないなど)
playframeworkなどのその他のライブラリや、sbt pluginが関連するものに関しては、上記の記述から自然に導き出せるはず・・・? playについて簡単に言うと、play 2.6はsbt 1対応済みなのでおそらくわりと普通にJava 9で動くはずだし、なんならplay 2.5や2.4も、sbt 0.13.17にしたりScala 2.11系でも最新の2.11.12にすれば動く可能性はある・・・が、Scala関係なく依存ライブラリの特有の問題で動かない可能性もあります。そこは各自頑張ってくだい。
さて、ここからもう少し詳細な豆知識(別に読まなくてもよい)
- 2.10.7と2.11.12は、最低限対応しただけで、本格的に色々やっているのはScala 2.12系以降なので、基本は2.12系以降を使ったほうが良いです。
- Scala 2.10.7 や 2.11.12 のREPLを普通にScalaコマンドから起動する場合は -nobootcp というオプションつけて起動しないとJava 9で起動不可能、というバグあったりするので気をつけてください(sbt consoleでは関係ない)
- タイトルに"コンパイラ"という文字を入れたのはわざとであり、あくまでもScalaコンパイラが動かないだけで、実行時にJava 9でもJava 8でもscala-libraryがおこなうことは大差ない(Java 8 と9の違いに影響受けるような動的な魔術はあまりない)はずなので、上記に書いたものより古いversionでもコンパイルを除いた実行だけなら動く可能性はある(未検証)
- ただし「コンパイルはJava 8の環境かつ”Java 9 未対応の古いScala”で行い、実際に動かす環境はJava 9」というパターンはあまりないと思うので、有名ライブラリ作者でもないかぎり、気にしなくて良いでしょう(このエントリ自体、初心者、中級者向けに書いてるつもりなので)
- sbt 0.13.16でJava 9で動かすのはこういうの https://twitter.com/xuwei_k/status/943847506332475392 ただし、0.13.16と0.13.17は互換あるので、わざわざこのテクニック使う必要も今となってはあまりないと思います
上記に挙げたバージョンは、なんとなくそれなりにJava 9でも動くというだけで、何から何まで完璧にJava 9対応しているわけではありません。もっと詳細に知りたい人は、以下のissueや、以下のリンクのjdk9, jdk10, jdk11というラベルが付いているissueなどから色々辿ってみてください
- https://github.com/scala/bug/labels/jdk10
- https://github.com/scala/bug/labels/jdk11
更に補足情報として、現状でのJava 10関連。2.12.6以前だとこの問題がありましたが、2.12.7で修正されました。
Scala compiler、Java 9 対応のときと全く同じパターンで、最適化のコンパイルオプションを指定すると、内部で使ってるasmが強制的にエラーになるので Java 10 で動かないhttps://t.co/3A23jhYCZ4https://t.co/wQrPrldvRf
— Kenji Yoshida (@xuwei_k) 2018年2月12日