如何通过GraalVM在Java环境中正确执行发起REST请求的JavaScript代码
如何通过GraalVM在Java环境中正确执行发起REST请求的JavaScript代码
看起来你遇到的问题根源在于:GraalVM默认的JavaScript运行环境既不是浏览器(没有XHR API),也不是完整的Node.js环境(缺少http模块支持),导致axios找不到合适的网络适配器来发起请求。下面给你两种实用的解决思路:
方法一:直接在JS中调用Java的HTTP客户端(推荐)
这种方法利用GraalVM的多语言互操作性,直接复用Java标准库的HTTP客户端,不需要依赖axios,兼容性和稳定性更好。
修改后的JavaScript代码
// 导入Java标准库中的HTTP相关类 const HttpClient = Java.type("java.net.http.HttpClient"); const HttpRequest = Java.type("java.net.http.HttpRequest"); const HttpResponse = Java.type("java.net.http.HttpResponse"); const URI = Java.type("java.net.URI"); const API_URL = "https://jsonplaceholder.typicode.com/posts"; const fetchPosts = () => { try { // 创建HTTP客户端实例 const client = HttpClient.newHttpClient(); // 构建GET请求 const request = HttpRequest.newBuilder() .uri(new URI(API_URL)) .GET() .build(); // 发送请求并获取响应 const response = client.send(request, HttpResponse.BodyHandlers.ofString()); // 解析JSON响应 const posts = JSON.parse(response.body()); console.log("Posts:", posts); } catch (error) { console.error("Error fetching posts:", error); } }; fetchPosts();
对应的Java代码
你的原有Java代码不需要做太多修改,直接读取并执行这段JS即可,无需打包axios等依赖:
public static void main( String[] args ) { String jscode = null; try { jscode = new String(Files.readAllBytes(Paths.get("/tmp/main.js"))); } catch (IOException e) { throw new RuntimeException(e); } try (Context context = Context.create()) { Value value = context.eval("js", jscode); value.execute(); } }
方法二:配置GraalVM启用Node.js兼容层(若坚持使用axios)
如果你一定要继续使用axios,需要让GraalVM模拟Node.js环境,同时确保axios的打包包含http适配器:
修改Java代码
创建Context时启用Node.js代理模式,并开放必要权限:
try (Context context = Context.newBuilder("js") .allowAllAccess(true) .option("js.nodeproxy", "true") .build()) { Value value = context.eval("js", jscode); value.execute(); }
注意事项
- 确保你的axios打包产物中包含了Node.js的http适配器(默认打包可能会剔除,需要调整打包配置)
- 这种方式需要GraalVM支持Node.js兼容,可能会引入额外的依赖和性能开销,不如方法一简洁高效
备注:内容来源于stack exchange,提问作者Aswath Murugan




