我正在尝试使用 clojure 为某些供应商实现“插件” 提供的软件。
以下是有关供应商提供的软件的一些背景信息。它 期望我实现一个特定的接口(interface),然后放入 jar 将包含该实现的文件保存到其服务器上的目录中。 然后,当客户端运行该软件时,我实现的类被“发送” 通过 RMI 从服务器到客户端,然后我的实现 该接口(interface)在客户端上运行。客户端没有我的jar文件 (或 clojure jar 文件)在它的类路径中。只有服务器有 那些 jar 文件。 RMI 似乎足够聪明,可以上传任何内容 依赖关系是必要的。
我已经在 clojure 中成功构建了一个非常简单的实现,并且 似乎有效。问题是,我希望能够更新我的 在客户端上即时实现。我嵌入了一个repl-server 我和我的类(class)可以成功连接到它。需要明确的是, repl-server 正在客户端上运行,我能够连接到 repl 收到提示“clojure.core=>”。然而,repl 似乎是 相当残废。如果我输入 (+ 1 1) 我会收到以下错误: “java.lang.ClassNotFoundException:clojure.lang.Numbers”。如果输入 (str“kent”)我得到“java.lang.NoClassDefFoundError:clojure/lang/ AFunction"。我输入的大多数内容都会产生类似的结果。我可以 然而,做一个简单的 def 例如 (def x 3) 并且 x 确实被定义了 从某种意义上说,REPL 似乎确实在运行。
看起来这可能是一个类路径问题,但我不确定为什么我的 “编译”代码,在客户端上运行不会有类路径 在同一客户端上运行的 repl 无法找到核心时出现问题 类。
有什么想法吗?
谢谢。 肯特。
最佳答案
首先,是否可以将 clojure.jar 作为 RMI 客户端的一部分进行分发?根据您对供应商软件的描述,我猜答案是否定的。
第二,clojure.jar 和 RMI 对象的内容是在服务器上的同一个 jar 文件中,还是都在它们自己的 jar 文件中?
这似乎很可能是类加载器问题。在 Clojure 中,每个定义的函数都会生成自己的类文件,然后 Clojure 通过特定的类加载器加载该类文件。 IIRC 每个函数都由其自己的类加载器实例加载,以便在重新定义该函数时允许垃圾收集该函数。同样,我认为,RMI 使用自己的类加载器通过网络加载远程 RMI 对象。因此这两个类加载器可能交互不良。
抱歉,我无法提供更多帮助...
--劳里
关于Clojure RMI类路径问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1746026/