From 3cd4815fe479b93ed0c433480f9298c7334b7a39 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 1 Nov 2017 08:48:12 +1000 Subject: [PATCH 1/5] More general boot classpath discovery --- .../src/main/scala/sbt/compiler/CompilerArguments.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala index df279bb37..df9bea371 100644 --- a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala +++ b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala @@ -45,7 +45,13 @@ final class CompilerArguments(scalaInstance: xsbti.compile.ScalaInstance, cp: xs /** Add the correct Scala library jar to the boot classpath if `addLibrary` is true.*/ def createBootClasspath(addLibrary: Boolean) = { - val originalBoot = System.getProperty("sun.boot.class.path", "") + def findBoot: String = { + import scala.collection.JavaConverters._ + System.getProperties.asScala.iterator.collectFirst { + case (k, v) if k.endsWith(".boot.class.path") => v + }.getOrElse("") + } + val originalBoot = System.getProperty("sun.boot.class.path", findBoot) if (addLibrary) { val newBootPrefix = if (originalBoot.isEmpty) "" else originalBoot + File.pathSeparator newBootPrefix + scalaInstance.libraryJar.getAbsolutePath From bf36f824fd10a1e892a0274d611b1a6c9014a5f4 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 1 Nov 2017 09:09:25 +1000 Subject: [PATCH 2/5] Generalize handling of ext.dirs --- compile/src/main/scala/sbt/compiler/CompilerArguments.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala index df9bea371..e3916fcb9 100644 --- a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala +++ b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala @@ -69,7 +69,7 @@ final class CompilerArguments(scalaInstance: xsbti.compile.ScalaInstance, cp: xs def bootClasspathFor(classpath: Seq[File]) = bootClasspath(hasLibrary(classpath)) import Path._ - def extClasspath: Seq[File] = (IO.parseClasspath(System.getProperty("java.ext.dirs", "")) * "*.jar").get + def extClasspath: Seq[File] = List("java.ext.dirs", "scala.ext.dirs").flatMap(k => (IO.parseClasspath(System.getProperty(k, "")) * "*.jar").get) } object CompilerArguments { val BootClasspathOption = "-bootclasspath" From 5a1e832a1393b5171e1d289faab6eb78d99f2539 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 1 Nov 2017 11:20:31 +1000 Subject: [PATCH 3/5] Ignore directories that scalac reports as underlying source on Java 9 --- compile/interface/src/main/scala/xsbt/Dependency.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile/interface/src/main/scala/xsbt/Dependency.scala b/compile/interface/src/main/scala/xsbt/Dependency.scala index 34c237bb3..9f203308f 100644 --- a/compile/interface/src/main/scala/xsbt/Dependency.scala +++ b/compile/interface/src/main/scala/xsbt/Dependency.scala @@ -63,7 +63,7 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with case Some((f, className, inOutDir)) => if (inOutDir && on.isJavaDefined) registerTopLevelSym(on) f match { - case ze: ZipArchive#Entry => for (zip <- ze.underlyingSource; zipFile <- Option(zip.file)) binaryDependency(zipFile, className) + case ze: ZipArchive#Entry => for (zip <- ze.underlyingSource; zipFile <- Option(zip.file).filterNot(_.isDirectory)) binaryDependency(zipFile, className) case pf: PlainFile => binaryDependency(pf.file, className) case _ => () } From aac97476ce70b3e70ae124d90de1942ff2f79a90 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 1 Nov 2017 13:36:23 +1000 Subject: [PATCH 4/5] Refactor createBootClasspath to avoid work when sun.boot.class.path is present --- .../scala/sbt/compiler/CompilerArguments.scala | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala index e3916fcb9..6a2a41056 100644 --- a/compile/src/main/scala/sbt/compiler/CompilerArguments.scala +++ b/compile/src/main/scala/sbt/compiler/CompilerArguments.scala @@ -45,13 +45,14 @@ final class CompilerArguments(scalaInstance: xsbti.compile.ScalaInstance, cp: xs /** Add the correct Scala library jar to the boot classpath if `addLibrary` is true.*/ def createBootClasspath(addLibrary: Boolean) = { - def findBoot: String = { - import scala.collection.JavaConverters._ - System.getProperties.asScala.iterator.collectFirst { - case (k, v) if k.endsWith(".boot.class.path") => v - }.getOrElse("") - } - val originalBoot = System.getProperty("sun.boot.class.path", findBoot) + def findBoot: String = + { + import scala.collection.JavaConverters._ + System.getProperties.asScala.iterator.collectFirst { + case (k, v) if k.endsWith(".boot.class.path") => v + }.getOrElse("") + } + val originalBoot = Option(System.getProperty("sun.boot.class.path")).getOrElse(findBoot) if (addLibrary) { val newBootPrefix = if (originalBoot.isEmpty) "" else originalBoot + File.pathSeparator newBootPrefix + scalaInstance.libraryJar.getAbsolutePath From d9df8835e67470849aa5efa8ed9330b421143427 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 5 Nov 2017 13:54:29 +1100 Subject: [PATCH 5/5] Add comment about reason for underlying source hack --- compile/interface/src/main/scala/xsbt/Dependency.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compile/interface/src/main/scala/xsbt/Dependency.scala b/compile/interface/src/main/scala/xsbt/Dependency.scala index 9f203308f..c20974790 100644 --- a/compile/interface/src/main/scala/xsbt/Dependency.scala +++ b/compile/interface/src/main/scala/xsbt/Dependency.scala @@ -63,7 +63,13 @@ final class Dependency(val global: CallbackGlobal) extends LocateClassFile with case Some((f, className, inOutDir)) => if (inOutDir && on.isJavaDefined) registerTopLevelSym(on) f match { - case ze: ZipArchive#Entry => for (zip <- ze.underlyingSource; zipFile <- Option(zip.file).filterNot(_.isDirectory)) binaryDependency(zipFile, className) + case ze: ZipArchive#Entry => + // Scala 2.10/2.11 give back $JAVA_HOME as the underlying source for the platform classloader + // See https://github.com/scala/scala/pull/6113. Treating that as not having an underlying source + // is the least bad option for now. We would not trigger a recompile if the JDK is updated, but that + // is better than recompiling *every* time, which seems to happen if we let the directory propagate + // to `binaryDependency`. + for (zip <- ze.underlyingSource; zipFile <- Option(zip.file).filterNot(_.isDirectory)) binaryDependency(zipFile, className) case pf: PlainFile => binaryDependency(pf.file, className) case _ => () }