Thanks much Rich. All your points are well taken, and OSGI and the
like are clearly not designed with any support for dynamic compiled
languages in mind. Having to live with that, here's the strategy that
works for us.

Our support for Clojure is based on Clojure bindings provided with
each bundle, providing functions that link back to internal plugin
functionalities. We want these bindings to be loaded at plugin
initialization, and the clojure funcs to be available for any other
plugins that depend on the ones that load the bindings. Plugins
themselves can choose what to make visible to other plugins.  OSGI/JPF
obviously provide plugins with custom classloaders that will lookup
classes according to plugin configurations.

Using Clojure won't use the custom classloader so the runtime
environment accessible to the Java side remains hidden. By using
plugin-specific bindings compiled in a shared runtime, the solution is
simple: because at plugin load time the system is single-user, we swap
the classloader Clojure uses when we load the bindings from within the
plugin, e.g

        public void loadBindings(URL source, ClassLoader cloader) throws
ThinklabException {

        try {

                DynamicClassLoader cl = null;
                if (cloader != null) {
                        cl = RT.ROOT_CLASSLOADER;
                        RT.ROOT_CLASSLOADER = new DynamicClassLoader(cloader);
                }

                        
Compiler.loadFile(Escape.fromURL(source.getFile().toString()));

                        if (cloader != null) {
                                RT.ROOT_CLASSLOADER = cl;
                        }

so that we can pass the classloader when we load bindings at
initialization, and the class references are found and compiled in.
This is ugly and only works because so far, Clojure has no need for a
specific classloader so we can use ours. The hack is obviously to make
ROOT_CLASSLOADER public and not final, and it could be avoided by
providing a form of loadFile that accepts a classloader parameter and
temporarily swaps the root classloader. But that's obviously still
ugly, and unacceptable in an unsynchronized environment, so I would
fully understand why you may not want to do it. For now that's all it
takes for our system to work properly, plus the fact that we can't
implement bindings that access the Java side of the plugin as macros,
because they will be compiled when the classes are invisible, and the
hack above is of course unacceptable when the system is in a multiuser
state. Anyway, that is easily solved by putting all Java accessors in
compiled functions and have the macros call those.

Having one runtime per session may be what we end up doing eventually,
but each runtime would still have to be initialized with the bindings,
so this specific problem would remain.

Thanks for any insight. Again, Clojure is a godsend for us.

Cheers
ferdinando


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to