diff --git a/backend/src/main/scala/bloop/Compiler.scala b/backend/src/main/scala/bloop/Compiler.scala index 022abf86c4..c6eab238e4 100644 --- a/backend/src/main/scala/bloop/Compiler.scala +++ b/backend/src/main/scala/bloop/Compiler.scala @@ -81,7 +81,7 @@ object Compiler { object NotOk { def unapply(result: Result): Option[Result] = result match { - case f @ (Failed(_, _, _) | Cancelled(_, _) | Blocked(_)) => Some(f) + case f @ (Failed(_, _, _) | Cancelled(_, _) | Blocked(_) | GlobalError(_)) => Some(f) case _ => None } } diff --git a/backend/src/main/scala/bloop/ScalaInstance.scala b/backend/src/main/scala/bloop/ScalaInstance.scala index cfa7c95cf0..2631d7752c 100644 --- a/backend/src/main/scala/bloop/ScalaInstance.scala +++ b/backend/src/main/scala/bloop/ScalaInstance.scala @@ -2,7 +2,7 @@ package bloop import java.io.File import java.net.URLClassLoader -import java.nio.file.{Files, Path, Paths} +import java.nio.file.{Files, Path, Paths, StandardCopyOption} import java.nio.file.attribute.{BasicFileAttributes, FileTime} import java.util.Properties @@ -159,23 +159,53 @@ object ScalaInstance { * domain. */ def scalaInstanceFromBloop(logger: Logger): Option[ScalaInstance] = { - def findLocationForClazz(clazz: Class[_]): Option[Path] = { - try Some(Paths.get(clazz.getProtectionDomain.getCodeSource.getLocation.toURI)) - catch { case NonFatal(_) => None } + lazy val tempDirectory = Files.createTempDirectory("bloop-scala-instance") + implicit val filter = DebugFilter.Compilation + def findLocationForClazz(clazz: Class[_], jarName: String): Option[Path] = { + try { + val expectedPath = clazz.getProtectionDomain.getCodeSource.getLocation.toURI + logger.debug(s"${clazz} detected in ${expectedPath}") + + try Some(Paths.get(expectedPath)) + catch { + case t: java.nio.file.FileSystemNotFoundException => + // When bloop is bootstrapped by coursier, jars are available from resources instead + logger.debug( + s"Load jar from resource because scheme '${expectedPath.getScheme}' has no file system provider" + ) + + val fromResourceStream = + clazz.getResourceAsStream("/" + expectedPath.getSchemeSpecificPart) + if (fromResourceStream == null) None + else { + val outPath = tempDirectory.resolve(jarName) + logger.debug(s"${clazz} detected in resource, dumping to ${outPath}...") + Files.copy(fromResourceStream, outPath) + Some(outPath) + } + } + } catch { + case NonFatal(t) => + logger.debug("Unexpected error when creting Bloop's classloader") + logger.trace(t) + None + } } if (cachedBloopScalaInstance != null) { cachedBloopScalaInstance } else { + logger.debug("Creating a scala instance from Bloop's classloader...") val instance = { for { - scalaLibraryJar <- findLocationForClazz(scala.Predef.getClass) - scalaReflectJar <- findLocationForClazz(classOf[scala.reflect.api.Trees]) - scalaCompilerJar <- findLocationForClazz(scala.tools.nsc.Main.getClass) - scalaXmlJar <- findLocationForClazz(classOf[scala.xml.Node]) - jlineJar <- findLocationForClazz(classOf[jline.console.ConsoleReader]) + libraryJar <- findLocationForClazz(scala.Predef.getClass, "scala-library.jar") + reflectJar <- findLocationForClazz(classOf[scala.reflect.api.Trees], "scala-reflect.jar") + compilerJar <- findLocationForClazz(scala.tools.nsc.Main.getClass, "scala-compiler.jar") + xmlJar <- findLocationForClazz(classOf[scala.xml.Node], "scala-xml.jar") + jlineJar <- findLocationForClazz(classOf[jline.console.ConsoleReader], "jline.jar") } yield { - val jars = List(scalaLibraryJar, scalaReflectJar, scalaCompilerJar, scalaXmlJar, jlineJar) + logger.debug(s"Created Bloop scala instance for ${BloopScalaInfo.scalaVersion}") + val jars = List(libraryJar, reflectJar, compilerJar, xmlJar, jlineJar) ScalaInstance( BloopScalaInfo.scalaOrganization, ScalacCompilerName, diff --git a/frontend/src/test/scala/bloop/tasks/CompileSpec.scala b/frontend/src/test/scala/bloop/tasks/CompileSpec.scala index d767718e16..8c30bc82fb 100644 --- a/frontend/src/test/scala/bloop/tasks/CompileSpec.scala +++ b/frontend/src/test/scala/bloop/tasks/CompileSpec.scala @@ -12,7 +12,6 @@ import bloop.cli.Commands import bloop.config.Config import bloop.engine.tasks.Tasks import bloop.engine.{Feedback, Run, State} -import bloop.exec.JavaEnv import bloop.logging.{Logger, RecordingLogger} import bloop.tasks.TestUtil.{ RootProject,