【问题标题】:Issues using a Java interface in Clojure在 Clojure 中使用 Java 接口的问题
【发布时间】:2015-02-14 08:02:34
【问题描述】:

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

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

当我严格按照教程操作时,我得到了 java.lang.ClassNotFoundException: stub.sayName,所以我尝试使用 reify 代替代理,但错误仍然存​​在。

目前我的代码如下:

对于接口: 包存根;

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 interface clojure interop


【解决方案1】:

好的,这些是你的问题:

  1. 你需要给java接口添加一个包名才能正常工作。再次阅读您的帖子时,我可以看到包名称,它没有被添加到代码块中......请参阅下面的 SayName.class 文件放置位置。
  2. 您需要根据您的代码更改java签名以取名字
  3. 您需要更改 reify 签名,以前的签名不起作用。首先结构错误,其次,reify 中的方法构造与 proxy 不同。对于 reify 形式,所有参数都需要引用一个照应“this”,我已将其替换为 _,因为它未在您的代码中使用。输入参数是表单中的第二个参数,您可以使用它来设置“Hallo, Welt”中的名称。
  4. 该类是 java.rmi.server.UnicastRemoteObject,而不是 java.rmi.server.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;
}

我编译了 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 是更好的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2016-04-26
    相关资源
    最近更新 更多