error when object passed in is java.lang.reflect.Proxy
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)
maybe this can be useful for fixing this issue: https://stackoverflow.com/a/49010634
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)