使用GraalVM Polyglot获取JS方法内变量为空的问题求助
如何在GraalVM ExecutionListener中获取JS方法内的局部变量?
问题描述
我在使用GraalVM Polyglot API调用JS模块时,尝试在ExecutionListener.onEnter中获取JS方法执行时的局部变量,但始终得到空集合。目前只能拿到export default中的成员,无法获取test方法内部的深层变量。
修正后的代码
package com.fbi.fvite; import org.graalvm.polyglot.*; import org.graalvm.polyglot.management.ExecutionListener; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; public class Test { private static Map<String, String> options = new HashMap<>(); public static void main(String[] args) { System.setProperty("polyglot.engine.WarnInterpreterOnly", "false"); // Enable CommonJS experimental support. options.put("js.commonjs-require", "true"); options.put("js.esm-eval-returns-exports", "true"); options.put("js.commonjs-require-cwd", "projects/" + CommAttr.projectId + "/src/modules"); // 开启JS调试支持 options.put("js.debug", "true"); Source js = null; try { js = Source.newBuilder("js",""" export default { /** * test method */ test(params) { const { hello, world } = params; var aaa = '123'; return { hello, world } } } """, "test.mjs" ).mimeType("application/javascript+module").build(); } catch (IOException e) { throw new RuntimeException(e); } try(Context context = Context.newBuilder() .allowAllAccess(true) .options(options) .allowExperimentalOptions(true) .allowIO(true) .allowDebugging(true) // 允许访问调试API .build()){ Value fun = context.eval(js).getMember("default").getMember("test"); ExecutionListener listener = ExecutionListener.newBuilder() .onEnter((e) -> { // 获取当前执行栈帧 Frame frame = e.getFrame(); if (frame != null) { Map<String, Object> variables = new HashMap<>(); // 遍历栈帧中的局部变量 for (String varName : frame.getVariableNames()) { Value varValue = frame.getVariable(varName); // 区分宿主对象和JS原生值,按需转换 variables.put(varName, varValue.isHostObject() ? varValue.asHostObject() : varValue.toString()); } SourceSection section = e.getLocation(); System.out.println("line: " + section.getStartLine() + ", code: " + section.getCharacters() + ", variables: " + variables); } }) .statements(true) .collectInputValues(true) .attach(context.getEngine()); Value value = fun.execute(Map.of("hello", "world")); System.out.println("完毕,返回值:" + value); listener.close(); } } }
关键修正说明
启用调试配置
- 添加
js.debug=true选项开启JS调试支持 - 构建Context时调用
.allowDebugging(true),允许访问栈帧等调试相关API
- 添加
正确获取局部变量
- 不再从JS函数对象
fun中取成员,而是通过ExecutionEvent.getFrame()获取当前执行的栈帧 - 利用
Frame.getVariableNames()遍历局部变量名,再通过Frame.getVariable(varName)获取对应变量值
- 不再从JS函数对象
变量值处理
- 区分宿主对象和JS原生值,按需转换为Java对象或字符串,方便查看输出
内容的提问来源于stack exchange,提问作者shengkai guo
相关产品推荐
相关产品推荐

