English 中文(简体)
clojure rmi classpath problem
原标题:

I am trying to use clojure to implement a "plugin" for some vendor supplied software.

Here is a little background on the vendor supplied software. It expects me to implement a particular interface and then put the jar file containing that implementation into a directory on its server. Then when a client runs the software, my implemented class gets "sent" to the client from the server via RMI and then my implementation of the interface runs on the client. The client doesn t have my jar file (or the clojure jar file) in it s classpath. Only the server has those jar files. RMI seems to be smart enough to upload whatever dependencies are necessary.

I have successfully built a very simple implementation in clojure and it seems to work. The problem is, I would like to be able to update my implementation on the client on the fly. I embedded a repl-server in my class and I can successfully connect to it. Just to be clear, the repl-server is running on the client and I am able to connect to the repl getting a prompt "clojure.core=>". However, the repl seems to be quite crippled. If I enter (+ 1 1) I get the following error: "java.lang.ClassNotFoundException: clojure.lang.Numbers". If enter (str "kent") I get "java.lang.NoClassDefFoundError: clojure/lang/ AFunction". Most things I enter produce something similar. I can however do a simple def such as (def x 3) and x does get defined so the REPL does seem to be running in some sense.

It seems like it might be a classpath problem, but I m not sure why my "compiled" code, running on the client would not have a classpath problem while the repl, running on the same client cant find core classes.

Any ideas?

Thanks. Kent.

问题回答

First of all, would it be possible to distribute clojure.jar as part of your RMI client? Based on your description of the vendor software, I m guessing the answer is no.

Second, is the contents of clojure.jar and your RMI object in the same jar file on the server, or are both in their own jar files?

It seems very likely that it s a classloader issue. In Clojure each defined function generates its own class file that Clojure then load via a specific class loader. IIRC each function is loaded by its own classloader instance in order to allow that function to be garbage collected in case it is redefined. Similarly, I think, RMI uses its own class loader to load remote RMI objects over the network. So possibly the two class loaders interact badly.

Sorry I can t be of more help...

-- Lauri





相关问题
How to improve Clojures error messages

I ve been playing a bit with Clojure and so far is fairly impressed, but one thing that I keep running into is wierd error messages from Clojure. This comes in two forms: Java errors, like null ...

clojure rmi classpath problem

I am trying to use clojure to implement a "plugin" for some vendor supplied software. Here is a little background on the vendor supplied software. It expects me to implement a particular interface ...

Help translating this Java codeblock to Clojure?

I m getting my feet wet with Clojure, and trying to get used to functional programming. I ve been translating various imperative functions from other languages into their Clojure equivalents -- and ...

Is functional Clojure or imperative Groovy more readable?

OK, no cheating now. No, really, take a minute or two and try this out. What does "positions" do? Edit: simplified according to cgrand s suggestion. (defn redux [[current next] flag] [(if flag ...

taking java method names as function arg in clojure

All, I want to create a function that takes a symbol representing a java method and applies it to some object: (user=> (defn f [m] (. "foo" (m))) When I execute this, I get a result much ...

how to efficiently apply a medium-weight function in parallel

I m looking to map a modestly-expensive function onto a large lazy seq in parallel. pmap is great but i m loosing to much to context switching. I think I need to increase the size of the chunk of work ...

热门标签