sbt-revolver is a plugin for SBT enabling a super-fast development turnaround for your Scala applications.
It sports the following features:
- Starting and stopping your application in the background of your interactive SBT shell (in a forked JVM)
- Triggered restart: automatically restart your application as soon as some of its sources have been changed
- Hot reloading: automatically reload the respective classes into your running application as soon as some of its sources have been changed, no restart necessary (requires JRebel, which is free for Scala development)
sbt-revolver requires SBT 0.11.1 or greater.
Add the following dependency to your
project/*.sbt file (e.g.
resolvers += "spray repo" at "http://repo.spray.cc" // not needed for sbt >= 0.12 addSbtPlugin("cc.spray" % "sbt-revolver" % "0.6.1")
and this to your
If you use SBTs full-configuration you need to
and then add the
Revolver.settings to the (sub-)project containing the
In order to enable hot reloading you need get a licensed JRebel JAR onto your system. You can do this with these simple steps:
- Go to this page and apply for a free "JRebel for Scala" license (in the "Get JRebel for free" box on the right).
- Wait for the email from ZeroTurnaround containing your personal
- Create a
~/.jrebeldirectory and copy the
jrebel.licfile from the email into this directory.
- Download the JRebel Generic JAR Installer from this page and run it.
When asked for the license let the installer check your
~/.jrebeldirectory. Remember which path the JRebel JAR was installed to.
Once you have JRebel installed you need to let sbt-revolver know where to find the
jrebel.jar. You can do this
either via the
Revolver.jRebelJar setting directly in your SBT config or via a shell environment variable with the
JREBEL_PATH (which is the recommended way, since it doesn't pollute your SBT config with system-specific settings).
For example, on OSX you would add the following line to your shell startup script:
sbt-revolver defines three new commands (SBT tasks) in its own
re-start <args> --- <jvmArgs>starts your application in a forked JVM. The optionally specified (JVM) arguments are appended to the ones configured via the
java-options(for re-start)setting (see the "Configuration" section below). If the application is already running it is first stopped before being restarted.
re-stopstops application. This is done by simply killing the forked JVM. If your application needs to run clean-up logic this should be tied in via a Shutdown Hook.
re-statusshows an informational message about the current running state of the application.
You can use
~re-start to go into "triggered restart" mode. Your application starts up and SBT watches for changes in
your source (or resource) files. If a change is detected SBT recompiles the required classes and sbt-revolver
automatically restarts your application.
When you press <ENTER> SBT leaves "triggered restart" and returns to the normal prompt keeping your application running.
When you have JRebel installed and configured as described in the "Installation" section above sbt-revolver supports hot reloading:
- Start your application with
- Enter "triggered compilation" with
~products. SBT watches for changes in your source (and resource) files. If a change is detected SBT recompiles the required classes and JRebel loads these classes right into your running application. Since your application is not restarted the time required to bring changes online is minimal (see the "Understanding JRebel" section below for more details). When you press <ENTER> SBT leaves triggered compilation and returns to the normal prompt keeping your application running.
- If you changed your application in a way that requires a full restart (see below) press <ENTER> to leave
triggered compilation and
- Of course you always stop the application with
JRebel is a JVM
-javaagent plugin that extends the root classloaders with the ability to manage reloaded classes.
When a change to a class file is detected on disk JRebel loads the changed class into your running application.
This is great for quickly bringing code changes live but also comes with some restriction that you should understand in
order to be able to use JRebel and sbt-revolver effectively.
When JRebel reloads a class
Foo all the code of
Foo is updated to the new version. However, all instances of
that already exist at the time of class reloading will remain alive in the JVMs heap. All fields of these objects
will also remain unchanged. After reloading all methods called on
Foo objects will be changed to their new
implementations. If the new
Foo class contains instance fields that were not present in the old
Foo these instance
fields will not be initialized for all old
Foo instances! Also, if you change the way that
Foo instances are
initialized then this change will only apply to
Foo instances created after class reloading. All old instances that
have been initialized by the old
Foo will remain unchanged.
The thing to remember when working with JRebel is that JRebel changes code, not data. All code running after class reloading will be the new code. Any code having run before class reloading will not be run again.
More information about JRebel can be found in the JRebel FAQ.
The following SBT settings defined by sbt-revolver are of potential interest:
SettingKey[Seq[String]], which lets you define arguments that sbt-revolver should pass to your application on every start. Any arguments given to the
re-starttask directly will be appended to this setting.
re-main-class(for re-start), which lets you optionally define a main class to run in
re-startindependently of the one set for running the project normally. This value defaults to the value of
compile:main-class(for run). If you don't specify a value here explicitly the same logic as for the normal run main class applies: If only one main class is found it one is chosen. Otherwise, the main-class chooser is shown to the user.
java-options(for re-start), a
SettingKey[Seq[String]], which lets you define the options to pass to the forked JVM when starting your application
SettingKey[String], which lets you override the value of the
To configure a 2 GB memory limit for your app when started with
javaOptions in Revolver.reStart += "-Xmx2g"
To set a special main class for your app when started with
mainClass in Revolver.reStart := Some("com.example.Main")
To set fixed start arguments (than you can still append to with the
Revolver.reStartArgs := Seq("-x")
sbt-revolver is licensed under APL 2.0.
Feedback and contributions to the project, no matter what kind, are always very welcome. However, patches can only be accepted from their original author. Along with any patches, please state that the patch is your original work and that you license the work to the sbt-revolver project under the project’s open source license.