You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraalVM中JS无法访问Clojure对象方法的问题求助

解决GraalJS无法访问Clojure对象方法的方案

问题根源

  1. 未正确导入HostAccess类,导致@HostAccess.Export注解未被GraalVM识别
  2. Context未配置允许宿主访问的策略,默认策略限制了方法访问
  3. 注解元数据未被正确传递到Java字节码层面

具体修复步骤

1. 导入HostAccess类

修改命名空间部分,补充HostAccess的导入:

(ns graaljs.core
  (:gen-class)
  (:import (org.graalvm.polyglot Context HostAccess)))

2. 配置Context的HostAccess策略

创建Context时显式允许宿主访问权限,确保GraalJS能识别导出的方法:

(let [js-code (format "(%s)" (slurp "./js/js-java-object-parser.js"))
      adapter (AdapterInstance. "wo")
      context (-> (Context/newBuilder (into-array ["js"]))
                  ;; 允许所有宿主访问操作,也可按需自定义策略
                  (.allowHostAccess HostAccess/ALL)
                  (.build))
      _ (-> context
            (.getBindings "js")
            (.putMember "adapter" adapter))
      js-evaluated-code (.eval context "js" js-code)]
  (.execute js-evaluated-code (into-array [])))

3. 确保注解正确应用

确认deftype中的方法注解写法无误,保证HostAccess.Export元数据关联到目标方法:

(definterface SampleAdapter (getData []))

(deftype AdapterInstance [documents] 
  SampleAdapter
  (^{HostAccess.Export true} 
    getData  
    [this]
    documents))

4. 可选方案:改用Java类(若Clojure类型仍有问题)

如果deftype生成的类存在注解传递问题,可直接定义Java类:

import org.graalvm.polyglot.HostAccess;

public class JavaAdapter {
    private final String documents;

    public JavaAdapter(String documents) {
        this.documents = documents;
    }

    @HostAccess.Export
    public String getData() {
        return documents;
    }
}

在Clojure中导入并使用该类:

(import your.package.JavaAdapter)
;; 其余代码不变,替换adapter实例为JavaAdapter
(let [adapter (JavaAdapter. "wo")
      ;; ...
      ])

验证修复

运行修改后的代码,JS中的adapter.getData()将正常返回"wo",控制台输出:

foo
wo
this works

内容的提问来源于stack exchange,提问作者yuner.bekir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 22:23:17