mirror of
https://github.com/sbt/sbt.git
synced 2026-10-06 10:03:56 +02:00
[2.x] fix: Honor JAVA_HOME in the Unix launcher (#9825)
Problem: The Unix launcher ignores JAVA_HOME and selects Java from PATH when JAVACMD is absent. Solution: Check JAVA_HOME/bin/java before falling back to PATH while preserving explicit --java-home and JAVACMD precedence. Fixes #9794
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
package example.test
|
||||
|
||||
import java.io.File
|
||||
import sbt.io.IO
|
||||
import scala.sys.process.{ Process, ProcessLogger }
|
||||
|
||||
/**
|
||||
* First-hop propagation guard: an explicit `-java-home` must be the JDK the Windows launcher runs
|
||||
@@ -33,4 +35,55 @@ object JavaHomeScriptTest extends verify.BasicTestSuite with ShellScriptUtil:
|
||||
out.exists(_.contains(javaExe)),
|
||||
s"launcher should run $javaExe; command echo was: ${out.mkString(" | ")}"
|
||||
)
|
||||
List(
|
||||
("JAVA_HOME overrides PATH", "", "home", "", "home"),
|
||||
("JAVACMD overrides JAVA_HOME", "command", "home", "", "command"),
|
||||
("invalid JAVACMD falls back to JAVA_HOME", "missing", "home", "", "home"),
|
||||
("empty JAVA_HOME falls back to PATH", "", "", "", "path"),
|
||||
("invalid JAVA_HOME falls back to PATH", "", "missing", "", "path"),
|
||||
("invalid JAVACMD and JAVA_HOME fall back to PATH", "missing", "missing", "", "path"),
|
||||
("--java-home overrides environment", "command", "home", "option", "option"),
|
||||
).foreach: (name, command, home, option, expected) =>
|
||||
test(name):
|
||||
checkJavaSelection(command, home, option, expected)
|
||||
|
||||
private def checkJavaSelection(
|
||||
command: String,
|
||||
home: String,
|
||||
option: String,
|
||||
expected: String
|
||||
): Unit =
|
||||
if isWindows then cancel("Bash launcher Java selection")
|
||||
else
|
||||
IO.withTemporaryDirectory: dir =>
|
||||
def javaHome(name: String): File = new File(dir, s"$name jdk")
|
||||
def java(name: String): File = new File(javaHome(name), "bin/java")
|
||||
List("path", "home", "command", "option").foreach: name =>
|
||||
IO.write(
|
||||
java(name),
|
||||
IO.read(new File(javaBinDir, "java"))
|
||||
.replace("else:\n", s"else:\n print('SELECTED: $name')\n")
|
||||
)
|
||||
Predef.assert(java(name).setExecutable(true))
|
||||
IO.write(new File(dir, "build.sbt"), "")
|
||||
val env = Seq(
|
||||
"PATH" -> s"${java("path").getParent}${File.pathSeparator}${sys.env("PATH")}",
|
||||
"JAVACMD" -> (if command.isEmpty then "" else java(command).getAbsolutePath),
|
||||
"JAVA_HOME" -> (if home.isEmpty then "" else javaHome(home).getAbsolutePath),
|
||||
"JAVA_OPTS" -> "",
|
||||
"SBT_OPTS" -> "",
|
||||
"JAVA_TOOL_OPTIONS" -> "",
|
||||
"XDG_CONFIG_HOME" -> dir.getAbsolutePath,
|
||||
"SBT_ETC_FILE" -> new File(dir, "missing-sbtopts").getAbsolutePath,
|
||||
)
|
||||
val args = if option.isEmpty then Seq.empty
|
||||
else Seq("--java-home", javaHome(option).getAbsolutePath)
|
||||
val output = scala.collection.mutable.ListBuffer.empty[String]
|
||||
val exit = Process(
|
||||
Seq(sbtScript.getAbsolutePath, "--server") ++ args ++ Seq("compile"),
|
||||
dir,
|
||||
env*
|
||||
).!(ProcessLogger(line => output += line, line => output += line))
|
||||
Predef.assert(exit == 0, output.mkString("\n"))
|
||||
Predef.assert(output.contains(s"SELECTED: $expected"), output.mkString("\n"))
|
||||
end JavaHomeScriptTest
|
||||
|
||||
@@ -173,6 +173,7 @@ trait ShellScriptUtil extends BasicTestSuite:
|
||||
envVars("JAVACMD") = new File(javaBinDir, "java").getAbsolutePath()
|
||||
envVars("JAVA_HOME") = javaHomeEnv
|
||||
else
|
||||
envVars("JAVACMD") = new File(javaBinDir, "java").getAbsolutePath()
|
||||
envVars("PATH") = javaBinDir + File.pathSeparator + path
|
||||
envVars("JAVA_HOME") = javaHomeEnv
|
||||
val cmd =
|
||||
|
||||
Reference in New Issue
Block a user