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)
)