Fix issue where ScalaInstance broke the thread-context-classloader for all scala classes.

The issue is that when you manually set a ScalaInstance, i.e. not one from Ivy, the
classpath which is returned for any given configuration ONLY uses Ivy.   This means that
the legitimate Scala JAR files that need to be on the classpath are missing from the list.
For some reason, the way we instantiate tests uses an unfiltered classloader against the
ScalaInstance, *BUT* the thread-context-classloader DOES use a filtered instance by
classpath.   This add the hook into the TestFramework runner creation so that
the classpath accurately reflects the jars needed.

cc @rkuhn
This commit is contained in:
Josh Suereth 2014-09-09 08:56:51 -04:00
parent 50460fad28
commit d2950da9dd
2 changed files with 12 additions and 1 deletions

View File

@ -191,7 +191,12 @@ object TestFramework {
val notInterfaceFilter = (name: String) => !interfaceFilter(name)
val dual = new DualLoader(scalaInstance.loader, notInterfaceFilter, x => true, getClass.getClassLoader, interfaceFilter, x => false)
val main = ClasspathUtilities.makeLoader(classpath, dual, scalaInstance, tempDir)
ClasspathUtilities.filterByClasspath(interfaceJar +: classpath, main)
// TODO - There's actually an issue with the classpath facility such that unmanagedScalaInstances are not added
// to the classpath correctly. We have a temporary workaround here.
val cp: Seq[File] =
if (scalaInstance.isManagedVersion) interfaceJar +: classpath
else scalaInstance.allJars ++ (interfaceJar +: classpath)
ClasspathUtilities.filterByClasspath(cp, main)
}
def createTestFunction(loader: ClassLoader, taskDef: TaskDef, runner: TestRunner, testTask: TestTask): TestFunction =
new TestFunction(taskDef, runner, (r: TestRunner) => withContextLoader(loader) { r.run(taskDef, testTask) }) { def tags = testTask.tags }

View File

@ -19,6 +19,12 @@ final class ScalaInstance(val version: String, val loader: ClassLoader, val libr
@deprecated("Only `allJars` and `jars` can be reliably provided for modularized Scala.", "0.13.0") val compilerJar: File,
@deprecated("Only `allJars` and `jars` can be reliably provided for modularized Scala.", "0.13.0") val extraJars: Seq[File],
val explicitActual: Option[String]) extends xsbti.compile.ScalaInstance {
/**
* This tells us if the scalaInstance is from a managed (i.e. ivy-resolved) scala *or*
* if it's a free-floating ScalaInstance, in which case we need to do tricks to the classpaths we find
* because it won't be on them.
*/
final def isManagedVersion = explicitActual.isDefined
// These are to implement xsbti.ScalaInstance
@deprecated("Only `allJars` and `jars` can be reliably provided for modularized Scala.", "0.13.0")
def otherJars: Array[File] = extraJars.toArray