2

ということで、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、その理由はわかりません。

ありがとうございました。

4

1 に答える 1

1

ソースコードを閲覧した後、修正を見つけました:

((scala.tools.nsc.interpreter.IMain) engine).settings().embeddedDefaults(Main.class.getClassLoader());

これにより、が同じものに変更さClassLoaderれます。ScriptEngine

于 2015-05-02T14:49:23.220 に答える