Finally managed to reproduce this issue 100% of the time.
Here is the reproducer:
import org.graalvm.polyglot.*;
import org.junit.Test;
public class GraalJSReproducer {
@Test
public void test() {
//@language=js
String script =
"const Logger = Java.type('java.util.logging.Logger');\n" +
"const Level = Java.type('java.util.logging.Level');\n" +
"\n" +
"const log = Logger.getLogger('es4x');\n";
try (Context context = Context.newBuilder("js")
.allowHostClassLookup(fqcn -> true)
.allowHostAccess(
HostAccess.newBuilder(HostAccess.ALL)
.targetTypeMapping(
Value.class,
Throwable.class,
it -> true,
it -> null)
.build())
.build()) {
context.eval(
Source.newBuilder(
"js",
script,
"script.js").buildLiteral());
// failure
context.eval(
Source.newBuilder(
"js",
"log.log(Level.INFO, 'some text', [])",
"script.js").buildLiteral());
}
}
}
The issue seems to be related to the targetTypeMapping. The mapping is not doing anything as it reproduces the issue 100% of the time, the goal of such mapping is to allow converting from JS errors (which can be Error classes, or Objects with a name and a (optional) message field).
In this example using graaljs 20.0.0 or 20.1.0-dev I always get the exception:
org.graalvm.polyglot.PolyglotException: java.lang.AssertionError: Invalid libray usage. Cached library must be adopted by a RootNode before it is executed.
at com.oracle.truffle.api.object.DynamicObjectGen$DynamicDispatchLibraryExports$Cached.dispatch(DynamicObjectGen.java:152)
at com.oracle.truffle.js.runtime.builtins.JSClassGen$InteropLibraryExports$Cached.accepts(JSClassGen.java:116)
at com.oracle.truffle.api.interop.InteropLibrary$Asserts.accepts(InteropLibrary.java:1238)
at com.oracle.truffle.polyglot.ToHostNodeGen.execute(ToHostNodeGen.java:45)
at com.oracle.truffle.polyglot.TargetMappingNode$SingleMappingNode.doDefault(TargetMappingNode.java:145)
at com.oracle.truffle.polyglot.TargetMappingNodeGen$SingleMappingNodeGen.execute(TargetMappingNodeGen.java:159)
at com.oracle.truffle.polyglot.HostExecuteNode$TargetMappingType.execute(HostExecuteNode.java:898)
at com.oracle.truffle.polyglot.HostExecuteNode.checkArgTypes(HostExecuteNode.java:351)
at com.oracle.truffle.polyglot.HostExecuteNodeGen.executeAndSpecialize(HostExecuteNodeGen.java:213)
at com.oracle.truffle.polyglot.HostExecuteNodeGen.executeImpl(HostExecuteNodeGen.java:96)
at com.oracle.truffle.polyglot.HostExecuteNode.execute(HostExecuteNode.java:94)
at com.oracle.truffle.polyglot.HostObject.invokeMember(HostObject.java:386)
at com.oracle.truffle.polyglot.HostObjectGen$InteropLibraryExports$Cached.invokeMemberNode_AndSpecialize(HostObjectGen.java:1313)
at com.oracle.truffle.polyglot.HostObjectGen$InteropLibraryExports$Cached.invokeMember(HostObjectGen.java:1288)
at com.oracle.truffle.api.interop.InteropLibrary$Asserts.invokeMember(InteropLibrary.java:1651)
at com.oracle.truffle.api.interop.InteropLibraryGen$CachedDispatch.invokeMember(InteropLibraryGen.java:4256)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$ForeignInvokeNode.executeCall(JSFunctionCallNode.java:1466)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeAndSpecialize(JSFunctionCallNode.java:292)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeCall(JSFunctionCallNode.java:238)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$InvokeNode.execute(JSFunctionCallNode.java:710)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute_generic4(JSWriteCurrentFrameSlotNodeGen.java:177)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute(JSWriteCurrentFrameSlotNodeGen.java:93)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.executeVoid(JSWriteCurrentFrameSlotNodeGen.java:343)
at com.oracle.truffle.js.nodes.binary.DualNode.execute(DualNode.java:121)
at com.oracle.truffle.js.nodes.function.FunctionBodyNode.execute(FunctionBodyNode.java:73)
at com.oracle.truffle.js.nodes.function.FunctionRootNode.executeInRealm(FunctionRootNode.java:147)
at com.oracle.truffle.js.runtime.JavaScriptRealmBoundaryRootNode.execute(JavaScriptRealmBoundaryRootNode.java:93)
at <js> :program(Unknown)
at org.graalvm.polyglot.Context.eval(Context.java:345)
at io.reactiverse.es4x.test.GraalJSReproducer.test(GraalJSReproducer.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Original Internal Error:
java.lang.AssertionError: Invalid libray usage. Cached library must be adopted by a RootNode before it is executed.
at com.oracle.truffle.api.object.DynamicObjectGen$DynamicDispatchLibraryExports$Cached.dispatch(DynamicObjectGen.java:152)
at com.oracle.truffle.js.runtime.builtins.JSClassGen$InteropLibraryExports$Cached.accepts(JSClassGen.java:116)
at com.oracle.truffle.api.interop.InteropLibrary$Asserts.accepts(InteropLibrary.java:1238)
at com.oracle.truffle.polyglot.ToHostNodeGen.execute(ToHostNodeGen.java:45)
at com.oracle.truffle.polyglot.TargetMappingNode$SingleMappingNode.doDefault(TargetMappingNode.java:145)
at com.oracle.truffle.polyglot.TargetMappingNodeGen$SingleMappingNodeGen.execute(TargetMappingNodeGen.java:159)
at com.oracle.truffle.polyglot.HostExecuteNode$TargetMappingType.execute(HostExecuteNode.java:898)
at com.oracle.truffle.polyglot.HostExecuteNode.checkArgTypes(HostExecuteNode.java:351)
at com.oracle.truffle.polyglot.HostExecuteNodeGen.executeAndSpecialize(HostExecuteNodeGen.java:213)
at com.oracle.truffle.polyglot.HostExecuteNodeGen.executeImpl(HostExecuteNodeGen.java:96)
at com.oracle.truffle.polyglot.HostExecuteNode.execute(HostExecuteNode.java:94)
at com.oracle.truffle.polyglot.HostObject.invokeMember(HostObject.java:386)
at com.oracle.truffle.polyglot.HostObjectGen$InteropLibraryExports$Cached.invokeMemberNode_AndSpecialize(HostObjectGen.java:1313)
at com.oracle.truffle.polyglot.HostObjectGen$InteropLibraryExports$Cached.invokeMember(HostObjectGen.java:1288)
at com.oracle.truffle.api.interop.InteropLibrary$Asserts.invokeMember(InteropLibrary.java:1651)
at com.oracle.truffle.api.interop.InteropLibraryGen$CachedDispatch.invokeMember(InteropLibraryGen.java:4256)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$ForeignInvokeNode.executeCall(JSFunctionCallNode.java:1466)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeAndSpecialize(JSFunctionCallNode.java:292)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode.executeCall(JSFunctionCallNode.java:238)
at com.oracle.truffle.js.nodes.function.JSFunctionCallNode$InvokeNode.execute(JSFunctionCallNode.java:710)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute_generic4(JSWriteCurrentFrameSlotNodeGen.java:177)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.execute(JSWriteCurrentFrameSlotNodeGen.java:93)
at com.oracle.truffle.js.nodes.access.JSWriteCurrentFrameSlotNodeGen.executeVoid(JSWriteCurrentFrameSlotNodeGen.java:343)
at com.oracle.truffle.js.nodes.binary.DualNode.execute(DualNode.java:121)
at com.oracle.truffle.js.nodes.function.FunctionBodyNode.execute(FunctionBodyNode.java:73)
at com.oracle.truffle.js.nodes.function.FunctionRootNode.executeInRealm(FunctionRootNode.java:147)
at com.oracle.truffle.js.runtime.JavaScriptRealmBoundaryRootNode.execute(JavaScriptRealmBoundaryRootNode.java:93)
at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:85)
at com.oracle.truffle.api.impl.DefaultDirectCallNode.call(DefaultDirectCallNode.java:59)
at com.oracle.truffle.js.lang.JavaScriptLanguage$1.execute(JavaScriptLanguage.java:228)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:102)
at com.oracle.truffle.polyglot.PolyglotContextImpl.eval(PolyglotContextImpl.java:822)
at org.graalvm.polyglot.Context.eval(Context.java:345)
at io.reactiverse.es4x.test.GraalJSReproducer.test(GraalJSReproducer.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Caused by: Attached Guest Language Frames (2)
Related to #170
Some more debug. If the script to be executed is:
context.eval(
Source.newBuilder(
"js",
"log.log(Level.INFO, 'some text')",
"script.js").buildLiteral());
Note that I'm now calling the logger with just 2 arguments, then it's fine. I see:
java -ea GraalJSReproducer
Apr 24, 2020 1:55:03 PM com.oracle.truffle.polyglot.HostMethodDesc$SingleMethod$MHBase invokeHandle
INFO: some text
So it seems to be a mix of the fact that I'm calling a java method with varargs (maybe?) + there is a typeMapping in place.
Here is my reproducer using SL:
public class Test {
@Export
public static String log(String msg, Throwable thrown) {
return "log1";
}
@Export
public static String log(Throwable thrown, String msgSupplier) {
return "log2";
}
@Test
public void test() {
try (Context context = Context.newBuilder().allowHostAccess(
HostAccess.newBuilder(HostAccess.EXPLICIT).targetTypeMapping(
Value.class,
Throwable.class,
it -> true,
it -> null).build()).build()) {
/*
* SL objects are dynamically dispatched and trigger this error.
*/
Value slObj = context.getBindings(SLLanguage.ID).getMember("new").execute();
Value staticClass = context.asValue(GR22815Test.class).getMember("static");
Assert.assertEquals("log1", staticClass.invokeMember("log", "some text", slObj).asString());
}
}
}
Fix is in the pipeline.
Will be fixed for 20.2.0. Backported to 19.3.3 and 20.1.0
Fixed: https://github.com/oracle/graal/commit/3b7594d09ba8f55a239801d981ca30a3d38118a8
Should be available in 20.2 nightly tomorrow.