diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/BasicJvmReplEvaluator.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/BasicJvmReplEvaluator.kt index e5a612512ac9e..083f053665704 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/BasicJvmReplEvaluator.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/BasicJvmReplEvaluator.kt @@ -42,7 +42,7 @@ class BasicJvmReplEvaluator(val scriptEvaluator: ScriptEvaluator = BasicJvmScrip } if (lastSnippetClass != null) { jvm { - baseClassLoader(lastSnippetClass.java.classLoader) + lastSnippetClassLoader(lastSnippetClass.java.classLoader) } } } diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt index 27461bbefe0e5..45fd0d96cac44 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/KJvmCompiledScript.kt @@ -119,13 +119,14 @@ fun KJvmCompiledScript.getOrCreateActualClassloader(evaluationConfiguration: Scr val module = compiledModule ?: throw IllegalStateException("Illegal call sequence, actualClassloader should be set before calling function on the class without module") val baseClassLoader = evaluationConfiguration[ScriptEvaluationConfiguration.jvm.baseClassLoader] + val lastClassLoader = evaluationConfiguration[ScriptEvaluationConfiguration.jvm.lastSnippetClassLoader] ?: baseClassLoader val classLoaderWithDeps = if (evaluationConfiguration[ScriptEvaluationConfiguration.jvm.loadDependencies] == false) baseClassLoader - else makeClassLoaderFromDependencies(baseClassLoader) + else makeClassLoaderFromDependencies(baseClassLoader, lastClassLoader) return module.createClassLoader(classLoaderWithDeps) } -private fun CompiledScript.makeClassLoaderFromDependencies(baseClassLoader: ClassLoader?): ClassLoader? { +private fun CompiledScript.makeClassLoaderFromDependencies(baseClassLoader: ClassLoader?, lastClassLoader: ClassLoader?): ClassLoader? { val processedScripts = mutableSetOf() fun recursiveScriptsSeq(res: Sequence, script: CompiledScript): Sequence = if (processedScripts.add(script)) script.otherScripts.asSequence().fold(res + script, ::recursiveScriptsSeq) @@ -139,17 +140,17 @@ private fun CompiledScript.makeClassLoaderFromDependencies(baseClassLoader: Clas val processedClasspathElements = mutableSetOf() fun recursiveClassPath(res: Sequence, classLoader: ClassLoader?): Sequence = when (classLoader) { - null -> res + null, baseClassLoader -> 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) } + recursiveClassPath(emptySequence(), lastClassLoader).forEach { processedClasspathElements.add(it) } val processedClassloaders = mutableSetOf() - return dependenciesWithConfigurations.fold(baseClassLoader) { parentClassLoader, (compilationConfiguration, scriptDependency) -> + return dependenciesWithConfigurations.fold(lastClassLoader) { parentClassLoader, (compilationConfiguration, scriptDependency) -> when (scriptDependency) { is JvmDependency -> { scriptDependency.classpath.mapNotNull { diff --git a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptEvaluation.kt b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptEvaluation.kt index 7fe61bc326581..48909d3c03af7 100644 --- a/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptEvaluation.kt +++ b/libraries/scripting/jvm/src/kotlin/script/experimental/jvm/jvmScriptEvaluation.kt @@ -33,6 +33,11 @@ val JvmScriptEvaluationConfigurationKeys.baseClassLoader by PropertiesCollection isTransient = true ) +/** + * Classloader of the last snippet (supposed to be used in REPL) + */ +val JvmScriptEvaluationConfigurationKeys.lastSnippetClassLoader by PropertiesCollection.key(isTransient = true) + /** * Load script dependencies before evaluation, true by default * If false, it is assumed that the all dependencies will be provided via baseClassLoader