Clojure中使用Java接口的问题

Clojure中使用Java接口的问题,java,interface,clojure,interop,Java,Interface,Clojure,Interop,我一直在关注使用clojure的分布式RMI教程,但它似乎已经过时,我无法让它工作: 当我严格遵循教程时,我得到了一个java.lang.ClassNotFoundException:stub.sayName,所以我尝试使用reify而不是proxy,但错误仍然存在 到目前为止,我的代码如下: 对于接口: 包装存根 import java.rmi.Remote; import java.rmi.RemoteException; public interface sayName extends

我一直在关注使用clojure的分布式RMI教程,但它似乎已经过时,我无法让它工作:

当我严格遵循教程时,我得到了一个java.lang.ClassNotFoundException:stub.sayName,所以我尝试使用reify而不是proxy,但错误仍然存在

到目前为止,我的代码如下:

对于接口: 包装存根

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface sayName extends Remote {
      String Name() throws RemoteException;
}
对于我的主要clojure课程:

(ns immutability.core
  (:gen-class))

(defn -main
  [& args]
  (println "Hello, World!"))
(def rmi-registry
  (java.rmi.registry.LocateRegistry/createRegistry 1099))

(defn name-server []
  (reify stub.sayName Name
    (Name [personname] "Hello, " + personname)))

(defn register-server []
  (.bind
   (java.rmi.registry.LocateRegistry/getRegistry)
   "Hello"
   (java.rmi.server.UnicastRemote/exportObject
    (name-server) 0)))
(register-server)

我肯定这是件愚蠢的小事,但我能想出来的

好吧,这些是你的问题:

您需要向java接口添加一个包名,以使其正常工作。再次阅读您的帖子时,我可以看到包名,它没有添加到代码块中。。。请参见下面的SayName.class文件的放置位置。 您需要根据代码更改java签名以获取名称 您需要更改具体化签名,您以前使用的签名无法使用。第一,结构错误,第二,方法结构在具体化上与代理不同。对于具体化形式,所有参数都需要引用回指“this”,我已将其替换为u,因为它不在代码中使用。输入参数是表单中的第二个参数,这就是您可以用来在Hallo,Welt中设置名称的参数。 该类是java.rmi.server.UnicastRemote对象,而不是java.rmi.server.UnicastRemote,正如您在原始代码中看到的那样。 在clojure中将服务器符号定义为defonce并不是一个真正的错误,但很好,因为服务器已经定义好了,所以在尝试重新评估文件时不会出现端口冲突。 发布这些更改后,代码将编译,并且似乎正在做它应该做的事情。我停止调用RPI调用

接口代码:

package stub;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface SayName extends Remote {
      String name(String n) throws RemoteException;
}
我将stub.SayName接口编译并存储在target/classes/stub/SayName.class中。它位于类路径上,在repl启动时相对于project.clj文件找到

clojure代码:

(ns immutability.core
  (:gen-class))

(defn -main
  [& args]
  (println "Hello, World!"))

(defonce rmi-registry (java.rmi.registry.LocateRegistry/createRegistry 1099))

(defn name-server []
  (reify stub.SayName
    (name [_ n] (str "Hello " n))))

(defn register-server []
  (.bind
   (java.rmi.registry.LocateRegistry/getRegistry)
   "Hello"
   (java.rmi.server.UnicastRemoteObject/exportObject
    (name-server) 0)))

(register-server)

最后一件事,请注意,您不希望在代码中直接留下类似register server的调用,因为编译时会调用它。将其注释掉,或者将其保留给REPL是更好的方法。

您将存根文件夹放在类路径的何处?问题自那时起已得到解决