4949 * @author Vladimir Dvorak
5050 */
5151@ Plugin (name = "ELResolver" ,
52- group = "groupELResolver" ,
53- fallback = true ,
54- description = "Purge BeanELResolver class cache on any class redefinition." ,
55- testedVersions = {"2.2" },
56- expectedVersions = {"2.2" })
52+ group = "groupELResolver" ,
53+ fallback = true ,
54+ description = "Purge BeanELResolver class cache on any class redefinition." ,
55+ testedVersions = {"2.2" },
56+ expectedVersions = {"2.2" })
5757@ Versions (
58- maven = {
59- //Jboss el 2
60- @ Maven (value = "[1.0,)" , artifactId = "jboss-el-api_2.2_spec" , groupId = "org.jboss.spec.javax.el" ),
61- //Juel
62- @ Maven (value = "[2.0,)" , artifactId = "juel" , groupId = "de.odysseus.juel" ),
63- //Jboss el 3.0
64- @ Maven (value ="[3.0,)" , artifactId = "javax.el-api" , groupId = "javax.el" )
65- },
66- manifest = {
67- // Seam jboss
68- @ Manifest (value ="[1.0,)" , versionName ="JBoss-EL-Version" , names ={@ Name (key ="JBoss-EL-Version" , value =".*" )}),
69- // Tomcat bundled EL (6-9)
70- @ Manifest (value ="[2.0,5.0)" ,versionName = Name .SpecificationVersion , names ={
71- @ Name (key =Name .ImplementationTitle ,value ="javax.el" ),
72- @ Name (key =Name .ImplementationVendor , value ="Apache.*Software.*Foundation" )
73- }),
74- // Tomcat bundled EL (10)
75- @ Manifest (value ="[5.0,)" ,versionName = Name .SpecificationVersion , names ={
76- @ Name (key =Name .ImplementationTitle ,value ="jakarta.el" ),
77- @ Name (key =Name .ImplementationVendor , value ="Apache.*Software.*Foundation" )
78- }),
79- //Jetty 7,8
80- @ Manifest (value ="[2.0,)" , versionName ={Name .BundleVersion }, names ={@ Name (key =Name .BundleSymbolicName ,value ="javax.el" )}),
81- //Jetty 9
82- @ Manifest (value ="[8.0,)" , versionName ={Name .BundleVersion }, names ={
83- @ Name (key =Name .BundleSymbolicName ,value ="org.mortbay.jasper.apache-el" ),
84- @ Name (key ="Bundle-Vendor" ,value ="Webtide" )}),
85- // GlassFish
86- @ Manifest (value ="[3.0,)" , versionName ={Name .BundleVersion }, names ={
87- @ Name (key =Name .BundleSymbolicName ,value ="com.sun.el.javax.el" ),
88- @ Name (key ="Bundle-Vendor" ,value ="GlassFish Community" )})
89- }
90- )
58+ maven = {
59+ //Jboss el 2
60+ @ Maven (value = "[1.0,)" , artifactId = "jboss-el-api_2.2_spec" , groupId = "org.jboss.spec.javax.el" ),
61+ //Juel
62+ @ Maven (value = "[2.0,)" , artifactId = "juel" , groupId = "de.odysseus.juel" ),
63+ //Jboss el 3.0
64+ @ Maven (value ="[3.0,)" , artifactId = "javax.el-api" , groupId = "javax.el" )
65+ },
66+ manifest = {
67+ // Seam jboss
68+ @ Manifest (value ="[1.0,)" , versionName ="JBoss-EL-Version" , names ={@ Name (key ="JBoss-EL-Version" , value =".*" )}),
69+ // Tomcat bundled EL (6-9)
70+ @ Manifest (value ="[2.0,5.0)" ,versionName = Name .SpecificationVersion , names ={
71+ @ Name (key =Name .ImplementationTitle ,value ="javax.el" ),
72+ @ Name (key =Name .ImplementationVendor , value ="Apache.*Software.*Foundation" )
73+ }),
74+ // Tomcat bundled EL (10)
75+ @ Manifest (value ="[5.0,)" ,versionName = Name .SpecificationVersion , names ={
76+ @ Name (key =Name .ImplementationTitle ,value ="jakarta.el" ),
77+ @ Name (key =Name .ImplementationVendor , value ="Apache.*Software.*Foundation" )
78+ }),
79+ //Jetty 7,8
80+ @ Manifest (value ="[2.0,)" , versionName ={Name .BundleVersion }, names ={@ Name (key =Name .BundleSymbolicName ,value ="javax.el" )}),
81+ //Jetty 9
82+ @ Manifest (value ="[8.0,)" , versionName ={Name .BundleVersion }, names ={
83+ @ Name (key =Name .BundleSymbolicName ,value ="org.mortbay.jasper.apache-el" ),
84+ @ Name (key ="Bundle-Vendor" ,value ="Webtide" )}),
85+ // GlassFish
86+ @ Manifest (value ="[3.0,)" , versionName ={Name .BundleVersion }, names ={
87+ @ Name (key =Name .BundleSymbolicName ,value ="com.sun.el.javax.el" ),
88+ @ Name (key ="Bundle-Vendor" ,value ="GlassFish Community" )})
89+ }
90+ )
9191public class ELResolverPlugin {
9292
9393 private static AgentLogger LOGGER = AgentLogger .getLogger (ELResolverPlugin .class );
@@ -121,7 +121,7 @@ public static void beanELResolverRegisterVariable(CtClass ctClass) throws Cannot
121121
122122 String initPlugin = PluginManagerInvoker .buildInitializePlugin (ELResolverPlugin .class );
123123 String registerThis = PluginManagerInvoker .buildCallPluginMethod (ELResolverPlugin .class , "registerBeanELResolver" ,
124- "this" , "java.lang.Object" );
124+ "this" , "java.lang.Object" );
125125
126126 String rootPackage = ctClass .getName ().startsWith ("javax" ) ? "javax" : "jakarta" ;
127127
@@ -140,9 +140,6 @@ public static void beanELResolverRegisterVariable(CtClass ctClass) throws Cannot
140140 } else if (checkJBoss_3_0_EL (rootPackage , ctClass )) {
141141 found = true ;
142142 LOGGER .debug ("JBossEL 3.0 - " + rootPackage + ".el.BeanELResolver - method added " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader). " );
143- } else if (checkGenericEL (ctClass )) {
144- found = true ;
145- LOGGER .debug ("Generic EL - " + rootPackage + ".el.BeanELResolver - method added " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader). " );
146143 }
147144
148145 if (!found ) {
@@ -158,14 +155,14 @@ public static void patchJBossReflectionUtil(CtClass ctClass) throws NotFoundExce
158155
159156 String buildInitializePlugin = PluginManagerInvoker .buildInitializePlugin (ELResolverPlugin .class , "base.getClass().getClassLoader()" );
160157 String registerJBossReflectionUtil = PluginManagerInvoker .buildCallPluginMethod ("base.getClass().getClassLoader()" ,
161- ELResolverPlugin .class , "registerJBossReflectionUtil" );
158+ ELResolverPlugin .class , "registerJBossReflectionUtil" );
162159
163160 CtMethod mFindMethod = ctClass .getDeclaredMethod ("findMethod" );
164161 mFindMethod .insertAfter (
165- "if(!$$ha$haInitialized) {" +
166- "$$ha$haInitialized=true;" +
167- buildInitializePlugin +
168- registerJBossReflectionUtil +
162+ "if(!$$ha$haInitialized) {" +
163+ "$$ha$haInitialized=true;" +
164+ buildInitializePlugin +
165+ registerJBossReflectionUtil +
169166 "}"
170167 );
171168 LOGGER .debug ("org.jboss.el.util.ReflectionUtil enhanced with resource bundles registration." );
@@ -177,8 +174,8 @@ private static boolean checkJuelEL(CtClass ctClass) {
177174 // check if we have purgeBeanClasses method
178175 CtMethod purgeMeth = ctClass .getDeclaredMethod ("purgeBeanClasses" );
179176 ctClass .addMethod (CtNewMethod .make (
180- "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
181- "purgeBeanClasses(classLoader);" +
177+ "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
178+ "purgeBeanClasses(classLoader);" +
182179 "}" , ctClass ));
183180 return true ;
184181 } catch (NotFoundException | CannotCompileException e ) {
@@ -197,15 +194,15 @@ private static boolean checkApacheEL(String rootPackage, CtClass ctClass)
197194 ctClass .addField (new CtField (CtClass .booleanType , "$$ha$purgeRequested" , ctClass ), CtField .Initializer .constant (false ));
198195
199196 ctClass .addMethod (CtNewMethod .make (
200- "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
201- "$$ha$purgeRequested=true;" +
197+ "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
198+ "$$ha$purgeRequested=true;" +
202199 "}" , ctClass ));
203200 CtMethod mGetBeanProperty = ctClass .getDeclaredMethod ("property" );
204201 mGetBeanProperty .insertBefore (
205202 "if($$ha$purgeRequested) {" +
206203 "$$ha$purgeRequested=false;" +
207204 "this.cache = new " + rootPackage + " .el.BeanELResolver.ConcurrentCache(CACHE_SIZE); " +
208- "}"
205+ "}"
209206 );
210207 CtField ctCacheField = ctClass .getDeclaredField ("cache" );
211208 int modifiers = ctCacheField .getModifiers ();
@@ -232,50 +229,6 @@ private static boolean checkJBoss_3_0_EL(String rootPackage, CtClass ctClass) {
232229 return false ;
233230 }
234231
235- private static boolean checkGenericEL (CtClass ctClass ) {
236- if (!(hasField (ctClass , "cache" ) || hasField (ctClass , "propertyCache" )
237- || hasField (ctClass , "properties" ) || hasField (ctClass , "typeCache" ))) {
238- return false ;
239- }
240- try {
241- ctClass .addMethod (CtNewMethod .make (
242- "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
243- "try {" +
244- "java.lang.Class cls = this.getClass();" +
245- "String[] fields = new String[]{\" cache\" ,\" propertyCache\" ,\" properties\" ,\" typeCache\" };" +
246- "for (int i = 0; i < fields.length; i++) {" +
247- "try {" +
248- "java.lang.reflect.Field f = cls.getDeclaredField(fields[i]);" +
249- "f.setAccessible(true);" +
250- "Object v = java.lang.reflect.Modifier.isStatic(f.getModifiers()) ? f.get(null) : f.get(this);" +
251- "if (v instanceof java.util.Map) {" +
252- "((java.util.Map)v).clear();" +
253- "} else if (v != null) {" +
254- "try {" +
255- "java.lang.reflect.Method m = v.getClass().getMethod(\" clear\" );" +
256- "m.invoke(v);" +
257- "} catch (Exception e) { }" +
258- "}" +
259- "} catch (NoSuchFieldException e) { }" +
260- "}" +
261- "} catch (Exception e) { }" +
262- "}" , ctClass ));
263- return true ;
264- } catch (CannotCompileException e ) {
265- LOGGER .error ("checkGenericEL() exception {}" , e .getMessage ());
266- }
267- return false ;
268- }
269-
270- private static boolean hasField (CtClass ctClass , String name ) {
271- try {
272- ctClass .getDeclaredField (name );
273- return true ;
274- } catch (NotFoundException e ) {
275- return false ;
276- }
277- }
278-
279232 /*
280233 * JBossEL has weak reference cache. Values are stored in ThreadGroupContext cache, that must be flushed from appropriate thread.
281234 * Therefore we must create request for cleanup cache in PURGE_CLASS_CACHE_METHOD and own cleanup is executed indirectly when
@@ -286,8 +239,8 @@ private static void patchJBossEl(String rootPackage, CtClass ctClass) {
286239 ctClass .addField (new CtField (CtClass .booleanType , "$$ha$purgeRequested" , ctClass ), CtField .Initializer .constant (false ));
287240
288241 ctClass .addMethod (CtNewMethod .make (
289- "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
290- "$$ha$purgeRequested=true;" +
242+ "public void " + PURGE_CLASS_CACHE_METHOD_NAME + "(java.lang.ClassLoader classLoader) {" +
243+ "$$ha$purgeRequested=true;" +
291244 "}" , ctClass ));
292245 try {
293246 CtMethod mGetBeanProperty = ctClass .getDeclaredMethod ("getBeanProperty" );
@@ -296,7 +249,7 @@ private static void patchJBossEl(String rootPackage, CtClass ctClass) {
296249 "$$ha$purgeRequested=false;" +
297250 "java.lang.reflect.Method meth = " + rootPackage + ".el.BeanELResolver.SoftConcurrentHashMap.class.getDeclaredMethod(\" $$ha$createNewInstance\" , null);" +
298251 "properties = (" + rootPackage + ".el.BeanELResolver.SoftConcurrentHashMap) meth.invoke(properties, null);" +
299- "}" );
252+ "}" );
300253 } catch (NotFoundException e ) {
301254 LOGGER .debug ("FIXME : checkJBoss_3_0_EL() 'getBeanProperty(...)' not found in javax.el.BeanELResolver." );
302255 }
@@ -313,7 +266,7 @@ public static void patchJbossElSoftConcurrentHashMap(CtClass ctClass) throws Can
313266 ctClass .addMethod (CtNewMethod .make (
314267 "public " + rootPackage + ".el.BeanELResolver.SoftConcurrentHashMap $$ha$createNewInstance() {" +
315268 "return new " + rootPackage + ".el.BeanELResolver.SoftConcurrentHashMap();" +
316- "}" , ctClass ));
269+ "}" , ctClass ));
317270 } catch (CannotCompileException e ) {
318271 LOGGER .error ("patchJbossElSoftConcurrentHashMap() exception {}" , e .getMessage ());
319272 }
0 commit comments