play-scalaをscala 2.9.1でビルドする
Posted on 2011-09-23 by takezoux2この記事は2011/09/21頃に書きました。play-scalaの1.0では、scala 2.9.1 に上がるらしいので、将来的には自前でビルドする必要性はなくなっていると思われます。
現在、弊社では Play framework の導入について検討を進めています。
これまで開発してきたアプリケーションについては Scala 2.9.x 系統をメインで使用していたのですが、play-scalaのビルドはScala 2.8.1で行われているため、社内のライブラリが使用できないという問題にぶち当たりました。
そこで、Scala 2.9.x 向けに play-scalaをビルドし直そうとしたのですが、思いのほか手こずったのでその手順を書いておきます。
事前準備
- scala 2.9.1
- git
- sbt 0.10.x
- sbt 0.7.x
- ant
が必要です。事前に全てを準備しておいてください。
1. githubから依存ライブラリとplay-scalaのソースコードをcloneしてくる。
xsbt
https://github.com/harrah/xsbt
sbinary
https://github.com/DRMacIver/sbinary
sjson
https://github.com/debasishg/sjson
play-scala
https://github.com/playframework/play-scala
2. sbtの0.11ブランチ、sbinary,sjsonをビルドする
sbt
sbt 0.10.1は、Scala 2.8.1でビルドされているので、そのままでは使用できません。
0.11ブランチでは、Scala 2.9.1になっているのでそのブランチに切り替えてビルドをする必要があります。
> git checkout 0.11
> sbt_0.10.x
@ sbt console
> update
> package
sbinary
masterでビルドすればOKです。
> sbt_0.10.x
@sbt console
> update
> ++ 2.9.1 package // scala2.9.1でビルド
sjson
これもmasterでビルドすればOKです。
> sbt_0.7.x
@sbt console
> update
> package
3. play-scalaの依存ライブラリを置き換え
3.1 libフォルダ内の “*_2.8.1-0.9.10.jar”と名前の付いているjarファイルを新しくビルドしたsbtのjarファイルに置き換える。
私の環境では、sbtのビルドで、”*_2.9.1-0.11.0-RC1.jar”と名前の付いたjarファイルが作成されたので、それを全てlibフォルダ内へ入れて、古い”*_2.8.1-0.9.10.jar”のファイルを全て削除しました。
ちなみに、30 個弱のjarファイルを入れ替える必要があるので頑張ってください。
3.2 libフォルダ内のsjson,sbinaryのjarファイルを置き換える
同様に、libフォルダ内のsjson_2.8.1-0.13.jar,sbinary_2.8.1-0.4.0.jarも、先ほどビルドしたscala2.9.1のjarファイルに置き換えてください。微妙な罠として、sbinaryのjarファイルは、$sbinary/core/target/scala-2.9.1.finalフォルダの中に入っています。$sbinary/target/scala-2.9.1.final/sbinary-parent_2.9.1-0.4.0.jarのほうは違うので気をつけてください。
3.3 libフォルダ内のscala-compiler.jar,scala-library.jarをScala 2.9.1のものに置き換える
はじめに入っているものは、Scala 2.8.1のjarファイルなので、
$SCALA2_9_1_HOME/libに入っている同名のjarファイルをコピーしてきてください。
3.4 dlibフォルダのcompiler-interface-bin-0.9.10.jarを置き換える
こちらのフォルダの中のjarファイルも同様に、先程ビルドした sbt のjarファイルへ置き換えておいてください。
4. ソースコードの修正
4箇所の修正が必要です。
4.1 sbtの Scala バージョンを変更
src-compiler/ScalaCompiler.scala 32行目を変更します。
val scalaProvider = sbt.getScala("2.9.1")
4.2 SbtCompiler.inputsの引数の変更に対応
src-compiler/ScalaCompiler.scala 53行目を変更します。
val inputs = SbtCompiler.inputs(classpath, sources, output, Nil/*Seq("-verbose")*/, Seq("-g"), 1, order)(compilers, SbtLogger)
を
val inputs = SbtCompiler.inputs(classpath, sources, output, Nil/*Seq("-verbose")*/, Seq("-g"),_root_.sbt.inc.Locate.definesClass, 1, order)(compilers,SbtLogger)
に書き換えてください。
4.3 compiler-interface-srcの変更
src-compiler/ScalaCompiler.scala 203行目を変更します。
case "compiler-interface-bin_2.8.1.final" => Array(new File(libs, "../dlib/compiler-interface-bin-0.9.10.jar"))
を
case "compiler-interface-bin_2.9.1.final" => Array(new File(libs, "../dlib/compiler-interface-bin-0.11.0-RC1.jar"))
に書き換えてください。書き換えるのはScalaのバージョンと、先ほど3.4でdlibフォルダへ入れたjarファイルの名前です。
4.4 xsbti.ScalaProviderの追加されたメソッドを追加
新しく、addToComponentと、componentLocationのメソッドが追加されています。この2つのメソッドを実装します。
src-compiler/ScalaCompiler.scala 212行目あたりに、以下のコードを挿入してください。使用されてはいないようなので、適当に例外を投げておけば大丈夫そうです。
def addToComponent( componentID : String, components : Array[File]) = {
throw new Exception("Not implemented")
}
def componentLocation(id : String) = {
throw new Exception("Not implemented")
}
5. ビルド
以上で完了です。あとは
ant -Dplay.path=/path/to/your/play/framework/installation
を実行すると、libフォルダにplay-scala.jarとplay-scala-compiler.jarが作成されます。
6. おまけ
いろいろめんどくさい人は、上で説明した修正内容を適用した fork を作成したのでこちらのレポジトリをcloneしてビルドして使ってみてください。