GraalJS 主机访问文档指出,添加注释就足够了
@HostAccess.Export
我的代码如下所示:
(ns graaljs.core
(:gen-class)
(:import (org.graalvm.polyglot Context)))
(definterface SampleAdapter (getData []))
(deftype AdapterInstance [documents]
SampleAdapter
(^{HostAccess.Export true}
getData
[this]
documents))
(let [js-code (format "(%s)" (slurp "./js/js-java-object-parser.js"))
adapter (AdapterInstance. "wo")
context (Context/create (into-array ["js"]))
_ (-> context
(.getBindings "js")
(.putMember "adapter" adapter))
js-evaluated-code (.eval context "js" js-code)]
(.execute js-evaluated-code (into-array [])))
我正在执行的JS是这个:
function parserFunction() {
console.log('foo')
console.log(adapter.getData())
console.log("this works")
}
在评估代码时我没有遇到任何问题,但是当我运行 JS 代码时,我在 REPL 中收到以下错误
foo
;
; Syntax error (PolyglotException) compiling at (C:\ZigiOps\graaljs\src\graaljs\core.clj:14:1).
; TypeError: invokeMember (getData) on graaljs.core.AdapterInstance failed due to: Unknown identifier: getData
; Evaluation of file core.clj failed: class clojure.lang.Compiler$CompilerException
由于某种原因我无法访问 JS 上下文中的对象方法
所以我找到了一种方法! 实现此目的的一种方法非常粗糙,有副作用,因为它会从执行的 JS 代码中提供对环境的各种不必要的访问,即调用您正在创建的
context的
(.allowAllAccess true)
方法
(-> context
(.getBindings "js")
(.putMember "adapter" adapter))
但正如前面提到的,这有副作用检查这里
更优雅的解决方法是修复注释。花了很长时间才找到它,由于某种未知的原因,关于如何在 clojure 中正确注释的讨论很少。 这是工作代码:
(ns graaljs.core
(:gen-class)
(:import (org.graalvm.polyglot Context HostAccess$Export)))
(definterface SampleAdapter (getData []))
(deftype AdapterInstance [documents]
SampleAdapter
(^{HostAccess$Export true}
getData
[this]
documents))
(let [js-code (format "(%s)" (slurp "./js/js-java-object-parser.js"))
adapter (AdapterInstance. "wo")
context (Context/create (into-array ["js"]))
_ (-> context
(.getBindings "js")
(.putMember "adapter" adapter))
js-evaluated-code (.eval context "js" js-code)]
(.execute js-evaluated-code (into-array [])))
不同之处在于我导入了注释并将 .(点)替换为 $(美元符号),并且它起作用了