Deduplicating classloaders and classpath entries on constructing script classloader
This commit is contained in:
+2
-2
@@ -31,7 +31,7 @@ class KJvmCompiledModuleFromClassLoader(val moduleClassLoader: ClassLoader) : KJ
|
||||
internal class DualClassLoader(fallbackLoader: ClassLoader, parentLoader: ClassLoader?) :
|
||||
ClassLoader(singleClassLoader(fallbackLoader, parentLoader) ?: parentLoader) {
|
||||
|
||||
private class Wrapper(parent: ClassLoader) : ClassLoader(parent) {
|
||||
internal class Wrapper(parent: ClassLoader) : ClassLoader(parent) {
|
||||
fun openFindResources(name: String): Enumeration<URL> = super.findResources(name)
|
||||
fun openFindResource(name: String): URL? = super.findResource(name)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ internal class DualClassLoader(fallbackLoader: ClassLoader, parentLoader: ClassL
|
||||
}
|
||||
}
|
||||
|
||||
private val fallbackClassLoader: Wrapper? =
|
||||
internal val fallbackClassLoader: Wrapper? =
|
||||
if (/* optimization */ parentLoader == null || singleClassLoader(fallbackLoader, parentLoader) != null) null
|
||||
else Wrapper(fallbackLoader)
|
||||
|
||||
|
||||
+28
-4
@@ -6,6 +6,7 @@
|
||||
package kotlin.script.experimental.jvm.impl
|
||||
|
||||
import java.io.*
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.script.experimental.api.*
|
||||
@@ -149,12 +150,35 @@ private fun CompiledScript<*>.makeClassLoaderFromDependencies(baseClassLoader: C
|
||||
script.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
|
||||
?.asSequence()?.map { script.compilationConfiguration to it } ?: emptySequence()
|
||||
}
|
||||
|
||||
val processedClasspathElements = mutableSetOf<URL>()
|
||||
fun recursiveClassPath(res: Sequence<URL>, classLoader: ClassLoader?): Sequence<URL> =
|
||||
when (classLoader) {
|
||||
null -> res
|
||||
is DualClassLoader -> recursiveClassPath(res, classLoader.parent) +
|
||||
recursiveClassPath(emptySequence(), classLoader.fallbackClassLoader)
|
||||
is URLClassLoader -> recursiveClassPath(res + classLoader.urLs, classLoader.parent)
|
||||
else -> recursiveClassPath(res, classLoader.parent)
|
||||
}
|
||||
recursiveClassPath(emptySequence(), baseClassLoader).forEach { processedClasspathElements.add(it) }
|
||||
|
||||
val processedClassloaders = mutableSetOf<ClassLoader>()
|
||||
|
||||
return dependenciesWithConfigurations.fold(baseClassLoader) { parentClassLoader, (compilationConfiguration, scriptDependency) ->
|
||||
when (scriptDependency) {
|
||||
is JvmDependency -> URLClassLoader(scriptDependency.classpath.map { it.toURI().toURL() }.toTypedArray(), parentClassLoader)
|
||||
is JvmDependencyFromClassLoader -> DualClassLoader(scriptDependency.getClassLoader(compilationConfiguration), baseClassLoader)
|
||||
else -> baseClassLoader
|
||||
}
|
||||
is JvmDependency -> {
|
||||
scriptDependency.classpath.mapNotNull {
|
||||
val url = it.toURI().toURL()
|
||||
if (processedClasspathElements.add(url)) url else null
|
||||
}.takeUnless { it.isEmpty() }?.let { URLClassLoader(it.toTypedArray(), parentClassLoader) }
|
||||
}
|
||||
is JvmDependencyFromClassLoader -> {
|
||||
val dependenciesClassLoader = scriptDependency.getClassLoader(compilationConfiguration)
|
||||
if (processedClassloaders.add(dependenciesClassLoader)) DualClassLoader(dependenciesClassLoader, parentClassLoader)
|
||||
else null
|
||||
}
|
||||
else -> null
|
||||
} ?: parentClassLoader
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user