ついにJava系のPaaSはGAEだけでなくHerokuも使えるようになり随分幅が広がって来ました。
データベースに様々なものが使え、技術的にロックインされないう点でHerokuには大きな魅了があります。というわけで、今回はScala2.9.1を使ってScalatraというRubyのSinatraライクなWebフレームワークをHerokuにデプロイし、Eclipseでのデバック&開発環境を作成するということをやっていきます。
なお、前回Mavenでビルドを行うということをやっていましたが、sbtとgiter8を使った方が断然開発が楽ですし、GitHubと連携して更新が速いので、個人的にはsbtをお勧めします。
環境は、
- scala 2.9.1-1
- sbt 0.11.2
- giter8 0.4.0
にて行います。全てMacOSX LionにてHomebrewのbrew installでインストールしたものの最新です(2012年3月30日現在)。
なお今回作成した最終的なソースは全て、
sifue/scalatra-heroku・GitHub
にプッシュしてありますので、途中で行き詰った方は、こちらからチェックアウトして使って下さい。
では早速、
Scalatra
以上の公式サイトを参考にScalatraをテンプレートからインストールします。
g8 scalatra/scalatra-sbt organization [com.example]: org.soichiro package [com.example.app]: sifue.scalatra name [scalatra-sbt-prototype]: scalatra servlet_name [MyScalatraServlet]: MyScalatraServlet scala_version [2.9.1]: version [0.1.0-SNAPSHOT]:
これでプロジェクト作成完了です。
まずは動作確認。
$ cd scalatra $ sbt > container:start > ~ compile
http://localhost:8080/ にアクセスして動くことを確認します。
sbtでは~ compileコマンドを起動したままにすると、ファイルの更新があるたびに自動ビルドしてくれます。MyScalatraServlet.scalaの表示内容などを変更して、試して見ると良いかもしれません。
次にCtrl+CでJettyを終了させて、次にEclipseへのインポートします。
開発環境はやはりscalaの開発者が力を要れているeclipseが将来有望ですので、そちらを使います。
typesafehub/sbteclipse・GitHub
以上を参考に。
project/plugins.sbtに以下を追記します。
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
そして、
$ sbt
> eclipse
以上を実行の後、Scala IDE for Eclipse2.0のインストールされたEclipse3.6.2のパッケージエクスプローラーの右クリックメニューのインポートからプロジェクトのインポートをします。
これで、無事Eclipseで開発できるようになりました。ただし、ビルドやサーバーの実行は、今のままではsbtから実行することになります。
次にherokuへのデプロイを行います。
Scalatra on Heroku
typesafehub/xsbt-start-script-plugin · GitHub
siasia/xsbt-web-plugin · GitHub
Getting Started with Scala on Heroku/Cedar
以上を参考にして実施します。ただ、ところどころ情報が古いので、Heroku本家やtypesafe本家も参照します。
なお、Herokuのアカウントの用意、gitのインストールherokuコマンドのインストールなどは済ませている前提とします。
project/build.sbtを作成して
resolvers += Classpaths.typesafeResolver addSbtPlugin("com.typesafe.startscript" % "xsbt-start-script-plugin" % "0.5.1")
を記述します。
プロジェクトフォルダ直下のbuild.sbtの先頭に
import com.typesafe.startscript.StartScriptPlugin seq(StartScriptPlugin.startScriptForClassesSettings: _*)
追記し、更に、compileの際にもjettyを利用するように、
"org.eclipse.jetty" % "jetty-webapp" % "7.6.0.v20120127" % "compile",
を追記し、最終的に以下のようにします。
import com.typesafe.startscript.StartScriptPlugin seq(StartScriptPlugin.startScriptForClassesSettings: _*) organization := "org.soichiro" name := "scalatra" version := "0.1.0-SNAPSHOT" scalaVersion := "2.9.1" seq(webSettings :_*) libraryDependencies ++= Seq( "org.scalatra" %% "scalatra" % "2.0.4", "org.scalatra" %% "scalatra-scalate" % "2.0.4", "org.scalatra" %% "scalatra-specs2" % "2.0.4" % "test", "ch.qos.logback" % "logback-classic" % "1.0.0" % "runtime", "org.eclipse.jetty" % "jetty-webapp" % "7.6.0.v20120127" % "container", "org.eclipse.jetty" % "jetty-webapp" % "7.6.0.v20120127" % "compile", "javax.servlet" % "servlet-api" % "2.5" % "provided" ) resolvers += "Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/"
次にプロジェクト直下にProcfileという名前のファイルを作成し、
web: target/start
以上を記述します。
src/main/scala/JettyLauncher.scalaを作成し、以下を記述。
サーブレット名は適宜変更してください。
import org.eclipse.jetty.server.Server import org.eclipse.jetty.servlet.{DefaultServlet, ServletContextHandler} import org.eclipse.jetty.webapp.WebAppContext import sifue.scalatra.MyScalatraServlet object JettyLauncher { def main(args: Array[String]) { val port = if(System.getenv("PORT") != null) System.getenv("PORT").toInt else 8080 val server = new Server(port) val context = new WebAppContext() context setContextPath "/" context.setResourceBase("src/main/webapp") context.addServlet(classOf[MyScalatraServlet], "/*") context.addServlet(classOf[DefaultServlet], "/") server.setHandler(context) server.start server.join } }
ここで、クリーン後、再コンパイル、ステージしてして動作テストをします。
$ sbt > clean > compile > stage > container:start > ~ compile
これで問題なく動けば、開発環境とHerokuへデプロイする準備は完了です。なお、Eclipseでブレークポイントをはってデバッグなどしたい際には、JettyLauncher.scalaを右クリックメニューからDebug As > Scala Applicationsとすれば、デバッグすることができます。
蛇足ですが、Herokuにデプロイしたくないよ、自前のJettyやTomcatサーバーにデプロイしたいよ、という方は、
Production Deployment
以上を参照下さい。あっさりwarファイルが作れます。
話を戻して、Herokuにデプロイするため、次にローカルのgitへのコミットの準備を行います。プロジェクト直下の.gitignoreファイルを作成して、
target project/boot project/target project/plugins/target
以上を追記します。これでビルドされたものはコミットされずにすみます。
そして、実際のコミットを行います。
$ git init $ git add . $ git commit -m "init"
これで完了です。このコミットを行わないとherokuにpushすることができません。
最後にherokuにログインをして、アプリの作成、そしてデプロイを実行します。
$ heroku login $ heroku create --stack cedar Creating strong-winter-3291... done, stack is cedar http://strong-winter-3291.herokuapp.com/ | [email protected]:strong-winter-3291.git Git remote heroku added $ git push heroku master
無事、デプロイに成功したようなら、
http://strong-winter-3291.herokuapp.com/
にアクセスしてみましょう。(なおこのアプリは後に消去する可能性があります。)
無事Hello World!が表示されたら、これでHeroku上のScalatraの完成でした。
まさかScalaがHeroku上で動かせる時代がくるなんて嬉しい限りですね。
以上、お疲れ様でした。