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
-~----------~----~----~----~------~----~------~--~---

Reply via email to