主机访问 GraalVM 中的 Clojure 对象

问题描述 投票:0回答:1

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 上下文中的对象方法

clojure clojure-java-interop graaljs
1个回答
0
投票

所以我找到了一种方法! 实现此目的的一种方法非常粗糙,有副作用,因为它会从执行的 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 [])))

不同之处在于我导入了注释并将 .(点)替换为 $(美元符号),并且它起作用了

© www.soinside.com 2019 - 2024. All rights reserved.