Controlling java version

In a shell script I can set control the java version by setting the env variable JAVA_HOME near the top of the shell script to enforce that all subprocesses inherit that env var.

I’m trying to convert a bunch of shell scripts to a scala program. The program
creates a project in /tmp and launches sbt in that project. I’d like to control
which version of Java is used. Really I’d like to detect and die if java 14 is used.

What is the correct way do to this. Do I really need to intervene at every call to a subshell and introduce an env var at each point?

Isn’t there a way to set an env var for the UNIX process which Scala is running in?

If the answer is that I unfortunately have to intervene at every subprocess creation, then who can I set an env variable value for a call such as

import sys.process._
Seq("sbt", "-Dsbt.log.noformat=true", "test:compile") !

or

import sys.process._
Seq("sbt", "-Dsbt.log.noformat=true", "test:compile") #> new File("/tmp/compile.out")

I’d like to assert at the top of my program that the java version is not 14.
But the following evaluates to empty string and prints the java version to the console ""

import sys.process._
Seq("java","-version") !!

Some of the documentation for !! talks about the process builder. What is that? Is it an implicit object? Can I define my own implicit object to define information for the environment of the sub process?

Maybe I figured something out, but it doesn’t quite work the way I hoped.
It seems I can put a Process object in place of a Seq[String] object.
And when creating the Process object, I can specify a cwd and augment the environment.

This works for the .! operator, but it doesn’t seem to work for the #> operator. The assertion always fails in this code

  def shellToFile(command:Seq[String],cwd:String,fileName:String):Unit = {
    require(fileName(0) == '/')
    require(cwd(0) == '/')
    import sys.process._
    val p = Process(command, cwd=Some(new File(cwd)), "JAVA_HOME" -> JAVA_HOME)
    val outFile = new File(fileName)

    p #> outFile
    assert(outFile.exists, s"expected file $outFile was not created")
  }

ahhh. I see, Process(...) #> new File(...) is only the ProcessBuilder.
I still need to exec the process.
unfortunately, and misleadingly

p #> new File("/tmp/foo") !

Does not work. At least IntelliJ complains, so I thought it was wrong.
But putting parens in and using .! works fine.

(p #> new File("/tmp/foo")).!