我正在尝试编写一个界面(GUI)以运行一些Kotlin脚本。我仅从Junit测试开始,以确保可以执行脚本。我什至无法加载kotlin引擎。看来我的依存关系(等级)是有序的,但是您可以再次检查。
var arr = [1, 2, 3, 4, 5];
var newArr = arr.reduce((acc, current) => {
acc.push((acc[acc.length - 1] || 0) + current);
return acc;
}, []);
console.log(newArr);
上方:compile name: 'kotlin-script-runtime',
group: 'org.jetbrains.kotlin', version: kotlin_version
compile name: 'kotlin-script-util',
group: 'org.jetbrains.kotlin', version: kotlin_version
compile name: 'kotlin-compiler-embeddable',
group: 'org.jetbrains.kotlin', version: kotlin_version
这是测试失败:
ext.kotlin_version = '1.3.0'
最后一个@Test
fun testEngine() {
// attempt to load script engine class before looking for it
val ktsEngineClassName = "org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngine";
var clazz: Class<*>? = null;
// assign the clazz variable inside a closure to catch ClassNotFound
assertDoesNotThrow({clazz = Class.forName(ktsEngineClassName)}, "could not find $ktsEngineClassName")
// just to make sure it's there
assertNotNull(clazz, "could not find $ktsEngineClassName")
// so far so good, but here's the problem:
val engineName = "kotlin"
// load the factory
val factory = ScriptEngineManager().getEngineByName(engineName)?.factory
// and test that we got it
assertNotNull(factory, "didn't find factory for '$engineName'." +
"\navailable: ${ScriptEngineManager().engineFactories}")
}
失败,显示以下输出:
assertNotNull
您可以看到,尽管脚本引擎类似乎已成功通过org.opentest4j.AssertionFailedError: didn't find factory for 'kotlin'.
available: [jdk.nashorn.api.scripting.NashornScriptEngineFactory@1a41b1fc] ==> expected: not <null>
加载,但未注册名称Class.forName
,并且可用引擎列表仅包含Nashorn。如何确保引擎已注册?
答案 0 :(得分:1)
看起来kotlin脚本引擎不在默认的类加载器中,因此在实例化ScriptEngineManager时需要指定一个类加载器:
ScriptEngineManager(clazz.getClassLoader()) getEngineByName(engineName)?. factory
更新
在Java 8中,如果您在路径 META_INF / services 中查看 $ JAVA_HOME / jre / lib / ext / nashorn.jar ,会有一个名为的文件> javax.script.ScriptEngineFactory 。内容是:
jdk.nashorn.api.scripting.NashornScriptEngineFactory
因此,当ScriptEngineManager
寻找ScriptEngine
实现时,它将扫描类路径中名为/META-INF/services/javax.script.ScriptEngineFactory
的条目,并从找到的每个条目中加载类名称。
通常,包含目标脚本引擎的jar将包含其自己的服务文件,但是,如果您的kotlin脚本引擎已经在类路径中,我想您可以使用以下命令创建名为/META-INF/services/javax.script.ScriptEngineFactory
的类路径资源
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
,您应该很好。另外,您不需要在示例// so far so good, but here's the problem:
上方的示例中提供的任何代码。