console actions provide a means for running user code in
the same virtual machine as sbt.
run also exists in a variant called
runMain that takes an
additional initial argument allowing you to specify the fully
qualified name of the main class you want to run.
share the same configuration and cannot be configured separately.
This page describes the problems with running user code in the same virtual machine as sbt, how sbt handles these problems, what types of code can use this feature, and what types of code must use a forked jvm. Skip to User Code if you just want to see when you should use a forked jvm.
User code can call
System.exit, which normally shuts down the JVM.
console actions run inside the same JVM as sbt,
this also ends the build and requires restarting sbt.
User code can also start other threads. Threads can be left running
after the main method returns. In particular, creating a GUI creates
several threads, some of which may not terminate until the JVM
terminates. The program is not completed until either
called or all non-daemon threads terminate.
During deserialization, the wrong class loader might be used for various complex reasons. This can happen in many scenarios, and running under SBT is just one of them. This is discussed for instance in issues #163 and #136. The reason is explained here.
User code is run with a custom
SecurityManager that throws a custom
System.exit is called. This exception is
caught by sbt. sbt then disposes of all top-level windows, interrupts
(not stops) all user-created threads, and handles the exit code. If the
exit code is nonzero,
console complete unsuccessfully. If
the exit code is zero, they complete normally.
sbt makes a list of all threads running before executing user code.
After the user code returns, sbt can then determine the threads created
by the user code. For each user-created thread, sbt replaces the
uncaught exception handler with a custom one that handles the custom
SecurityException thrown by calls to
System.exit and delegates to
the original handler for everything else. sbt then waits for each
created thread to exit or for
System.exit to be called. sbt handles a
System.exit as described above.
A user-created thread is one that is not in the
system thread group
and is not an
AWT implementation thread (e.g.
AWT-Windows). User-created threads include the
Given the above, when can user code be run with the
The user code cannot rely on shutdown hooks and at least one of the following situations must apply for user code to run in the same JVM:
System.exitis used to end the program and user-created threads terminate when interrupted.
The requirements on threading and shutdown hooks are required because the JVM does not actually shut down. So, shutdown hooks cannot be run and threads are not terminated unless they stop when interrupted. If these requirements are not met, code must run in a forked jvm.
The feature of allowing
System.exit and multiple threads to be used
cannot completely emulate the situation of running in a separate JVM and
is intended for development. Program execution should be checked in a
forked jvm when using multiple threads or
As of sbt 0.13.1, multiple
run instances can be managed. There can
only be one application that uses AWT at a time, however.