scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

JSR223 - inconsistent behaviour across multiple eval calls #8669

Open scabug opened 10 years ago

scabug commented 10 years ago

Upon the first evaluation of a script, an instance of the specified interface is returned as expected.

Upon the second evaluation of the same script (using a new ScriptEngine), the returned object is no longer an instance of the interface.

The code snippet, when executed, throws a RuntimeException on "call 2".

// ScalaTest.java
package scala.test;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class ScalaTest {
    // main method
    public static void main(String[] args) throws Exception {
        // set system property to use java classpath
        System.setProperty("scala.usejavacp", "true");

        // script which returns a new instance of SomeInterface
        String script = "new scala.test.ScalaTest.SomeInterface() { def run() { println(\"someMethod called\") } }";

        // eval the script the first time, passes without errors, prints to the console as expected
        runScript(script, 1);

        // eval the script the second time, throws a RuntimeException that the result of engine.eval() is not an instance of SomeInterface 
        runScript(script, 2);
    }

    // execute the specified script; call parameter indicates the time the script has been called and is used for debug only 
    public static void runScript(String script, int call) throws Exception {
        // get a new scala script engine
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");

        // eval the script
        Object obj = engine.eval(script);

        // check if the result is an instance of SomeInterface
        if (!(obj instanceof SomeInterface)) {
            throw new RuntimeException("engine broken on call "+Integer.toString(call));
        }

        // call run method on the resulting instance
        ((SomeInterface)obj).run();
    }

    // simple interface with a single method
    public interface SomeInterface {
        void run();
    }
}
scabug commented 10 years ago

Imported From: https://issues.scala-lang.org/browse/SI-8669?orig=1 Reporter: Mio Ussum (temp44) Affected Versions: 2.11.1

scabug commented 10 years ago

@som-snytt said: It works if the interface is java.lang.Runnable, but not with the nested interface.

scabug commented 10 years ago

Mio Ussum (temp44) said: Yes, i figured that. However, it does not work if the interface is not nested, either. I only provided it nested to make the snippet shorter.