By default, the run task runs in the same JVM as sbt. Forking is
required under certain circumstances, however.
Or, you might want to fork Java processes when implementing new tasks.
By default, a forked process uses the same Java and Scala versions being
used for the build and the working directory and JVM options of the
current process. This page discusses how to enable and configure forking
for both run and test tasks. Each kind of task may be configured
separately by scoping the relevant keys as explained below.
The fork setting controls whether forking is enabled (true) or not
(false). It can be set in the run scope to only fork run commands or
in the test scope to only fork test commands.
To fork all test tasks (test, testOnly, and testQuick) and run
tasks (run, runMain, Test / run, and Test / runMain),
fork := true
To only fork Compile / run and Compile / runMain:
Compile / run / fork := true
To only fork Test / run and Test / runMain:
Test / run / fork := true
Note: run and runMain share the same configuration and cannot be configured separately.
To enable forking all test tasks only, set fork to true in the
Test scope:
Test / fork := true
See Testing for more control over how tests are assigned to JVMs and what options to pass to each group.
To change the working directory when forked, set Compile / run / baseDirectory
or Test / baseDirectory:
// sets the working directory for all `run`-like tasks
run / baseDirectory := file("/path/to/working/directory/")
// sets the working directory for `run` and `runMain` only
Compile / run / baseDirectory := file("/path/to/working/directory/")
// sets the working directory for `Test / run` and `Test / runMain` only
Test / run / baseDirectory := file("/path/to/working/directory/")
// sets the working directory for `test`, `testQuick`, and `testOnly`
Test / baseDirectory := file("/path/to/working/directory/")
To specify options to be provided to the forked JVM, set javaOptions:
run / javaOptions += "-Xmx8G"
or specify the configuration to affect only the main or test run
tasks:
Test / run / javaOptions += "-Xmx8G"
or only affect the test tasks:
Test / javaOptions += "-Xmx8G"
Select the Java installation to use by setting the javaHome directory:
javaHome := Some(file("/path/to/jre/"))
Note that if this is set globally, it also sets the Java installation
used to compile Java sources. You can restrict it to running only by
setting it in the run scope:
run / javaHome := Some(file("/path/to/jre/"))
As with the other settings, you can specify the configuration to affect
only the main or test run tasks or just the test tasks.
By default, forked output is sent to the Logger, with standard output
logged at the Info level and standard error at the Error level. This
can be configured with the outputStrategy setting, which is of type
OutputStrategy.
// send output to the build's standard output and error
outputStrategy := Some(StdoutOutput)
// send output to the provided OutputStream `someStream`
outputStrategy := Some(CustomOutput(someStream: OutputStream))
// send output to the provided Logger `log` (unbuffered)
outputStrategy := Some(LoggedOutput(log: Logger))
// send output to the provided Logger `log` after the process terminates
outputStrategy := Some(BufferedOutput(log: Logger))
As with other settings, this can be configured individually for main or
test run tasks or for test tasks.
By default, the standard input of the sbt process is not forwarded to
the forked process. To enable this, configure the connectInput
setting:
run / connectInput := true
To fork a new Java process, use the
Fork API. The values of interest are
Fork.java, Fork.javac, Fork.scala, and Fork.scalac. These are of
type Fork and provide apply and fork
methods. For example, to fork a new Java process, :
val options = ForkOptions(...)
val arguments: Seq[String] = ...
val mainClass: String = ...
val exitCode: Int = Fork.java(options, mainClass +: arguments)
ForkOptions defines the Java installation to use, the working directory, environment variables, and more. For example, :
val cwd: File = ...
val javaDir: File = ...
val options = ForkOptions(
envVars = Map("KEY" -> "value"),
workingDirectory = Some(cwd),
javaHome = Some(javaDir)
)