Add a property for resolving via classloader in JSR-223

This commit is contained in:
Ilya Chernikov
2019-10-09 16:13:38 +02:00
parent 54caf4bf16
commit 8b750bfdc7
2 changed files with 40 additions and 2 deletions
@@ -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) {
@@ -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<KotlinJsr223DefaultScript>()
@@ -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