Bob, if you check the link to the blog post, it described such an
implementation that I did a while ago. Unfortunately what I found out is that
it doesn't work with some class loaders. Mainly because there are class loaders
that at some point in their life cycle will throw an exception when a
loadClass() is issued, and even if you use defineClass() a loadClass() is still
issued for java.lang.Object when defining your class for the first time,
causing an exception. So in the end I'm not using that code either, but I would
be using it if it was safe.
On 16.09.2010, at 17:13, Bob Lee wrote:
> Jevgeni,
>
> The best long term solution for the VM is ephemerons. They're not slated for
> Java 7 or even 8 yet though.
>
> I implemented "class loader locals" as a library years ago. Unfortunately, I
> don't have the code anymore because I didn't end up using them.
>
> The internals went something like this:
>
> public class ClassLoaderLocals {
> public static final Map values = new ConcurrenHashMap();
> }
>
> (I used synchronization at the time.)
>
> Now, force each ClassLoader to load its own copy of ClassLoaderLocals. If you
> reflectively invoke defineClass() instead of calling loadClass(), the
> ClassLoader won't check its parent loader for ClassLoaderLocals.
>
> Finally, paper over this with a nice, ThreadLocal-like API that hides the
> ugly reflection.
>
> Bob
>
> On Thu, Sep 16, 2010 at 7:56 AM, Jevgeni Kabanov <[email protected]> wrote:
> Hi guys,
>
> I'd like to contribute two new classes to the JDK7 and add a new
> package-visible field to the ClassLoader. These classes would be meant for
> the framework and server developers to allow for greater control over the
> references between classes in different class loaders. Specifically the goal
> would be to prevent the notoriously common classloader leaks. The motivation
> is partially described here:
> http://dow.ngra.de/2009/06/15/classloaderlocal-how-to-avoid-classloader-leaks-on-application-redeploy/
> That blog post also describes a way to backport it to older Java versions,
> unfortunately we found that the described approach will not work in some
> esoteric cases.
>
> The pseudo-code follows. It's not really optimized or even tested and is only
> meant to illustrate the functionality and complexity of the proposal. I'd
> like to hear your feedback on this.
>
> class ClassLoader {
> Map localMap = new HashMap();
> //...
> }
>
> public class ClassLoaderLocal {
> private Object key = new Object();
>
> public Object get(ClassLoader cl) {
> cl.localMap.get(key);
> }
>
> public void set(ClassLoader cl, Object value) {
> cl.localMap.put(key, value);
> }
> }
>
> public class ClassLoaderWeakReference extends Reference {
> private final WeakReference clRef;
> private final ClassLoaderLocal cll = new ClassLoaderLocal();
> public ClassLoaderWeakReference(Object target) {
> clRef = new WeakReference(target.getClass().getClassLoader());
> cll.set(target.getClass().getClassLoader(), target);
> }
>
> public Object get() {
> if (clRef.get() == null)
> return null;
> return cll.get((ClassLoader) clRef.get());
> }
> }
>
> Jevgeni Kabanov: Founder & CTO at ZeroTurnaround
> [email protected] | Skype: ekabanov | http://twitter.com/ekabanov
> "jrebel is r0x: http://bit.ly/6fRGji" - mschambeck
>
>
Jevgeni Kabanov: Founder & CTO at ZeroTurnaround
[email protected] | Skype: ekabanov | http://twitter.com/ekabanov
"Planning to give #JRebel 3.0 a try. No more Java restarting." - Jan Van Hoecke