Hot code replace for scala / scalatra with free JRebel

2 minute read

One of the (many) advantages of working with the Play framework is that you can start the server and have your changes automatically reloaded. This makes developing much easier and much less frustating. Recently I’ve started experimenting with scalatra as a lightweight framework for creating REST APIs. Even though there is some standard rudimentary support through sbt:


$ sbt
> container:start
> ~ ;copy-resources;aux-compile

This doesn’t really work that great. Sometimes scala / jetty / scalatra stops responding, I get out-of-memory errors and the code changes aren’t instantanious. When looking around for solutions I ran across JRebel. I knew it existed for Java, but they also have support for Scala. Better yet, zeroturnaround, offers a free version of JRebel specifically aimed at scala developers: http://zeroturnaround.com/software/jrebel/buy/

If you follow the instructions at their site (I installed JRebel using the Eclipse marketplace) you can enable this for your scala project. I enabled this for the sbt generated Eclipse project for my previous scala/scaltra article.

I used an embedded Jetty to start scalatra and whenever I now change a scala file it’s automatically reloaded:


[2012-09-12 20:53:53] 
[2012-09-12 20:53:53] #############################################################
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  JRebel 5.0.1 (201207181843)
[2012-09-12 20:53:53]  (c) Copyright ZeroTurnaround OU, Estonia, Tartu.
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  Over the last 1 days JRebel prevented 
[2012-09-12 20:53:53]  at least 1 redeploys/restarts saving you about 0 hours.
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  This product is licensed to Jos Dirksen
[2012-09-12 20:53:53]  for use with Scala classes only 
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  License acquired through MyJRebel server.
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  You are subscribed for the plan "JRebel Scala Plan",
[2012-09-12 20:53:53]  subscription ends on 2013-09-12,
[2012-09-12 20:53:53]  current subscription token is valid until 2012-10-12.
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53]  The following plugins are disabled at the moment: 
[2012-09-12 20:53:53]  * Apache MyFaces plugin (set -Drebel.myfaces_plugin=true to enable)
[2012-09-12 20:53:53]  * Click plugin (set -Drebel.click_plugin=true to enable)
[2012-09-12 20:53:53]  * JRuby Plugin (set -Drebel.jruby_plugin=true to enable)
[2012-09-12 20:53:53]  * Jersey plugin (set -Drebel.jersey_plugin=true to enable)
[2012-09-12 20:53:53]  * Oracle ADF Core plugin (set -Drebel.adf_core_plugin=true to enable)
[2012-09-12 20:53:53]  * Oracle ADF Faces plugin (set -Drebel.adf_faces_plugin=true to enable)
[2012-09-12 20:53:53]  * RESTlet plugin (set -Drebel.restlet_plugin=true to enable)
[2012-09-12 20:53:53]  * Seam-Wicket plugin (set -Drebel.seam_wicket_plugin=true to enable)
[2012-09-12 20:53:53]  * Spring Data Plugin (set -Drebel.spring_data_plugin=true to enable)
[2012-09-12 20:53:53]  * WebObjects plugin (set -Drebel.webobjects_plugin=true to enable)
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53] #############################################################
[2012-09-12 20:53:53] 
[2012-09-12 20:53:53] JRebel: Directory '/Users/jos/Dev/scalatra/firststeps/hello-scalatra/target/scala-2.9.1/classes' will be monitored for changes.
[2012-09-12 20:53:53] JRebel: Directory '/Users/jos/Dev/scalatra/firststeps/hello-scalatra/target/scala-2.9.1/test-classes' will be monitored for changes.
[2012-09-12 20:53:53] JRebel: Directory '/Users/jos/Dev/scalatra/firststeps/hello-scalatra/bin' will be monitored for changes.
[2012-09-12 20:55:10] JRebel: Reloading class 'org.smartjava.scalatra.HelloScalatraServlet'.
[2012-09-12 20:55:16] JRebel: Reloading class 'org.smartjava.scalatra.routes.WebRoutes$class'.
[2012-09-12 20:55:16] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes$class'.
[2012-09-12 20:55:16] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:55:16] JRebel: Reloading class 'org.smartjava.scalatra.repository.BidRepository'.
[2012-09-12 20:55:16] JRebel: Reloading class 'org.smartjava.scalatra.model.Bid'.
[2012-09-12 20:55:54] JRebel: Reloading class 'org.smartjava.scalatra.repository.BidRepository'.
[2012-09-12 20:58:19] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:58:19] JRebel: Reloading class 'org.smartjava.scalatra.repository.ItemRepository'.
[2012-09-12 20:58:39] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:58:43] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:59:09] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:59:21] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.
[2012-09-12 20:59:24] JRebel: Reloading class 'org.smartjava.scalatra.routes.RESTRoutes'.

Note though, that at least for scalatra, it doesn’t do everything. When I add a new route I still need to restart the server before I can make a REST call to this route. Code changes for existing routes work normally though. I’ll have a look at the plugin mechanism for JRebel to see whether I can create a plugin for scalatra.

Updated: