所以,我正在使用 Scala 的JSR 223
创建一个脚本系统,但我遇到了这个问题,我找不到任何原因。
有一个类似单例的类,它具有添加事件侦听器(从脚本)和调度事件(从核心)的方法。一切正常,但由于某种原因,当我调度事件时,添加的侦听器消失了。
重现问题后,我发现脚本引擎创建了单例的另一个实例:
这是我Singleton
课:
package test;
import java.util.Arrays;
public final class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {
Arrays.stream(Thread.currentThread().getStackTrace()).forEach(System.out::println);
System.out.println();
}
public static Singleton instance() {
return instance;
}
}
这是我Main
课:
package test;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public final class Main {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");
// this is a trick I found to access the classpath,
// might be the problem
@SuppressWarnings("rawtypes")
scala.collection.immutable.List nil = scala.collection.immutable.Nil$.MODULE$;
@SuppressWarnings("unchecked")
scala.collection.immutable.$colon$colon<String> vals = scala.collection.immutable.$colon$colon$.MODULE$.apply("true", nil);
((scala.tools.nsc.interpreter.IMain) engine).settings().usejavacp().tryToSet(vals);
engine.eval("test.Singleton.instance");
Singleton.instance();
}
}
这是输出:
java.lang.Thread.getStackTrace(Unknown Source)
test.Singleton.<init>(Singleton.java:10)
test.Singleton.<clinit>(Singleton.java:7)
$line3.$read$$iw$$iw$.<init>(<console>:8)
$line3.$read$$iw$$iw$.<clinit>(<console>)
$line3.$eval$.$result$lzycompute(<console>:5)
$line3.$eval$.$result(<console>:5)
$line3.$eval.$result(<console>)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:773)
scala.tools.nsc.interpreter.IMain$ReadEvalPrint.callEither(IMain.scala:777)
scala.tools.nsc.interpreter.IMain$ReadEvalPrint.evalEither(IMain.scala:792)
scala.tools.nsc.interpreter.IMain$WrappedRequest.eval(IMain.scala:613)
scala.tools.nsc.interpreter.IMain.eval(IMain.scala:1047)
javax.script.AbstractScriptEngine.eval(Unknown Source)
test.Main.main(Main.java:19)
java.lang.Thread.getStackTrace(Unknown Source)
test.Singleton.<init>(Singleton.java:10)
test.Singleton.<clinit>(Singleton.java:7)
test.Main.main(Main.java:20)
堆栈跟踪显示脚本引擎最终创建了一个新的Singleton
实例,但我不知道为什么。
谢谢。
浏览源代码后找到了修复程序:
((scala.tools.nsc.interpreter.IMain) engine).settings().embeddedDefaults(Main.class.getClassLoader());
这会将ScriptEngine
的ClassLoader
更改为相同的。