diff --git a/backend/src/main/scala/bloop/Compiler.scala b/backend/src/main/scala/bloop/Compiler.scala index b15db508cd..03f643e8c6 100644 --- a/backend/src/main/scala/bloop/Compiler.scala +++ b/backend/src/main/scala/bloop/Compiler.scala @@ -604,54 +604,73 @@ object Compiler { } } - private def getCompilationOptions( - inputs: CompileInputs, - logger: Logger, - newClassesDir: Path - ): CompileOptions = { - // Sources are all files - val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying)) - val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying)) - def existsReleaseSetting = inputs.scalacOptions.exists(opt => + /** + * Bloop runs Scala compilation in the same process as the main server, + * so the compilation process will use the same JDK that Bloop is using. + * That's why we must ensure that produce class files will be compliant with expected JDK version + * and compilation errors will show up when using wrong JDK API. + */ + private def adjustScalacReleaseOptions( + scalacOptions: Array[String], + javacBin: Option[AbsolutePath], + logger: Logger + ): Array[String] = { + def existsReleaseSetting = scalacOptions.exists(opt => opt.startsWith("-release") || opt.startsWith("--release") || opt.startsWith("-java-output-version") ) - def sameHome = inputs.javacBin match { + def sameHome = javacBin match { case Some(bin) => bin.getParent.getParent == JavaRuntime.home case None => false } - val scalacOptions = inputs.javacBin.flatMap(binary => + javacBin.flatMap(binary => // /bin/java JavaRuntime.getJavaVersionFromJavaHome(binary.getParent.getParent) ) match { - case None => inputs.scalacOptions - case Some(_) if existsReleaseSetting || sameHome => inputs.scalacOptions + case None => scalacOptions + case Some(_) if existsReleaseSetting || sameHome => scalacOptions case Some(version) => try { val numVer = if (version.startsWith("1.8")) 8 else version.takeWhile(_.isDigit).toInt val bloopNumVer = JavaRuntime.version.takeWhile(_.isDigit).toInt if (bloopNumVer > numVer) { - inputs.scalacOptions ++ List("-release", numVer.toString()) + scalacOptions ++ List("-release", numVer.toString()) } else { logger.warn( s"Bloop is runing with ${JavaRuntime.version} but your code requires $version to compile, " + "this might cause some compilation issues when using JDK API unsupported by the Bloop's current JVM version" ) - inputs.scalacOptions + scalacOptions } } catch { case NonFatal(_) => - inputs.scalacOptions + scalacOptions } } + } + + private def getCompilationOptions( + inputs: CompileInputs, + logger: Logger, + newClassesDir: Path + ): CompileOptions = { + // Sources are all files + val sources = inputs.sources.map(path => converter.toVirtualFile(path.underlying)) + val classpath = inputs.classpath.map(path => converter.toVirtualFile(path.underlying)) + + val scalacOptions = adjustScalacReleaseOptions( + scalacOptions = inputs.scalacOptions, + javacBin = inputs.javacBin, + logger = logger + ) val optionsWithoutFatalWarnings = scalacOptions.filter(_ != "-Xfatal-warnings") - val isFatalWarningsEnabled = scalacOptions.length != optionsWithoutFatalWarnings.length + val areFatalWarningsEnabled = scalacOptions.length != optionsWithoutFatalWarnings.length // Enable fatal warnings in the reporter if they are enabled in the build - if (isFatalWarningsEnabled) + if (areFatalWarningsEnabled) inputs.reporter.enableFatalWarnings() CompileOptions diff --git a/frontend/src/test/scala/bloop/JavaVersionSpec.scala b/frontend/src/test/scala/bloop/JavaVersionSpec.scala index ffedbaff61..8c5b67f52d 100644 --- a/frontend/src/test/scala/bloop/JavaVersionSpec.scala +++ b/frontend/src/test/scala/bloop/JavaVersionSpec.scala @@ -5,6 +5,8 @@ import bloop.config.Config import bloop.logging.RecordingLogger import bloop.util.TestProject import bloop.util.TestUtil +import java.nio.file.Files +import scala.util.Try object JavaVersionSpec extends bloop.testing.BaseSuite { @@ -12,6 +14,10 @@ object JavaVersionSpec extends bloop.testing.BaseSuite { def checkFlag(scalacOpts: List[String], jdkVersion: String = "8") = { val javaHome = jvmManager.get(jdkVersion).toPath() + Try { + println(Files.list(javaHome).collect(java.util.stream.Collectors.toList())) + println(Files.readString(javaHome.resolve("release"))) + } val jvmConfig = Some(Config.JvmConfig(Some(javaHome), Nil)) TestUtil.withinWorkspace { workspace => val sources = List( @@ -37,7 +43,7 @@ object JavaVersionSpec extends bloop.testing.BaseSuite { | value repeat is not a member of String | L2: val output = "La ".repeat(2) + "Land"; | ^ - |a/src/main/scala/Foo.scala: L2 [E1] + |$targetFoo: L2 [E1] |Failed to compile 'a' |""".stripMargin )