GraalVM下Java调用接收字节数组的JS函数报错如何解决
问题原因
你遇到的报错和参数无效问题由两个核心错误导致:
- 调用
context.eval执行JS文件时,函数定义语句的返回值为undefined,你将该返回值当做解码函数调用自然触发执行异常,需要从JS全局上下文主动获取定义好的lppDecode函数。 - 参数类型和内容不符合要求:你直接把十六进制字符串
getBytes()得到的是字符对应的ASCII字节,不是十六进制串对应的实际载荷字节;同时你传递了字符串类型给需要字节数组的lppDecode函数,类型不匹配。
调整后的代码
import org.apache.commons.codec.binary.Hex; // 用于十六进制串转字节数组,也可以自行实现转换逻辑 @Test public void testTestDecorder() throws Exception { // 初始化上下文,开启必要权限避免类型映射异常 Context context = Context.newBuilder("js") .allowAllAccess(true) .build(); String javaScriptDecoder = FileUtils.readFileToString(new File("src/main/resources/decoderOnly.js")); // 执行JS文件,将函数加载到全局上下文 context.eval("js", javaScriptDecoder); // 从全局作用域获取lppDecode函数对象 Value decodeFunction = context.getBindings("js").getMember("lppDecode"); // 把十六进制串转成实际的载荷字节数组 byte[] payloadBytes = Hex.decodeHex("016700E1027329EC038807FDD800BEE10000C8"); // 调用函数,GraalVM会自动将Java byte[]映射为JS可识别的字节类型 String json = decodeFunction.execute(payloadBytes).asString(); logger.debug(json); }
可选兼容方案
如果你的JS函数要求传入无符号数字数组而非字节数组,可以先对字节做无符号转换再传入:
Integer[] unsignedBytes = new Integer[payloadBytes.length]; for (int i = 0; i < payloadBytes.length; i++) { unsignedBytes[i] = payloadBytes[i] & 0xFF; } String json = decodeFunction.execute((Object) unsignedBytes).asString();
内容的提问来源于stack exchange,提问作者Jeryl Cook
相关产品推荐
相关产品推荐

