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?) :
|
internal class DualClassLoader(fallbackLoader: ClassLoader, parentLoader: ClassLoader?) :
|
||||||
ClassLoader(singleClassLoader(fallbackLoader, parentLoader) ?: parentLoader) {
|
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 openFindResources(name: String): Enumeration<URL> = super.findResources(name)
|
||||||
fun openFindResource(name: String): URL? = super.findResource(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
|
if (/* optimization */ parentLoader == null || singleClassLoader(fallbackLoader, parentLoader) != null) null
|
||||||
else Wrapper(fallbackLoader)
|
else Wrapper(fallbackLoader)
|
||||||
|
|
||||||
|
|||||||
+28
-4
@@ -6,6 +6,7 @@
|
|||||||
package kotlin.script.experimental.jvm.impl
|
package kotlin.script.experimental.jvm.impl
|
||||||
|
|
||||||
import java.io.*
|
import java.io.*
|
||||||
|
import java.net.URL
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
@@ -149,12 +150,35 @@ private fun CompiledScript<*>.makeClassLoaderFromDependencies(baseClassLoader: C
|
|||||||
script.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
|
script.compilationConfiguration[ScriptCompilationConfiguration.dependencies]
|
||||||
?.asSequence()?.map { script.compilationConfiguration to it } ?: emptySequence()
|
?.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) ->
|
return dependenciesWithConfigurations.fold(baseClassLoader) { parentClassLoader, (compilationConfiguration, scriptDependency) ->
|
||||||
when (scriptDependency) {
|
when (scriptDependency) {
|
||||||
is JvmDependency -> URLClassLoader(scriptDependency.classpath.map { it.toURI().toURL() }.toTypedArray(), parentClassLoader)
|
is JvmDependency -> {
|
||||||
is JvmDependencyFromClassLoader -> DualClassLoader(scriptDependency.getClassLoader(compilationConfiguration), baseClassLoader)
|
scriptDependency.classpath.mapNotNull {
|
||||||
else -> baseClassLoader
|
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