Strange java.beans.Introspector behavior on WebLogic with DCEVM and HotSwapAgent

I am running WebLogic on JVM 1.7 with DCEVM (full implementation) and HotSwapAgent with a custom plugin that runs on every onClassLoad.

I'm having problems with Freemarker, which uses java.beans.Introspector. I found that when I call Introspector.flushCaches in a method called HotSwapAgent (via ReflectionCommand), then BeanInfo in Introspector is not valid (checked using a debugger in this thread). However, when I make a request to the WLS application server, the Introspector for the workflow shows the old values!

This seems like some thread-local implementation, but I could not find anything that would point to this assumption in the java.beans.Introspector documentation.

Does anyone know why this is happening and how to solve it?

I currently store information about reloaded classes in a separate class and reload everything in this cache from the request stream that works.

Thanks for any hint.

+4
source share
1 answer

Found this thanks to @ddekany and his answer to a related issue in Freemarker removeIntrospectionInfo does not work with DCEVM after model fraud

The JVM (at least HotSpot 1.7) seems to cache the Introspector cache for ThreadGroup. This means that Introspector.flushCaches must be called in a thread that runs in the corresponding ThreadGroup .

When I completed this for all ThreadGroups in the application, everything worked correctly.

I could not find any documentation why java.beans.Introspector cached for ThreadGroup , so if anyone has reliable information, add a comment with a link.

Thanks.

Update:

Based on JDK7 source

 /** * Introspect on a Java Bean and learn about all its properties, exposed * methods, and events. * <p> * If the BeanInfo class for a Java Bean has been previously Introspected * then the BeanInfo class is retrieved from the BeanInfo cache. * * @param beanClass The bean class to be analyzed. * @return A BeanInfo object describing the target bean. * @exception IntrospectionException if an exception occurs during * introspection. * @see #flushCaches * @see #flushFromCaches */ public static BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException { if (!ReflectUtil.isPackageAccessible(beanClass)) { return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); } ThreadGroupContext context = ThreadGroupContext.getContext(); BeanInfo beanInfo; synchronized (declaredMethodCache) { beanInfo = context.getBeanInfo(beanClass); } if (beanInfo == null) { beanInfo = new Introspector(beanClass, null, USE_ALL_BEANINFO).getBeanInfo(); synchronized (declaredMethodCache) { context.putBeanInfo(beanClass, beanInfo); } } return beanInfo; } 

This is definitely added in JDK7 because I checked the JDK6 code and it does not exist!

+3
source

Source: https://habr.com/ru/post/1214173/


All Articles