Proposal: Environment variables (JAVA_OPTS, SBT_OPTS) and how to pass JVM arguments

This is a proposal for how JAVA_OPTS, SBT_OPTS, and various command line options should for for both Bash (Linux / macOS) and Windows Batch. For backward compatibility and convenience, it’s meant not to be huge departure from the way it’s already implemented.

There are mainly three ways of passing arguments to sbt launcher script:

  1. JAVA_OPTS environment variable
  2. SBT_OPTS environment variable
  3. command line arguments

.jvmopts, .sbtopts, and /etc/sbt/sbtopts are variants of the above.

JAVA_OPTS / .jvmopts

The content of JAVA_OPTS is passed in java command line without modification. This could be something like

-Dfile.encoding=UTF-8

When JAVA_OPTS is empty, it should default to -Dfile.encoding=UTF-8. Generally we should discourage the use of JAVA_OPTS and use SBT_OPTS.

SBT_OPTS / .sbtopts

The content of SBT_OPTS is passed into the same mapping and processing as the command line argument:

-Xms2048M -Xmx2048M -Xss4M --supershell=false

In terms of the feature, SBT_OPT should act as a superset of JAVA_OPTS allowing -X* and -Dkey=val as well as sbt script specific features such as -v and --supershell=false.

command line argument

By default, command line argument to sbt script is assumed to be a command passed through to the sbt’s launcher JAR, and thereby sbt Main (“mothership”) unless they are explicitly specified as command line options at the sbt script level.

They are basically the ones specified in https://github.com/sbt/sbt-launcher-package, such as -v and -no-colors.

For the discussion of passing arguments to JVM here are the relevant ones:

  • -Dkey=val. -Dkey=val are passed directly as JVM argument.
  • -X*. Options starting with -X should be passed directly as JVM argument.
  • -J-X*. This is same as above, except -J is stripped. -J-X* is for keeping compatibility with sbt-extras script.

Note:

  • I don’t know if we need to support -S-X*. If we’re not doing that already, I think it’s ok to skip it.
  • -XX* should be covered by -X*.

Legacy Windows Config:

C:\Program Files (x86)\sbt\conf\sbtconfig.txt

Proposal would be to standardize on:

C:\Program Files (x86)\sbt\conf\sbtopts

Note: the installation path doesn’t matter, it is looking for ..\conf\sbtopts as a file relative to the sbt.bat file. Not sure if that distinction is worth pointing out.

Perhaps be explicit that SBT_OPTS is a superset of JAVA_OPTS

The content of SBT_OPTS can contain both JAVA_OPTS content as well as sbt command line arguments (e.g. --supershell=false)

Or some such?

I don’t remember why we make this distinction, but I’m guessing it’s because annoying to work with files without extension on Windows because traditionally Windows users tend to use GUI for file navigation and editing.

Sounds good. I added the following:

In terms of the feature, SBT_OPT should act as a superset of JAVA_OPTS allowing -X* and -Dkey=val as well as sbt script specific features such as -v and --supershell=false.

Generally we should discourage the use of JAVA_OPTS and use SBT_OPTS

I use JAVA_OPTS to pass down system properties into JVMs forked by sbt. -D command line arguments don’t t work for this because the system properties aren’t passed into subprocesses. It would be nice to have a way specify system properties that are propagated into forked JVMs from the command line (without changes to the build files - I’m aware that properties can explicitly be passed into forked JVMs by editing build.sbt but this isn’t great for ad-hoc properties / experimentation).