On Jan 28, 2009, at 10:27 AM, Ferdinando Villa wrote:
> > Clojure is saving our life and enabling thing we would never have > dreamed of without in our ARIES project (http:// > ecoinformatics.uvm.edu/ > aries). Still, we need to hack RT in order to be able to use it. I've > seen some discussion on classloader flexibility in the context of > Eclipse integration. In our case, we use a similar environment (JPF > plugin framework, may move to similar OGSI later) where Clojure > bindings are loaded by each plugin in sequence, each having to use a > specific classloader in order to see the Java classes in the plugin. > Because there is one RT, we're not going to make it work unless we > manually switch the classloader Clojure uses to the plugin-specific > one every time we load bindings. This requires making a field public > and it's, generally speaking, a ugly hack. Also, because we run in a > multi-user server environment, we'd love to have one RT per session so > we could only load what's needed there and not pollute the runtime in > other sessions. Or even RT objects arranged in a tree so each can use > the parent's environment and cleanly be disposed of when not needed > anymore. > > All this is clearly hard to do with the current static Clojure > runtime. How much of this is a choice, and how much is likely to > change in the future? We'd love to use Clojure as is. > Let me first state that I am very interested in supporting people using environments like OSGi etc. That said, I have yet to see any proper description of how these environments purport to support dynamic compiled bytecode and the other things a dynamic, non- interpreted language like Clojure might need. All these environments invent their own semantics for classloaders, ignoring/modifying to various degrees delegation, context classloaders etc. So, there's no standard way to support these environments. Even standard Java libs can run into trouble or require code modifications to work. But I will consider hooks, or conditional code in order to do special handling, if only there was some documentation indicating the environment has a solution for anything other than static Java. Here are some of the things Clojure needs: - It needs to create classes from bytecode in memory (at least for dynamic-loaded cljs and eval/repl). With Java proper, there is no way to do this other than to create a custom classloader. That classloader needs to be rooted, and since these environments are constantly swapping out loaders, finding a suitable root that leaves the class accessible can be a challenge. - It needs to proxy Class.forName. Many of these environments assume compiled Java that, when needing to find classes dynamically, will call Class.forName directly. This call looks back in the stack for the caller, and uses its classloader. However, when the call is indirect, via a library, like calls through Clojure's import, then this mechanism resolves with the library's loader. This causes problems when the consumer's loader doesn't share a hierarchical relationship with the library's, or when delegation is disabled. But it seems that these environments stop considering dynamic use at "just use Class.forName and you'll get your bundle/module's loader". Conversely, people that want to use these environments, which base their modularity around classloaders, don't seem to want to use classloaders to get multiple independent Clojure instances, when that is precisely the way to do that. If you want one RT per session, load Clojure into a classloader per session. Clojure is compiled, like Java, and has a single namespace, like Java, and it you want independence/security, you use classloaders, like Java. Being in a module system doesn't necessarily mean that Clojure should be a shared module. If Clojure's RT/Namespace environment was not static, there would then be different instances, and those instances would have to be threaded, interpreter style, through the call chain, and names would have to be resolved dynamically with lookups. This would impact performance and interoperability. Since it seems like you have something that works, but requires a hack, could you describe more fully what you are doing, and how Clojure could better support it (needed hooks etc)? Anyone doing OSGi etc can please chime in with as well. Thanks, Rich --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---