jshell-scriptengine icon indicating copy to clipboard operation
jshell-scriptengine copied to clipboard

error when object passed in is java.lang.reflect.Proxy

Open sdyura opened this issue 2 years ago • 2 comments

i want to use this plugin in a webapp, and most of them use proxies for classes for various reasons, also i want to have the option to test thing and pass in mockito mocks, and they also use proxies, but its not working for me.


    private static void runJShellBindingExample2() {
        try {
            ScriptEngineManager manager = new ScriptEngineManager();
            ScriptEngine engine = manager.getEngineByName("jshell");

            String script = "" +
                    "if (inputA != null && inputB != null) {" +
                    "   System.out.println(\"Input A: \" + inputA);" +
                    "   System.out.println(\"Input B: \" + inputB);" +
                    "   var output = inputA + \" \" + inputB;" +
                    "   System.out.println(\"GOING TO RETURN: \" + output);" +
                    "   return output;" +
                    "}" +
                    "else {" +
                    "   return \"\";" +
                    "}";

            CharSequence magic = (CharSequence)Proxy.newProxyInstance(ScriptEngineExample.class.getClassLoader(), new Class[] {CharSequence.class}, (proxy, method, args) -> {
                if (method.getName().equals("toString")) {
                    return String.valueOf(System.nanoTime());
                }
                return method.invoke("", args);
            });

            System.out.println("testing 1 " + magic);
            System.out.println("testing 2 " + magic);
            System.out.println("testing 3 " + magic);
            System.out.println("testing 4 " + magic);

            engine.put("inputA", "hello");
            engine.put("inputB", magic);

            Object result = engine.eval(script);
            System.out.println("runJShellBindingExample2 Result: " + result);

        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

gives me:

testing 1 13515178228750
testing 2 13515178263000
testing 3 13515178281583
testing 4 13515178295291
javax.script.ScriptException: package jdk.proxy1 does not exist
Snippet:VariableKey(inputB)#1-jdk.proxy1.$Proxy0 inputB = (jdk.proxy1.$Proxy0) ch.obermuhlner.scriptengine.jshell.VariablesTransfer.getVariableValue("inputB");
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.throwAsScriptException(JShellCompiledScript.java:178)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.evaluateSnippet(JShellCompiledScript.java:157)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.pushVariables(JShellCompiledScript.java:59)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.eval(JShellCompiledScript.java:42)
	at java.scripting/javax.script.CompiledScript.eval(CompiledScript.java:93)
	at ch.obermuhlner.scriptengine.jshell.JShellScriptEngine.eval(JShellScriptEngine.java:86)
	at ch.obermuhlner.scriptengine.jshell.JShellScriptEngine.eval(JShellScriptEngine.java:74)
	at ch.obermuhlner.scriptengine.jshell.JShellScriptEngine.eval(JShellScriptEngine.java:64)
	at ch.obermuhlner.scriptengine.example.ScriptEngineExample.runJShellBindingExample2(ScriptEngineExample.java:98)
	at ch.obermuhlner.scriptengine.example.ScriptEngineExample.runJShellExamples(ScriptEngineExample.java:23)
	at ch.obermuhlner.scriptengine.example.ScriptEngineExample.main(ScriptEngineExample.java:12)

the error i get when i try it in my actual app is a bit different, but similar:

javax.script.ScriptException: cannot find symbol
  symbol:   class MyTest$MyTestHelper$Proxy$_$$_WeldClientProxy
  location: package mypackage
Snippet:VariableKey(testObject)#4-mypackage.MyTest$MyTestHelper$Proxy$_$$_WeldClientProxy testObject = (mypackage.MyTest$MyTestHelper$Proxy$_$$_WeldClientProxy) ch.obermuhlner.scriptengine.jshell.VariablesTransfer.getVariableValue("testObject");
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.throwAsScriptException(JShellCompiledScript.java:178)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.evaluateSnippet(JShellCompiledScript.java:157)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.pushVariables(JShellCompiledScript.java:59)
	at ch.obermuhlner.scriptengine.jshell.JShellCompiledScript.eval(JShellCompiledScript.java:42)
	at java.scripting/javax.script.CompiledScript.eval(CompiledScript.java:93)
	at ch.obermuhlner.scriptengine.jshell.JShellScriptEngine.eval(JShellScriptEngine.java:86)
	at mypackage.MyScriptEnvironment.invokeFunction(ScriptEnvironment.java:29)

sdyura avatar Nov 08 '23 18:11 sdyura

maybe this can be useful for fixing this issue: https://stackoverflow.com/a/49010634

sdyura avatar Jul 31 '24 13:07 sdyura

i have found a workaround, if i add

        <dependency>
            <groupId>org.apache.groovy</groupId>
            <artifactId>groovy-jsr223</artifactId>
            <version>4.0.22</version>
        </dependency>

and do

getEngineByName("groovy")

it actually runs the jshell script correctly

but this basically means stopping using this project altogether

(this workaround also MASSIVELY reduces the memory usage of this code, 1GB ram allows 3000 concurrent groovy scripts as opposed to 60 concurrent jshell scripts)

sdyura avatar Aug 07 '24 19:08 sdyura