Running a Remote sbt Console for a Scala or Play Application
Last updated November 29, 2023
Table of Contents
Running an sbt console in the same environment you deploy to provides an important means of debugging production errors. In this article, you’ll learn two methods of starting a remote console.
We’ll assume that you already have a working Scala or Play application running on Heroku. If you do not, then you can quickly create one by following the getting started guide. Once your application is up and running, you’re ready to try the first console technique.
Running the Default sbt Console
With no additional code, you can run sbt remotely with the Heroku CLI’s run
command like this:
$ heroku run sbt console
...
Running `sbt console` attached to terminal... up, run.3991
Picked up JAVA_TOOL_OPTIONS: -Djava.rmi.server.useCodebaseOnly=true
Getting org.scala-sbt sbt 0.13.5 ...
downloading https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt/0.13.5/jars/sbt.jar ...
[SUCCESSFUL ] org.scala-sbt#sbt;0.13.5!sbt.jar (94ms)
...
>
But the one-off dyno created by the run
command will not have access to the sbt cache, and thus it must download all of your application’s dependencies again. You can avoid this by making a small change to your configuration.
Booting with a Custom Main Class
The sbt-native-packager, which is included by default in all Play 2.2.x and 2.3.x applications, allows you to start your application with a custom main class. First, make sure your application is using at least version 0.7.6 of the sbt-native-packager by adding the following line to your project/plugins.sbt
file (note that this will cause a conflict if you are already using the sbt-start-script
plugin, which is included by default with Play 2.1.x and 2.0.x applications).
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.6")
Then add the Scala compiler as a dependency by adding this line to your build.sbt
:
libraryDependencies <+= scalaVersion("org.scala-lang" % "scala-compiler" % _ )
Now, compile and stage your application by running this command:
$ sbt compile stage
After the sbt process has completed, you can start a local console by running the following command and replacing “<your-app>” with the value of the name
setting in your build.sbt
:
$ target/universal/stage/bin/<your-app> -main scala.tools.nsc.MainGenericRunner -usejavacp
Failed to created JLineReader: java.lang.NoClassDefFoundError: jline/console/completer/Completer
Falling back to SimpleReader.
Welcome to Scala version 2.11.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val i = 7
i: Int = 7
scala> i*i
res0: Int = 49
scala>
Press Ctrl+C
to exit.
Now put that command in your Procfile
so it can be run remotely. If you don’t already have a Procfile
in your app, create one in the root directory. Then add the following code to it (replacing “<your-app>” on both lines):
web: target/universal/stage/bin/<your-app> -Dhttp.port=${PORT}
console: target/universal/stage/bin/<your-app> -main scala.tools.nsc.MainGenericRunner -usejavacp
Next, commit all of your changes and push them to Heroku like so:
$ git add build.sbt project/plugins.sbt Procfile
$ git commit -m "added custom main class runner"
$ git push heroku master
After the deployment has completed, you can start a Scala console by executing the console
target from the Procfile like so:
$ heroku run console
Running `console` attached to terminal... up, run.2581
Picked up JAVA_TOOL_OPTIONS: -Djava.rmi.server.useCodebaseOnly=true
Failed to created JLineReader: java.lang.NoClassDefFoundError: jline/console/completer/Completer
Falling back to SimpleReader.
Welcome to Scala version 2.11.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_20-slim).
Type in expressions to have them evaluated.
Type :help for more information.
scala>
Press Ctrl+C
to exit again.
For more information on using the Scala console, see the Scala REPL documentation. For more information on using the sbt-native-packager plugin to execute custom main classes, see the sbt documentation site.