I have this kind of problem. I have Clojure code contained in Eclipse plug-in (denoted A) in *.clj files. I don’t want AOT compilation. However, I need to load the clojure code from another Clojure plug-in B. This is possible when B depends on A. Clojure can easily access the classpath and everything works. But I want the plug-in A to be plugged as extension to B. But there is a problem because I could not find a way how to load a Clojure file contained in A from *.clj file contained in B. I would like to use the Clojure ‘load’ function which can load *.clj files from classpath but this function just cannot see contents of plug-in A event when I explicitely start the plug-in like this
(org.eclipse.core.runtime.Platform/getBundle "A")
Reaction to Laurent’s answer
Laurent, thank you very much! This is very interesting. However, I think this mayby solves a harder problem then my original one. You discribed how to call clojure code from java plug-in which is totaly awesome. I need to call clojure code from clojure plug-in which I think may be easier. I imagine that I would create extension point and provide clojure functions like this
<extension point="transforms">
<function namespace="my.nemaspace" fn="my-transform"/>
</extension>
So I do not need any magic with IExecutableExtensionFactory. I can read the extension registry from clojure code. What I cannot do is load the function specified in the extension. Is this doable or did I just misunderstood something? I noticed that you are using clojure.osgi. This looks cool, is there any documentation for that project?
Another solution occured to me: it is possible, in Eclipse, despite what I said in my previous answer, to create cyclic dependencies between the classloaders!
Eclipse guys needed to introduce this so that certain types of libraries (log4j, etc.) could work in an OSGi environment (which is what Eclipse is based upon).
This requires to leverage the
Eclipse-BuddyPolicymechanism (Third Party libraries and classloading).It’s quite easy: if you want plugin B to see all classes and resources of plugin A, just add this to plugin B’s
META-INF/MANIFEST.MFfile:The line above indicates that plugin B’s classloader will be able to access what its dependents classloaders have access to.
I created a sample set of plugins named A and B where B has 2 commands (visible in the top menu) : the first applies a text transformation on the “hello” hard coded string by calling clojure code in B. The second dynamically loads an new text transformation from plugin A, so that when you invoke the first command again, you see the result of applying transformations from B and transformations from A.
In your case, it may not even be required to use Eclipse Extension Point / Extension mechanism at all, after all. It will all depend on how you intent plugin B to “discover” plugin A relevant information.
The github repository showing this in action: https://github.com/laurentpetit/stackoverflow-12689605
HTH,
—
Laurent