mirror of https://github.com/sbt/sbt.git
Add improved classloader construction short circuit
In order for sbt to function well, it needs the test interface, jansi and forked jline jars provided by a classloader that is parent to all other sbt classloaders. To do this for just the test interface jar, I just checked if the top loader in the app configuration had the correct name. Now that there are three jars, this is more complicated so I updated the launcher to create a top loader with the method getEarlyJars implemented and returning the three needed jars. This is a much more scalable design. If sbt is entered with a configuration that does not have a top loader with the getEarlyJars method defined, then we just fall back on constructing the default layered classlaoder from the configuration classpath. The motivation for this change is that I discovered that sbt immediately crashed when I tried to run a non-snapshot version. After this change, I verified that both snapshot and non-snapshot versions of the latest sbt code could load with both an obsolete and up-to-date launcher.
This commit is contained in:
parent
6110734383
commit
464ea1b97e
|
|
@ -9,7 +9,7 @@ package sbt.internal
|
|||
|
||||
import java.io.File
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.net.{ URL, URLClassLoader }
|
||||
import java.net.URL
|
||||
import java.util.concurrent.{ ExecutorService, Executors }
|
||||
import ClassLoaderClose.close
|
||||
|
||||
|
|
@ -60,21 +60,20 @@ private[sbt] class XMainConfiguration {
|
|||
def run(moduleName: String, configuration: xsbti.AppConfiguration): xsbti.MainResult = {
|
||||
val topLoader = configuration.provider.scalaProvider.launcher.topLoader
|
||||
val updatedConfiguration =
|
||||
if (topLoader.getClass.getCanonicalName.contains("TestInterfaceLoader")) {
|
||||
topLoader match {
|
||||
case u: URLClassLoader =>
|
||||
val urls = u.getURLs
|
||||
var i = 0
|
||||
while (i < urls.length && i >= 0) {
|
||||
if (urls(i).toString.contains("jline")) i = -2
|
||||
else i += 1
|
||||
}
|
||||
if (i < 0) configuration
|
||||
else makeConfiguration(configuration)
|
||||
case _ => configuration
|
||||
try {
|
||||
val method = topLoader.getClass.getMethod("getEarlyJars")
|
||||
val jars = method.invoke(topLoader).asInstanceOf[Array[URL]]
|
||||
var canReuseConfiguration = jars.length == 3
|
||||
var j = 0
|
||||
while (j < jars.length && canReuseConfiguration) {
|
||||
val s = jars(j).toString
|
||||
canReuseConfiguration =
|
||||
s.contains("jline") || s.contains("test-interface") || s.contains("jansi")
|
||||
j += 1
|
||||
}
|
||||
} else {
|
||||
makeConfiguration(configuration)
|
||||
if (canReuseConfiguration) configuration else makeConfiguration(configuration)
|
||||
} catch {
|
||||
case _: NoSuchMethodException => makeConfiguration(configuration)
|
||||
}
|
||||
val loader = updatedConfiguration.provider.loader
|
||||
Thread.currentThread.setContextClassLoader(loader)
|
||||
|
|
|
|||
Loading…
Reference in New Issue