有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Clojure中使用Java接口的问题

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

http://nakkaya.com/2009/12/05/distributed-clojure-using-rmi/

我得到了一个java。lang.ClassNotFoundException:存根。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)

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


共 (1) 个答案

  1. # 1 楼答案

    好的,这些是你的问题:

    1. 您需要在java接口中添加一个包名,它才能正常工作。再次阅读您的帖子时,我可以看到包名,它没有添加到代码块中。。。请参见下面的“姓名”放置位置。类文件
    2. 您需要根据代码更改java签名以获取名称
    3. 您需要更改“具体化”签名,之前的签名无法使用。首先,结构是错误的,其次,方法结构在具体化上与代理不同。对于具体化形式,所有参数都需要引用回指“this”,我已将其替换为u,因为它不在代码中使用。输入参数是表单中的第二个参数,您可以使用它来设置“你好,欢迎”中的名称
    4. 这个类是java。rmi。服务器UnicastRemoteObject,而不是java。rmi。服务器UnicastRemote,就像你原来的代码一样
    5. 在clojure中将服务器符号定义为defonce并不是一个真正的错误,但很好,这样当您尝试重新评估文件时,就不会出现端口冲突,因为服务器已经定义好了

    在发布这些更改后,代码将进行编译,并且似乎正在做它应该做的事情。我停止调用RPI调用

    接口代码:

    package stub;
    
    import java.rmi.Remote;
    import java.rmi.RemoteException;
    
    public interface SayName extends Remote {
          String name(String n) throws RemoteException;
    }
    

    我编译并存储了存根。target/classes/stub/SayName中的SayName接口。班它位于类路径上,在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是更好的方法