2024 年 Clojure 工作状态调查 中分享您的想法!

欢迎!请查看 关于页面 了解更多关于如何使用本站的信息。

0
REPL

嗨!
我正在使用 clojure+nrepl 开发一个插件。
项目 gradle 依赖项

dependencies {
    implementation("org.clojure:clojure:1.10.0")
    implementation("nrepl:nrepl:1.0.0")
}

当我调用时,我得到 FileNotFoundException 异常

RT.var("clojure.core", varName)

错误在哪里?
谢谢!

1 个答案

+1

被选中
 
最佳答案

RT 是一个内部实现类。

Clojure 的 Java API 在 https://clojure.github.io/clojure/javadoc/clojure/java/api/package-summary.html

感谢你的帮助。
我已经阅读了Clojure的Java API。当调用
Clojure.var("clojure.core", "+")时,它抛出了相同的异常。
我通过以下方法解决了问题:
Thread.currentThread().setContextClassLoader()
可能是因为IDEA插件的运行环境特殊。
再次感谢
嗨,alexmiller。
我该如何使用Java API为Clojure创建一个nrepl客户端?
我不能将Clojure代码转换为Java代码,例如

=> (require '[nrepl.core :as nrepl])
nil
=> (with-open [conn (nrepl/connect :port 59258)])
     (-> (nrepl/client conn 1000)
         (nrepl/message {:op "eval" :code "(time (reduce + (range 1e6)))"})
         doall      ;; `message` and `client-session` all return lazy seqs
         pprint)
对于任何Clojure变量,您将使用Clojure.var()来获取其引用,然后在其上调用invoke()。对于类似消息的文本,您可以使用Clojure.read()从字符串中读取Clojure数据,或者使用构造函数如hash-map。with-open是一个宏,但在这种情况下,它基本上是在模仿Java中的try-with-resources能做到的,所以您实际上不需要它。->将需要展开,或者您可以将更多的代码放入一个Clojure函数中,然后直接调用它。

我还没有编译这个代码,但最终你会得到类似以下内容的代码:

```

private static final IFn require = Clojure.var("clojure.core", "require");
private static final IFn doall = Clojure.var("clojure.core", "doall");

private static final Object portKW = Clojure.read(":port");
private static final Object opKW = Clojure.read(":op");
private static final Object codeKW = Clojure.read(":code");

private static final IFn connect;
private static final IFn client;
private static final IFn message;

static {
  require.invoke(Clojure.read("nrepl.core"));
  connect = Clojure.var("nrepl.core", "connect");
  client = Clojure.var("nrepl.core", "client");
  message = Clojure.var("nrepl.core", "message");
}

public 对象 getConnection(int 端口) {
   return connect.invoke(portKW, 端口);
}

public 对象 getClient(对象 conn, int 超时) {
  return client.invoke(conn, 超时);
}

public 对象 send(对象 client, 对象 message) {
  对象 result = message.invoke(client, message);
  return doall.invoke(result);
}
```

然后


```
try (对象 conn = getConnection(59258)) {
  对象 client = getClient(conn, 1000);
  对象 result = send(client, Map.of(opKW, "eval", codeKW, "(time (reduce + (range 1e6)))"));
  // result here is a map, do what you want with it
}
```
by
edited by
谢谢,它成功连接了,  有一些小的修改

public 静态 IPersistentMap evalCodeMap() {
        Map map = Maps.newHashMap();
        map.put(Clojure.read(":op"), Clojure.read("eval"));
        map.put(Clojure.read(":code"), Clojure.var("clojure.core", "eval").invoke("(+ 1 2)"));
        return PersistentHashMap.create(map);
    }

Clojure.var("nrepl.core", "message").invoke(client , evalCodeMap())

BTW,Clojure代码看起来更简单。
是先用Clojure编程,然后再调用Java中的Clojure?如何操作?gen-class还是require namespace?
...