mjiderhamn/classloader-leak-prevention

BeanELResolverCleanUp (2.6.2) for at leat el-api-2.2.4 does really clear anything?

mgsCatDev opened this issue · 1 comments

I'm using javax.el-api-2.2.4 and the implementation of BeanELResolver has this atribute:
private static final SoftConcurrentHashMap properties = new SoftConcurrentHashMap();

This inner class SoftConcurrentHashMap extends Map but it's method "clear" (which is the one used in BeanELResolverCleanUp) I think does nothing because this class really is a wrapper for an another map which really is the one who contains the elements:

 static private class SoftConcurrentHashMap extends
            ConcurrentHashMap<Class<?>, BeanProperties> {

    private static final int CACHE_INIT_SIZE = 1024;
    private ConcurrentHashMap<Class<?>, BPSoftReference> map =
        new ConcurrentHashMap<Class<?>, BPSoftReference>(CACHE_INIT_SIZE);
    private ReferenceQueue<BeanProperties> refQ =
                    new ReferenceQueue<BeanProperties>();

    // Remove map entries that have been placed on the queue by GC.
    private void cleanup() {
        BPSoftReference BPRef = null;
        while ((BPRef = (BPSoftReference)refQ.poll()) != null) {
            map.remove(BPRef.key);
        }
    }

    @Override
    public BeanProperties put(Class<?> key, BeanProperties value) {
        cleanup();
        BPSoftReference prev =
            map.put(key, new BPSoftReference(key, value, refQ));
        return prev == null? null: prev.get();
    }

    @Override
    public BeanProperties putIfAbsent(Class<?> key, BeanProperties value) {
        cleanup();
        BPSoftReference prev =
            map.putIfAbsent(key, new BPSoftReference(key, value, refQ));
        return prev == null? null: prev.get();
    }

    @Override
    public BeanProperties get(Object key) {
        cleanup();
        BPSoftReference BPRef = map.get(key);
        if (BPRef == null) {
            return null;
        }
        if (BPRef.get() == null) {
            // value has been garbage collected, remove entry in map
            map.remove(key);
            return null;
        }
        return BPRef.get();
    }
}

Hi @unpringatmes . Sorry for the late reply.

As explained on my blog the BeanELResolver should have been fixed as of 2.2.4. Since the original bug should be fixed, is doesn't matter that the cleanup in fact does nothing - it still shouldn't leak.

I'm closing this issue with only improvement of the JavaDoc. If however you are still seeing leaks originating in BeanELResolver I'd love to get more info.