(I'm aware this is related to How can I embed Clojure in an RCP application, but that thread is old and my setup is somewhat different)
I'm using Eclipse 3.7.1 and for days now have been trying to write an Eclipse/RCP app in Clojure (as much as possible). I've tried building the source version of clojure.osgi and CCW, have tried the RCPClojure demo project and several other things. Each one of them didnt work (mainly seemingly "unfixable" build/classpath errors, lack of up-to-date docs/response, version conflicts etc...)
My own steps to bring me at least 50% success:
Create a new plugin project wrapping the Clojure 1.3.0 jar file, set plugin ID org.clojure.v1.3.0
Create a new plugin project org.cljtest42
using RCP Hello template
org.clojure
plugin dependency/classes
folderplugin.xml
to add /classes
folder to runtime classpath, also add org.cljtest42
to exported packages.Add two simple Clojure files in the org.cljtest42
package/namespace:
TestClass.clj:
(ns org.cljtest42.TestClass
(:gen-class))
(defn -main [greet] (println greet))
compile.clj
(ns org.cljtest42.compile)
(dorun (map compile ['org.cljtest42.TestClass]))
Trigger AOT compilation by selecting project node and choose Run > Clojure application (the /classes
folder should now be populated with compiled clojure classes).
Reference TestClass from the Activator
class (e.g. in start() - also tried in Perspective.createInitialLayout())
So far so good. However, trying to run this project as an Eclipse application always fails with this:
java.io.FileNotFoundException: Could not locate org/cljtest42/TestClass__init.class or org/cljtest42/TestClass.clj on classpath:
at clojure.lang.RT.load(RT.java:430)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:401)
at com.pspctclr.cljtest42.TestClass.<clinit>(Unknown Source)
It would be outstanding if someone more knowledgable could share some pointers on how this issue could be overcome. Could it be that it's either because the AOT compiled classes don't actually end up in the classpath (not sure why?, /classes is explicitly added) or that the separate Clojure plugin can't access them due to the way Equinox/OSGI works?
Thanks!
The problem seems that the Clojure bundle doesn't see your bundle's classes, although you've exported them. This is, because, in OSGi (as you probably know), in order for a bundle to be able to see a class, its package needs to be imported.
But what about cases, where a bundle needs to load a class from a bundle, which has called it. In order for this to work, Eclipse has implemented buddy policies, which are designed exactly for this case:
Eclipse-BuddyPolicy: [dependent|registered]
.Eclipse-BuddyPolicy: registered
, you'll need to add manifest header to the bundles, which uses Clojure: Eclipse-RegisterBuddy: <clojure-bundle-name>
Disclaimer: I don't have any experience with Clojure, but I wanted to take a shot at this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With