diff --git a/libraries/scripting/jsr223-test/test/kotlin/script/experimental/jsr223/test/KotlinJsr223ScriptEngineIT.kt b/libraries/scripting/jsr223-test/test/kotlin/script/experimental/jsr223/test/KotlinJsr223ScriptEngineIT.kt index 2e6f34b9077..b5903a6f4ed 100644 --- a/libraries/scripting/jsr223-test/test/kotlin/script/experimental/jsr223/test/KotlinJsr223ScriptEngineIT.kt +++ b/libraries/scripting/jsr223-test/test/kotlin/script/experimental/jsr223/test/KotlinJsr223ScriptEngineIT.kt @@ -12,6 +12,12 @@ import org.junit.Test import javax.script.* import kotlin.script.experimental.jvmhost.jsr223.KotlinJsr223ScriptEngineImpl +// duplicating it here to avoid dependency on the implementation - it may interfere with tests +private const val KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY = "kotlin.jsr223.experimental.resolve.dependencies.from.context.classloader" + +@Suppress("unused") // accessed from the tests below +val shouldBeVisibleFromRepl = 7 + class KotlinJsr223ScriptEngineIT { init { @@ -272,6 +278,26 @@ obj Assert.assertTrue(result is Function0<*>) Assert.assertEquals(3, (result as Function0<*>).invoke()) } + + @Test + fun testResolveFromContextStandard() { + val scriptEngine = ScriptEngineManager().getEngineByExtension("kts")!! + val result = scriptEngine.eval("kotlin.script.experimental.jsr223.test.shouldBeVisibleFromRepl * 6") + Assert.assertEquals(42, result) + } + + @Test + fun testResolveFromContextDirectExperimental() { + val prevProp = System.setProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY, "true") + try { + val scriptEngine = ScriptEngineManager().getEngineByExtension("kts")!! + val result = scriptEngine.eval("kotlin.script.experimental.jsr223.test.shouldBeVisibleFromRepl * 6") + Assert.assertEquals(42, result) + } finally { + if (prevProp == null) System.clearProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY) + else System.setProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY, prevProp) + } + } } fun assertThrows(exceptionClass: Class<*>, body: () -> Unit) { diff --git a/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScriptEngineFactory.kt b/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScriptEngineFactory.kt index f19e21218db..3e4416f1a94 100644 --- a/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScriptEngineFactory.kt +++ b/libraries/scripting/jsr223/src/kotlin/script/experimental/jsr223/KotlinJsr223DefaultScriptEngineFactory.kt @@ -12,8 +12,9 @@ import javax.script.Bindings import javax.script.ScriptContext import javax.script.ScriptEngine import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.dependencies +import kotlin.script.experimental.jvm.JvmDependencyFromClassLoader import kotlin.script.experimental.jvm.JvmScriptCompilationConfigurationBuilder -import kotlin.script.experimental.jvm.dependenciesFromCurrentContext import kotlin.script.experimental.jvm.jvm import kotlin.script.experimental.jvm.updateClasspath import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext @@ -21,6 +22,13 @@ import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromT import kotlin.script.experimental.jvmhost.createJvmEvaluationConfigurationFromTemplate import kotlin.script.experimental.jvmhost.jsr223.KotlinJsr223ScriptEngineImpl +/** + * If the property is set to true, the dependencies will be resolved directly from the context classloader + * (Thread.currentThread().contextClassLoader) using reflection and other techniques (experimental!). + * Otherwise the same classloader will be used to extract the classpath first, and this classpath will be used instead. + */ +const val KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY = "kotlin.jsr223.experimental.resolve.dependencies.from.context.classloader" + class KotlinJsr223DefaultScriptEngineFactory : KotlinJsr223JvmScriptEngineFactoryBase() { private val compilationConfiguration = createJvmCompilationConfigurationFromTemplate() @@ -49,7 +57,11 @@ class KotlinJsr223DefaultScriptEngineFactory : KotlinJsr223JvmScriptEngineFactor this, ScriptCompilationConfiguration(compilationConfiguration) { jvm { - dependenciesFromCurrentContext() + if (System.getProperty(KOTLIN_JSR223_RESOLVE_FROM_CLASSLOADER_PROPERTY) == "true") { + dependencies(JvmDependencyFromClassLoader { Thread.currentThread().contextClassLoader }) + } else { + dependenciesFromCurrentContext() + } } }, evaluationConfiguration