We're migrating legacy code from Nashorn to Graal.js, and facing issues with how numeric values are mapped internally. In Nashorn, large numbers like 15-digit integers were mapped to java.lang.Double. Now, with Graal.js, those are being interpreted as SafeInteger, which implements TruffleObject.
This breaks the following assertion in our polyglot interop logic:
assert !(result instanceof TruffleObject); What’s confusing is that this assertion fails during TestNG tests, but passes when run as a standalone Java application — the returned value is a SafeInteger in standalone and gets null when in test environment.
Here’s a simplified test case:
@Test
public static void test() throws ScriptException {
Scope scope = ScriptManager.createScope();
String test = "314159265358979";
scope.setValue(new Variable("maxPrecisionJavascript", DataType.NUMBER), test);
Expression expr1 = ScriptManager.createExpression("result = maxPrecisionJavascript;");
expr1.eval(scope);
String actual = scope.getValueAsString("result");
System.out.println("Result: " + actual);
}
This test results in a java.lang.AssertionError in HostToGuestRootNode.java when run in the test environment at scope.getValueAsString("result")
Here’s the full stack trace:
org.graalvm.polyglot.PolyglotException: java.lang.AssertionError
at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:125)
...
at com.tibco.bpm.se.core.test.GraalTest.test(GraalTest.java:56)
Caused by: java.lang.AssertionError
at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:125)
Question:
Why does SafeInteger (a TruffleObject) cause the !(result instanceof TruffleObject) assertion to fail in the test environment but not in the standalone app — even though the object appears to be the same? Are there any known differences in Graal.js behavior or polyglot engine setup between test (e.g. TestNG) and runtime environments? and How to solve for Large Number.
-enableassertions
(short form:-ea
)?ScriptManager
,Expression
orVariable
come from. Also your "full stack trace" is not full at all. It contains just two stack-frames.