Scala: Print all environment variables and system properties

While working with the sbt and Mill build tools recently, and updating Scala and Java versions like crazy, I’ve been trying to verify some things in my Scala applications. Just now I wrote this little Scala 3 / Dotty application to print out all system environment variables and properties:

@main def EnvironmentVariables =
    import scala.collection.JavaConverters._
    import scala.language.implicitConversions
    val environmentVars = System.getenv().asScala
    for ((k,v) <- environmentVars) println(s"key: $k, value: $v")

    val properties = System.getProperties().asScala
    for ((k,v) <- properties) println(s"key: $k, value: $v")

All of the output is shown below, though I trimmed some long output. I was looking for all Java environment variables, so I made most of those fields bold:

key: PATH, value: /opt/local/bin:/opt/local/sbin ...
key: PKG_CONFIG_PATH, value: /usr/local/opt/openssl@1.1/lib/pkgconfig
key: JAVA_MAIN_CLASS_59322, value: xsbt.boot.Boot
key: HISTSIZE, value: 1000000
key: JAVA_HOME, value: /Users/al/Library/Caches/Coursier/jvm/adopt@1.11.0-7/Contents/Home
key: JAVA_OPTS, value: -Dfile.encoding=UTF-8
key: TERM, value: xterm-256color
key: CS_FORMER_JAVA_HOME, value:
key: LANG, value: en_US.UTF-8
key: LDFLAGS, value: -L/usr/local/opt/openssl@1.1/lib
key: HISTFILESIZE, value: 1000000
key: DISPLAY, value: /private/tmp/com.apple.launchd....
key: LOGNAME, value: al
key: XPC_SERVICE_NAME, value: 0
key: PWD, value: /Users/al/Projects/Books/ScalaCookbook2Examples...
key: TERM_PROGRAM_VERSION, value: 421.2
key: SHELL, value: /bin/bash
key: TERM_PROGRAM, value: Apple_Terminal
key: CPPFLAGS, value: -I/usr/local/opt/openssl@1.1/include
key: SECURITYSESSIONID, value: 186a8
key: USER, value: al
key: TMPDIR, value: /var/folders/hk/0n_3xn8...
key: SSH_AUTH_SOCK, value: /private/tmp/com.apple.launchd....
key: XPC_FLAGS, value: 0x0
key: TERM_SESSION_ID, value: FEBCD025-77DE-41D1-...
key: __CF_USER_TEXT_ENCODING, value: 0x...
key: Apple_PubSub_Socket_Render, value: /private/tmp/com.apple.launchd....
key: HOME, value: /Users/al
key: SHLVL, value: 1
key: gopherProxySet, value: false
key: awt.toolkit, value: sun.lwawt.macosx.LWCToolkit
key: java.specification.version, value: 11
key: sun.cpu.isalist, value:
key: sun.jnu.encoding, value: UTF-8
key: java.class.path, value: /Users/al/bin/sbt/bin/sbt-launch.jar
key: java.vm.vendor, value: AdoptOpenJDK
key: sun.arch.data.model, value: 64
key: jline.shutdownhook, value: false
key: java.vendor.url, value: https://adoptopenjdk.net/
key: user.timezone, value: America/Denver
key: os.name, value: Mac OS X
key: java.vm.specification.version, value: 11
key: sun.java.launcher, value: SUN_STANDARD
key: user.country, value: US
key: sun.boot.library.path, value: /Users/al/Library/Caches/Coursier/jvm/adopt@1.11.0-7/Contents/Home/lib
key: sun.java.command, value: /Users/al/bin/sbt/bin/sbt-launch.jar
key: http.nonProxyHosts, value: local|*.local|...
key: jdk.debug, value: release
key: sun.cpu.endian, value: little
key: user.home, value: /Users/al
key: user.language, value: en
key: java.specification.vendor, value: Oracle Corporation
key: java.version.date, value: 2020-04-14
key: java.home, value: /Users/al/Library/Caches/Coursier/jvm/adopt@1.11.0-7/Contents/Home
key: file.separator, value: /
key: java.vm.compressedOopsMode, value: Zero based
key: line.separator, value:

key: java.specification.name, value: Java Platform API Specification
key: java.vm.specification.vendor, value: Oracle Corporation
key: java.awt.graphicsenv, value: sun.awt.CGraphicsEnvironment
key: jline.esc.timeout, value: 0
key: sun.management.compiler, value: HotSpot 64-Bit Tiered Compilers
key: ftp.nonProxyHosts, value: local|*.local|...
key: java.runtime.version, value: 11.0.7+10
key: user.name, value: al
key: path.separator, value: :
key: os.version, value: 10.14.6
key: jna.nosys, value: true
key: java.runtime.name, value: OpenJDK Runtime Environment
key: file.encoding, value: UTF-8
key: jnidispatch.path, value: /var/folders/hk/...
key: java.vm.name, value: OpenJDK 64-Bit Server VM
key: jna.platform.library.path, value: /usr/lib:/usr/lib
key: java.vendor.version, value: AdoptOpenJDK
key: jna.loaded, value: true
key: java.vendor.url.bug, value: https://github.com/AdoptOpenJDK/openjdk-support/issues
key: java.io.tmpdir, value: /var/folders/hk/...
key: java.version, value: 11.0.7
key: user.dir, value: /Users/al/Projects/Books/ScalaCookbook2Examples
key: os.arch, value: x86_64
key: java.vm.specification.name, value: Java Virtual Machine Specification
key: java.awt.printerjob, value: sun.lwawt.macosx.CPrinterJob
key: sun.os.patch.level, value: unknown
key: java.library.path, value: /Users/al/Library/Java/Extensions...
key: java.vendor, value: AdoptOpenJDK
key: java.vm.info, value: mixed mode
key: java.vm.version, value: 11.0.7+10
key: scala.ext.dirs, value: /Users/al/.sbt/0.13/java9-rt-ext-adoptopenjdk_11_0_7
key: sun.io.unicode.encoding, value: UnicodeBig
key: java.class.version, value: 55.0
key: socksNonProxyHosts, value: local|*.local|169.254/16|*.169.254/16

In my case I mostly wanted to know what Java command line options/arguments were enabled, and the Java/JVM version, so after sifting through this output, I saw that I could just print these Java system properties:

println(System.getenv().asScala("JAVA_OPTS"))               // -Dfile.encoding=UTF-8
println(System.getProperties().asScala("java.version"))     // 11.0.7
println(System.getProperties().asScala("java.vm.version"))  // 11.0.7+10

I ran this on a MacOS system, so it was interesting to see “Mac OS X” in the output; that name hasn’t been used in several years now. I also installed this version of Java with Coursier, so that’s why that name shows up in the output.

Passing Java/JVM options to SBT

Note that on Unix/Linux systems you can start SBT like this:

env JAVA_OPTS="-Xmx512m -Xms128m" sbt

When you do so, that first line prints this output:

println(System.getenv().asScala("JAVA_OPTS"))   // -Xmx512m -Xms128m

That ended up being a nice way to confirm that the Java command line options I was setting were making it through sbt to the JVM. For example, many other examples I see on the internet do not actually work.