1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.servlet.listener;
15
16 import java.lang.reflect.Field;
17 import java.util.Iterator;
18 import java.util.concurrent.ConcurrentHashMap;
19
20 import javax.servlet.ServletContextEvent;
21 import javax.servlet.ServletContextListener;
22
23 import org.eclipse.jetty.util.Loader;
24 import org.eclipse.jetty.util.log.Log;
25 import org.eclipse.jetty.util.log.Logger;
26
27
28
29
30
31
32
33
34
35
36 public class ELContextCleaner implements ServletContextListener
37 {
38 private static final Logger LOG = Log.getLogger(ELContextCleaner.class);
39
40
41 public void contextInitialized(ServletContextEvent sce)
42 {
43 }
44
45 public void contextDestroyed(ServletContextEvent sce)
46 {
47 try
48 {
49
50 Class beanELResolver = Loader.loadClass(this.getClass(), "javax.el.BeanELResolver");
51
52
53 Field field = getField(beanELResolver);
54
55
56 purgeEntries(field);
57
58 LOG.info("javax.el.BeanELResolver purged");
59 }
60
61 catch (ClassNotFoundException e)
62 {
63
64 }
65 catch (SecurityException e)
66 {
67 LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
68 }
69 catch (IllegalArgumentException e)
70 {
71 LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
72 }
73 catch (IllegalAccessException e)
74 {
75 LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
76 }
77 catch (NoSuchFieldException e)
78 {
79 LOG.warn("Cannot purge classes from javax.el.BeanELResolver", e);
80 }
81
82 }
83
84
85 protected Field getField (Class beanELResolver)
86 throws SecurityException, NoSuchFieldException
87 {
88 if (beanELResolver == null)
89 return null;
90
91 return beanELResolver.getDeclaredField("properties");
92 }
93
94 protected void purgeEntries (Field properties)
95 throws IllegalArgumentException, IllegalAccessException
96 {
97 if (properties == null)
98 return;
99
100 if (!properties.isAccessible())
101 properties.setAccessible(true);
102
103 ConcurrentHashMap map = (ConcurrentHashMap) properties.get(null);
104 if (map == null)
105 return;
106
107 Iterator<Class> itor = map.keySet().iterator();
108 while (itor.hasNext())
109 {
110 Class clazz = itor.next();
111 LOG.info("Clazz: "+clazz+" loaded by "+clazz.getClassLoader());
112 if (Thread.currentThread().getContextClassLoader().equals(clazz.getClassLoader()))
113 {
114 itor.remove();
115 LOG.info("removed");
116 }
117 else
118 LOG.info("not removed: "+"contextclassloader="+Thread.currentThread().getContextClassLoader()+"clazz's classloader="+clazz.getClassLoader());
119 }
120 }
121 }