You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Calling the .addAll() method on a Java HashSet in JavaScript with a JavaScript array as the parameter (See above code example) throws the exception:
javax.script.ScriptException: java.lang.UnsupportedOperationException: Unsupported operation identifier 'iterator' and object '[JavaObject[org.example.MockClass]]'(language: JavaScript, type: Array). Identifier is not executable or instantiable.
See Stack Trace for more information.
The code example at the top works on Nashorn, and it appears the problem is with Graal not mapping the JavaScript Array to a Collection, which Set.addAll() requires [1].
This explicit mapping solution came from another issue [2]. Using this type map caused other problems as the type mapping is too generic and caught other data types.
JS Error object no longer being passable to the logger:
InvokeScriptedProcessor[id=350d1c49-b35e-3954-61b3-347c6d73f6f9] Processing halted: yielding [1 sec]: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (error) on org.apache.nifi.controller.TerminationAwareLogger failed due to: no applicable overload found (overloads: [
Method[public void org.apache.nifi.controller.TerminationAwareLogger.error(java.lang.String,java.lang.Object[])],
Method[public void org.apache.nifi.controller.TerminationAwareLogger.error(java.lang.String)],
Method[public void org.apache.nifi.controller.TerminationAwareLogger.error(java.lang.String,java.lang.Object[],java.lang.Throwable)],
Method[public void org.apache.nifi.controller.TerminationAwareLogger.error(java.lang.String,java.lang.Throwable)],
Method[public default void org.apache.nifi.logging.ComponentLog.error(org.apache.nifi.logging.LogMessage)]
], arguments: [com.oracle.truffle.js.runtime.builtins.JSErrorObject@1e1ab28c (JSErrorObject)])
The issue is caused by the JSErrorObject being passed into a Java logger class method which does not have a method that takes JSErrorObject. I have been unable to find a way to map JSErrorObject to anything else, as it seems to be indistinguishable from an object. From my research, it seems we can’t directly reference JSErrorObject from truffle. Is there a way to explicitly map JSErrorObject to something else?
Is there a proper way to use JavaScript Arrays in Java methods requiring Collections as their parameters?
Stack Trace
javax.script.ScriptException: java.lang.UnsupportedOperationException: Unsupported operation identifier 'iterator' and object '[JavaObject[org.example.MockClass]]'(language: JavaScript, type: Array). Identifier is not executable or instantiable.
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineException.unsupported(PolyglotEngineException.java:147)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotInteropErrors.invokeUnsupported(PolyglotInteropErrors.java:193)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ProxyInvokeNode.invokeOrExecute(PolyglotObjectProxyHandler.java:261)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ProxyInvokeNode.doCachedMethod(PolyglotObjectProxyHandler.java:214)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ProxyInvokeNodeGen.executeAndSpecialize(PolyglotObjectProxyHandlerFactory.java:308)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ProxyInvokeNodeGen.execute(PolyglotObjectProxyHandlerFactory.java:244)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ObjectProxyNode.doDefault(PolyglotObjectProxyHandler.java:150)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ObjectProxyNodeGen.executeAndSpecialize(PolyglotObjectProxyHandlerFactory.java:124)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ObjectProxyNodeGen.executeImpl(PolyglotObjectProxyHandlerFactory.java:110)
at org.graalvm.truffle/com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler.invoke(PolyglotObjectProxyHandler.java:105)
at jdk.proxy1/jdk.proxy1.$Proxy40.iterator(Unknown Source)
at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:335)
at <js>.:program(<eval>:9)
at org.graalvm.sdk/org.graalvm.polyglot.Context.eval(Context.java:403)
at org.graalvm.js.scriptengine/com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:485)
at org.graalvm.js.scriptengine/com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:427)
at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:247)
at org.example.ScriptingEngine.runScript(ScriptingEngine.java:29)
at org.example.Main.main(Main.java:52)
Caused by: java.lang.UnsupportedOperationException: Unsupported operation identifier 'iterator' and object '[JavaObject[org.example.MockClass]]'(language: JavaScript, type: Array). Identifier is not executable or instantiable.
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotEngineException.unsupported(PolyglotEngineException.java:147)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotInteropErrors.invokeUnsupported(PolyglotInteropErrors.java:193)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ProxyInvokeNode.invokeOrExecute(PolyglotObjectProxyHandler.java:261)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ProxyInvokeNode.doCachedMethod(PolyglotObjectProxyHandler.java:214)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ProxyInvokeNodeGen.executeAndSpecialize(PolyglotObjectProxyHandlerFactory.java:308)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ProxyInvokeNodeGen.execute(PolyglotObjectProxyHandlerFactory.java:244)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler$ObjectProxyNode.doDefault(PolyglotObjectProxyHandler.java:150)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ObjectProxyNodeGen.executeAndSpecialize(PolyglotObjectProxyHandlerFactory.java:124)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandlerFactory$ObjectProxyNodeGen.executeImpl(PolyglotObjectProxyHandlerFactory.java:110)
at org.graalvm.truffle/com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:718)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:641)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:574)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:558)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callIndirect(OptimizedCallTarget.java:486)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.call(OptimizedCallTarget.java:467)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler.invoke(PolyglotObjectProxyHandler.java:105)
at jdk.proxy1/jdk.proxy1.$Proxy40.iterator(Unknown Source)
at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:335)
at org.graalvm.truffle/com.oracle.truffle.host.HostMethodDesc$SingleMethod$MHBase.invokeHandle(HostMethodDesc.java:350)
at org.graalvm.truffle/com.oracle.truffle.host.GuestToHostCodeCache$1.executeImpl(GuestToHostCodeCache.java:96)
at org.graalvm.truffle/com.oracle.truffle.host.GuestToHostRootNode.execute(GuestToHostRootNode.java:80)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:718)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callInlined(OptimizedCallTarget.java:522)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.GraalRuntimeSupport.callInlined(GraalRuntimeSupport.java:239)
at org.graalvm.truffle/com.oracle.truffle.host.GuestToHostRootNode.guestToHostCall(GuestToHostRootNode.java:102)
at org.graalvm.truffle/com.oracle.truffle.host.HostMethodDesc$SingleMethod$MHBase.invokeGuestToHost(HostMethodDesc.java:386)
at org.graalvm.truffle/com.oracle.truffle.host.HostExecuteNode.doInvoke(HostExecuteNode.java:876)
at org.graalvm.truffle/com.oracle.truffle.host.HostExecuteNode.doFixed(HostExecuteNode.java:139)
at org.graalvm.truffle/com.oracle.truffle.host.HostExecuteNodeGen$Inlined.executeAndSpecialize(HostExecuteNodeGen.java:402)
at org.graalvm.truffle/com.oracle.truffle.host.HostExecuteNodeGen$Inlined.execute(HostExecuteNodeGen.java:362)
at org.graalvm.truffle/com.oracle.truffle.host.HostObject.invokeMember(HostObject.java:465)
at org.graalvm.truffle/com.oracle.truffle.host.HostObjectGen$InteropLibraryExports$Cached.invokeMemberNode_AndSpecialize(HostObjectGen.java:7369)
at org.graalvm.truffle/com.oracle.truffle.host.HostObjectGen$InteropLibraryExports$Cached.invokeMember(HostObjectGen.java:7355)
at org.graalvm.truffle/com.oracle.truffle.api.interop.InteropLibraryGen$CachedDispatch.invokeMember(InteropLibraryGen.java:8477)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$ForeignInvokeNode.executeCall(JSFunctionCallNode.java:1609)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeAndSpecialize(JSFunctionCallNode.java:318)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeCall(JSFunctionCallNode.java:263)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$InvokeNode.execute(JSFunctionCallNode.java:764)
at com.oracle.truffle.js.nodes.JavaScriptNode.executeVoid(JavaScriptNode.java:192)
at com.oracle.truffle.js.nodes.control.AbstractBlockNode.executeVoid(AbstractBlockNode.java:80)
at com.oracle.truffle.js.nodes.control.AbstractBlockNode.executeVoid(AbstractBlockNode.java:55)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedBlockNode.executeGeneric(OptimizedBlockNode.java:78)
at com.oracle.truffle.js.nodes.control.AbstractBlockNode.execute(AbstractBlockNode.java:75)
at com.oracle.truffle.js.nodes.binary.DualNode.execute(DualNode.java:119)
at com.oracle.truffle.js.nodes.function.FunctionBodyNode.execute(FunctionBodyNode.java:73)
at com.oracle.truffle.js.nodes.function.FunctionRootNode.executeInRealm(FunctionRootNode.java:156)
at com.oracle.truffle.js.runtime.JavaScriptRealmBoundaryRootNode.execute(JavaScriptRealmBoundaryRootNode.java:96)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:718)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:641)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:574)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:558)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callDirect(OptimizedCallTarget.java:504)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedDirectCallNode.call(OptimizedDirectCallNode.java:69)
at com.oracle.truffle.js.lang.JavaScriptLanguage$ParsedProgramRoot.execute(JavaScriptLanguage.java:248)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.executeRootNode(OptimizedCallTarget.java:718)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.profiledPERoot(OptimizedCallTarget.java:641)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callBoundary(OptimizedCallTarget.java:574)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.doInvoke(OptimizedCallTarget.java:558)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callIndirect(OptimizedCallTarget.java:486)
at jdk.internal.vm.compiler/org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.call(OptimizedCallTarget.java:467)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:1481)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotContextDispatch.eval(PolyglotContextDispatch.java:63)
... 6 more
Suppressed: Attached Guest Language Frames (4)
Suppressed: java.lang.UnsupportedOperationException: iterator
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invokeDefault(PolyglotFunctionProxyHandler.java:203)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotObjectProxyHandler.invoke(PolyglotObjectProxyHandler.java:108)
... 52 more
Caused by: java.lang.IllegalAccessException: no such method: java.util.Collection.iterator()Iterator/invokeSpecial
at java.base/java.lang.invoke.MemberName.makeAccessException(MemberName.java:972)
at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1117)
at java.base/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3649)
at java.base/java.lang.invoke.MethodHandles$Lookup.findSpecial(MethodHandles.java:2996)
at org.graalvm.truffle/com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invokeDefault(PolyglotFunctionProxyHandler.java:201)
... 53 more
Caused by: java.lang.AbstractMethodError: 'java.util.Iterator java.util.Collection.iterator()'
at java.base/java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.base/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
... 56 more
I am able to reproduce the missing conversion of JavaScript arrays to Java Collection. I agree that this is unfortunate. I have no idea why the corresponding code in truffle does not do that by default (considering that it is willing to convert arrays to Java List). The consequence is that methods like Collection.addAll()/Collections.min() do not work while methods that take List (like Collections.sort()) work fine.
You are right that you can add the missing conversion through a custom target type mapping. Personally, I would use
targetTypeMapping(Value.class, Collection.class, Value::hasArrayElements, v -> v.as(List.class))
I don't understand your troubles with errors. I don't see the relation to the mentioned target type mapping. Errors do not have array elements, so they should not be affected at all. I am afraid that I cannot help you without a reproducible test-case.
Versions
Graal Scripting Engine Setup
To run each script file I used the following:
JS Code Example
See MockClass:
Issue
Calling the .addAll() method on a Java HashSet in JavaScript with a JavaScript array as the parameter (See above code example) throws the exception:
See Stack Trace for more information.
The code example at the top works on Nashorn, and it appears the problem is with Graal not mapping the JavaScript Array to a Collection, which Set.addAll() requires [1].
Nashorn Scripting Engine Setup:
(OpenJDK 11.0.19)
As before, I ran the same script in the same way:
In Graal, I could get around this issue by adding explicit type maps [2]
This explicit mapping solution came from another issue [2]. Using this type map caused other problems as the type mapping is too generic and caught other data types.
JS Error object no longer being passable to the logger:
The issue is caused by the JSErrorObject being passed into a Java logger class method which does not have a method that takes JSErrorObject. I have been unable to find a way to map JSErrorObject to anything else, as it seems to be indistinguishable from an object. From my research, it seems we can’t directly reference JSErrorObject from truffle. Is there a way to explicitly map JSErrorObject to something else?
Is there a proper way to use JavaScript Arrays in Java methods requiring Collections as their parameters?
Stack Trace
[1] https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Set.html#addAll(java.util.Collection)
[2] #3 (comment)
The text was updated successfully, but these errors were encountered: