Getting Play 2 with Scalate to run on heroku

After having everything in place I thought it’d be a great idea to deploy the small app in the cloud. After some research I was really excited about Heroku. In my eyes a brilliant idea and realization of PaaS.
After the decision for Heroku it took me only a couple of minutes, till I was ready to go,¬† with the quite¬† good tutorial of the heroku guys. The push worked flawlessly. But when I wanted to admire my first app in the cloud, I got an error message on the page. Shouldn’t be too easy anyway, right?
The logs told me the following:

2012-04-18T06:00:44+00:00 app[web.1]: ! @6a4hnb7bj - Internal server error, for request [GET /] ->
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.compileAndLoad(TemplateEngine.scala:834) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]:
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.compileAndLoadEntry(TemplateEngine.scala:691) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.util.IOUtil$.writeBinaryFile(IOUtil.scala:111) ~[scalate-util-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: 	at akka.actor.Actor$class.apply(Actor.scala:290) [akka-actor-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.layout.DefaultLayoutStrategy.org$fusesource$scalate$layout$DefaultLayoutStrategy$$tryLayout(DefaultLayoutStrategy.scala:77) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: [error] o.f.s.l.DefaultLayoutStrategy - Unhandled: org.fusesource.scalate.TemplateException: target/../tmp/src/app/target/../app/views/layouts/default.scaml.scala (No such file or directory)
2012-04-18T06:00:44+00:00 app[web.1]: play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[TemplateException: target/../tmp/src/app/target/../app/views/layouts/default.scaml.scala (No such file or directory)]]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.liftedTree1$1(TemplateEngine.scala:411) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: 	at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:63) [play_2.9.1-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.load(TemplateEngine.scala:475) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: 	at play.core.ActionInvoker.apply(Invoker.scala:61) [play_2.9.1-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: Caused by: java.io.FileNotFoundException: target/../tmp/src/app/target/../app/views/layouts/default.scaml.scala (No such file or directory)
2012-04-18T06:00:44+00:00 app[web.1]:
2012-04-18T06:00:44+00:00 app[web.1]: Caused by: org.fusesource.scalate.TemplateException: target/../tmp/src/app/target/../app/views/layouts/default.scaml.scala (No such file or directory)
2012-04-18T06:00:44+00:00 app[web.1]: 	at akka.actor.ActorCell.invoke(ActorCell.scala:617) [akka-actor-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: 	at java.io.FileOutputStream.(FileOutputStream.java:160) ~[na:1.6.0_20]
2012-04-18T06:00:44+00:00 app[web.1]: 	at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:82) [play_2.9.1-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.load(TemplateEngine.scala:405) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: [error] application -
2012-04-18T06:00:44+00:00 app[web.1]: 	at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:179) [akka-actor-2.0.jar:2.0]
2012-04-18T06:00:44+00:00 app[web.1]: 	at java.io.FileOutputStream.open(Native Method) ~[na:1.6.0_20]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.compileAndLoad(TemplateEngine.scala:747) ~[scalate-core-1.5.3.jar:1.5.3]
2012-04-18T06:00:44+00:00 app[web.1]: 	at java.io.FileOutputStream.(FileOutputStream.java:209) ~[na:1.6.0_20]
2012-04-18T06:00:44+00:00 app[web.1]: 	at org.fusesource.scalate.TemplateEngine.compileAndLoadEntry(TemplateEngine.scala:691) ~[scalate-core-1.5.3.jar:1.5.3]

It took me a while to find out what the problem was. The scalate integrating code contained paths like “/app/views” which worked perfectly on my machine but wasn’t on heroku. Deleting the first slash solved the problem.

While investigating the problem I thought that the problem might come from the not yet precompiled Scamls. So I enabled precompilation for Scalate. This can be done as follows:

Add the xsbt scalate generator to the plugins.sbt of your project:

libraryDependencies  "com.mojolly.scalate" %% "xsbt-scalate-generator" % (v + "-0.1.6"))

Additionally a build.sbt must be added to the home directory of the project with the following content:

import com.mojolly.scalate.ScalatePlugin._

seq(scalateSettings:_*)

scalateTemplateDirectory in Compile <<= (baseDirectory) { _ / "app/views" }

//scalateImports ++= Seq(
//  "import OAuth2Imports._",
//  "import model._"
//)
//
//scalateBindings ++= Seq(
//  Binding("flash", "scala.collection.Map[String, Any]", defaultValue = "Map.empty"),
//  Binding("session", "org.scalatra.Session"),
//  Binding("sessionOption", "Option[org.scalatra.Session]"))

The commented parts are bindings and “auto-imports” that might become handy if you need em. If you don’t use the e.g. oauth libraries, you’ll of course get compilation errors as the imports are added to the templates. I’ve left some examples in the file as a reminder that and how it is possible to use these features.

As precompilation is something you should have enabled in production anyway, I left it enabled after finding out why the app on heroku didn’t run.

Coming up

So far all entered data is “persisted” to memory. To change this I’ll use MongoDB, as this is an excellent alternative for a classic SQL.

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s