Scala 脚本引擎创建单例的另一个实例



所以,我正在使用 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());

这会将ScriptEngineClassLoader更改为相同的。

相关内容

  • 没有找到相关文章

最新更新