diff --git a/modules/build/src/main/scala/scala/build/internal/OsLibc.scala b/modules/build/src/main/scala/scala/build/internal/OsLibc.scala index 4e95cd5409..d0d63e8b6e 100644 --- a/modules/build/src/main/scala/scala/build/internal/OsLibc.scala +++ b/modules/build/src/main/scala/scala/build/internal/OsLibc.scala @@ -5,7 +5,12 @@ import coursier.jvm.{JavaHome, JvmIndex} import java.io.IOException import java.nio.charset.Charset -import scala.util.Try +import scala.build.Positioned +import scala.build.blooprifle.VersionUtil.parseJavaVersion +import scala.build.internal.CsLoggerUtil.* +import scala.build.options.BuildOptions +import scala.util.control.NonFatal +import scala.util.{Properties, Try} object OsLibc { @@ -81,4 +86,41 @@ object OsLibc { s"${JavaHome.systemId}|$defaultJvm0" } + def javaHomeVersion(javaHome: Positioned[os.Path]): (Int, String) = { + val ext = if (Properties.isWin) ".exe" else "" + val javaCmd = (javaHome.value / "bin" / s"java$ext").toString + + val javaVersionOutput = os.proc(javaCmd, "-version").call( + cwd = os.pwd, + stdout = os.Pipe, + stderr = os.Pipe, + mergeErrIntoOut = true + ).out.text().trim() + val javaVersion = parseJavaVersion(javaVersionOutput).getOrElse { + throw new Exception(s"Could not parse java version from output: $javaVersionOutput") + } + (javaVersion, javaCmd) + } + + def downloadJvm(jvmId: String, options: BuildOptions): String = { + implicit val ec = options.finalCache.ec + val javaHomeManager = options.javaHomeManager + .withMessage(s"Downloading JVM $jvmId") + val logger = javaHomeManager.cache + .flatMap(_.archiveCache.cache.loggerOpt) + .getOrElse(_root_.coursier.cache.CacheLogger.nop) + val command = { + val path = logger.use { + try javaHomeManager.get(jvmId).unsafeRun() + catch { + case NonFatal(e) => throw new Exception(e) + } + } + os.Path(path) + } + val ext = if (Properties.isWin) ".exe" else "" + val javaCmd = (command / "bin" / s"java$ext").toString + javaCmd + } + } diff --git a/modules/build/src/main/scala/scala/build/options/BuildOptions.scala b/modules/build/src/main/scala/scala/build/options/BuildOptions.scala index f8997a6fbf..2a1b57c370 100644 --- a/modules/build/src/main/scala/scala/build/options/BuildOptions.scala +++ b/modules/build/src/main/scala/scala/build/options/BuildOptions.scala @@ -13,7 +13,6 @@ import java.nio.charset.StandardCharsets import java.security.MessageDigest import scala.build.EitherCps.{either, value} -import scala.build.blooprifle.VersionUtil.parseJavaVersion import scala.build.errors._ import scala.build.internal.Constants._ import scala.build.internal.CsLoggerUtil._ @@ -21,7 +20,6 @@ import scala.build.internal.ScalaParse.scala2NightlyRegex import scala.build.internal.{OsLibc, StableScalaVersion, Util} import scala.build.options.validation.BuildOptionsRule import scala.build.{Artifacts, Logger, Os, Position, Positioned} -import scala.util.Properties import scala.util.control.NonFatal final case class BuildOptions( @@ -162,20 +160,8 @@ final case class BuildOptions( case class JavaHomeInfo(javaCommand: String, version: Int) private lazy val javaCommand0: Positioned[JavaHomeInfo] = { - val javaHome = javaHomeLocation() - val ext = if (Properties.isWin) ".exe" else "" - val javaCmd = (javaHome.value / "bin" / s"java$ext").toString - - val javaVersionOutput = os.proc(javaCmd, "-version").call( - cwd = os.pwd, - stdout = os.Pipe, - stderr = os.Pipe, - mergeErrIntoOut = true - ).out.text().trim() - val javaVersion = parseJavaVersion(javaVersionOutput).getOrElse { - throw new Exception(s"Could not parse java version from output: $javaVersionOutput") - } - + val javaHome = javaHomeLocation() + val (javaVersion, javaCmd) = OsLibc.javaHomeVersion(javaHome) Positioned(javaHome.positions, JavaHomeInfo(javaCmd, javaVersion)) } diff --git a/modules/cli/src/main/scala/scala/cli/commands/SharedOptions.scala b/modules/cli/src/main/scala/scala/cli/commands/SharedOptions.scala index 3b79559b73..74c7a61c11 100644 --- a/modules/cli/src/main/scala/scala/cli/commands/SharedOptions.scala +++ b/modules/cli/src/main/scala/scala/cli/commands/SharedOptions.scala @@ -12,7 +12,6 @@ import java.io.{ByteArrayOutputStream, File, InputStream} import scala.build.blooprifle.BloopRifleConfig import scala.build.compiler.{BloopCompilerMaker, ScalaCompilerMaker, SimpleScalaCompilerMaker} -import scala.build.internal.CsLoggerUtil._ import scala.build.internal.{Constants, OsLibc} import scala.build.options.{Platform, ScalacOpt, ShadowingSeq} import scala.build.{options => bo, _} @@ -189,31 +188,22 @@ final case class SharedOptions( def bloopRifleConfig(): BloopRifleConfig = { - val options = buildOptions(false, None) - implicit val ec = options.finalCache.ec - val jvmId = compilationServer.bloopJvm.getOrElse { - OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17") - } - val javaHomeManager = options.javaHomeManager - .withMessage(s"Downloading JVM $jvmId") - val logger = javaHomeManager.cache - .flatMap(_.archiveCache.cache.loggerOpt) - .getOrElse(_root_.coursier.cache.CacheLogger.nop) - val command = { - val path = logger.use { - try javaHomeManager.get(jvmId).unsafeRun() - catch { - case NonFatal(e) => throw new Exception(e) - } + val options = buildOptions(false, None) + lazy val defaultJvmCmd = + OsLibc.downloadJvm(OsLibc.baseDefaultJvm(OsLibc.jvmIndexOs, "17"), options) + val javaCmd = compilationServer.bloopJvm.map(OsLibc.downloadJvm(_, options)).orElse { + for (javaHome <- options.javaHomeLocationOpt()) yield { + val (javaHomeVersion, javaHomeCmd) = OsLibc.javaHomeVersion(javaHome) + if (javaHomeVersion >= 17) javaHomeCmd + else defaultJvmCmd } - os.Path(path) - } - val ext = if (Properties.isWin) ".exe" else "" + }.getOrElse(defaultJvmCmd) + compilationServer.bloopRifleConfig( logging.logger, coursierCache, logging.verbosity, - (command / "bin" / s"java$ext").toString, + javaCmd, directories.directories, Some(17) )