我正在尝试使用clojure为某些供应商实现“插件” 提供的软件。
以下是供应商提供的软件的一些背景知识。它 我希望我实现一个特定的接口,然后放入jar 包含该实现的文件到其服务器上的目录中。 然后当客户端运行该软件时,我实现的类被“发送” 通过RMI从服务器到客户端然后我执行 接口在客户端上运行。客户端没有我的jar文件 (或clojure jar文件)在它的classpath中。只有服务器有 那些jar文件。 RMI似乎足够智能上传任何东西 依赖是必要的。
我已经在clojure中成功构建了一个非常简单的实现 它似乎工作。问题是,我希望能够更新我的 在客户端上实现实现。我嵌入了一个repl-server 我的班级和我可以成功连接到它。只是为了清楚, repl-server正在客户端上运行,我可以连接到 repl得到提示“clojure.core =>”。然而,repl似乎是 相当残废。如果我输入(+ 1 1)我收到以下错误: “java.lang.ClassNotFoundException:clojure.lang.Numbers”。如果输入 (str“kent”)我得到“java.lang.NoClassDefFoundError:clojure / lang / 功能“。我输入的大多数东西产生类似的东西。我可以 然而,做一个简单的def,如(def x 3)和x确实如此定义 从某种意义上说,REPL确实在运行。
似乎它可能是一个类路径问题,但我不确定为什么我的 在客户端上运行的“编译”代码不会有类路径 在同一客户端上运行的repl找不到核心问题 类。
有什么想法吗?
感谢。 肯特。
答案 0 :(得分:2)
首先,是否可以将clojure.jar作为RMI客户端的一部分进行分发?根据您对供应商软件的描述,我猜测答案是否定的。
第二,clojure.jar和你的RMI对象的内容是在服务器上的同一个jar文件中,还是都在自己的jar文件中?
它似乎很可能是一个类加载器问题。在Clojure中,每个定义的函数都会生成自己的类文件,然后Clojure通过特定的类加载器加载。 IIRC每个函数都由它自己的类加载器实例加载,以便在重新定义时允许对该函数进行垃圾收集。同样,我认为,RMI使用自己的类加载器通过网络加载远程RMI对象。所以两个类加载器可能会相互影响很糟糕。
抱歉,我无法提供更多帮助......
- 劳里