0

I have a Javascript file: https://gist.github.com/VanitySoft/0cfd26991fa9ac33e03782e4316695c2

// lppDecode decodes an array of bytes into an array of ojects, 
function lppDecode(bytes) {
  //...
}

In my Java test case, i'm trying to send an array of bytes:

@Test
public void testTestDecorder() throws IOException {
  Context context = Context.create();
  String javaSctiptDecorder = FileUtils.readFileToString(new File("src/main/resources/decoderOnly.js"));
  Value decodeFunction = context.eval("js", javaSctiptDecorder);
  byte[] bytes = "016700E1027329EC038807FDD800BEE10000C8".getBytes();
  String json = decodeFunction.execute(new String(bytes)).asString();
  logger.debug(json);       
}

But I keep getting an error:

java.lang.UnsupportedOperationException: Unsupported operation Value.execute(Object...) for 'undefined'(language: JavaScript, type: undefined). You can ensure that the operation is supported using Value.canExecute().
  at com.oracle.truffle.polyglot.PolyglotEngineException.unsupported(PolyglotEngineException.java:144)
  at com.oracle.truffle.polyglot.PolyglotValue.unsupported(PolyglotValue.java:620)
  at com.oracle.truffle.polyglot.PolyglotValue.executeUnsupported(PolyglotValue.java:263)
  at com.oracle.truffle.polyglot.PolyglotValue$InteropCodeCache$AbstractExecuteNode.executeShared(PolyglotValue.java:1906)
  at com.oracle.truffle.polyglot.PolyglotValue$InteropCodeCache$ExecuteNode.executeImpl(PolyglotValue.java:1978)
  at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:113)
  at com.oracle.truffle.api.impl.DefaultCallTarget.callDirectOrIndirect(DefaultCallTarget.java:84)
  at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:99)
  at com.oracle.truffle.api.impl.DefaultRuntimeAccessor$DefaultRuntimeSupport.callProfiled(DefaultRuntimeAccessor.java:119)
  at com.oracle.truffle.polyglot.PolyglotValue$InteropValue.execute(PolyglotValue.java:2787)
  at org.graalvm.polyglot.Value.execute(Value.java:457)
  at com.vanitysoft.nearsight.domain.dao.impl.GraavlTest.testTestDecorder(GraavlTest.java:44)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  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 org.junit.runner.JUnitCore.run(JUnitCore.java:115)
  at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:43)
  at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
  at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
  at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
  at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
  at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
  at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
  at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
  at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
  at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
  at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
  at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:82)
  at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:73)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
  at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
  at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
  at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:141)
  at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: Attached Guest Language Frames (1)

How can I get GraalVM to work with this byte array?

jccampanero
  • 50,989
  • 3
  • 20
  • 49
Jeryl Cook
  • 989
  • 17
  • 40

2 Answers2

1

Seems like you're missing parenthesis around your js code. I have kept spelling typos in variable names in your code as they are.

@Test
public void testTestDecorder() throws IOException {
    Context context = Context.create();
    String javaSctiptDecorder = FileUtils.readFileToString(new File("src/main/resources/decoderOnly.js"));
    javaSctiptDecorder = "(" + javaSctiptDecorder + ")";
    Value decodeFunction = context.eval("js", javaSctiptDecorder);
    byte[] bytes = "016700E1027329EC038807FDD800BEE10000C8".getBytes();
    String json = decodeFunction .execute(new String(bytes)).asString();
    logger.debug(json);     
}

Check out these official examples: 1 and 2
Notice the paranthesis around JS objects/functions.

Mythos
  • 1,378
  • 1
  • 8
  • 21
1

The problem is that in decoderFunction.js you are defining the named function lppDecode. In Javascript, this is considered a function declaration, a statement, and not an expression, and it cannot be evaluated by Graal.

The problem is described in this Github issue. alexjordan's in his answer provides the solution:

You need to add parentheses around it, otherwise a named function is considered a statement not an expression in JavaScript. (function test() { return 'Hello World' }) should work.

So, enclosing your function within parentheses, either in the original Javascript file, or when constructing your Java variables, as pointed out as well by Mythos in his answer, should work.

You can check the indicated behavior in a browser Javascript console. Try defining for instance the following:

function lppDecode(bytes) { console.log('Bytes:', bytes); return bytes;}

As a result, as indicated, the browser will print undefined:

named function declaration

On the contrary, if you enclose your function within parentheses:

(function lppDecode(bytes) { console.log('Bytes:', bytes); return bytes;})

you will receive a reference to the function instead:

function reference

that can be used directly:

use function expression

That is what Graal will do.

These great related references provide further information:

jccampanero
  • 50,989
  • 3
  • 20
  • 49