使用 DCEVM 和 HotSwapAgent 在 WebLogic 上出现奇怪的 java.beans.Introspector 行为
Strange java.beans.Introspector behavior on WebLogic with DCEVM and HotSwapAgent
我运行在 JVM 1.7 上使用 DCEVM(完整实现)和 HotSwapAgent 以及在每次 onClassLoad 时都会触发的自定义插件的 HotSwapAgent 上使用 WebLogic。
我 运行 遇到了使用 java.beans.Introspector 的 Freemarker 的问题。我发现的事实是,当我对 HotSwapAgent 调用的方法(通过 ReflectionCommand)调用 Introspector.flushCaches 时,Introspector 中的 BeanInfo 会正确失效(在该线程中使用调试器进行检查)。但是,当我向 WLS 应用服务器发出请求时,工作线程的 Introspector 会显示旧值!
这似乎是某种线程本地实现,但我无法在 java.beans.Introspector 的文档中找到任何指向该假设的内容。
有人知道为什么会发生这种情况以及如何解决吗?
目前,我将有关重新加载的 classes 的信息存储在单独的 class 中,并从请求线程重新加载该缓存中的所有内容,这是有效的。
感谢任何线索。
感谢@ddekany 和他在
上对相关问题的回答找到了这个
似乎 JVM(至少 HotSpot 1.7)缓存每个线程组的 Introspector 缓存。这意味着,必须在相应的 ThreadGroup
.
中运行的线程中调用 Introspector.flushCaches
当我为应用程序中的所有线程组执行此操作时,一切又开始正常工作。
我找不到任何文档说明 java.beans.Introspector
是根据 ThreadGroup
缓存的,所以如果有人对此有可靠的信息,请添加评论 link。
谢谢。
更新:
来自 JDK7 源代码
/**
* 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;
}
这个肯定是JDK7添加的,因为我查了JDK6的代码,没有!
我运行在 JVM 1.7 上使用 DCEVM(完整实现)和 HotSwapAgent 以及在每次 onClassLoad 时都会触发的自定义插件的 HotSwapAgent 上使用 WebLogic。
我 运行 遇到了使用 java.beans.Introspector 的 Freemarker 的问题。我发现的事实是,当我对 HotSwapAgent 调用的方法(通过 ReflectionCommand)调用 Introspector.flushCaches 时,Introspector 中的 BeanInfo 会正确失效(在该线程中使用调试器进行检查)。但是,当我向 WLS 应用服务器发出请求时,工作线程的 Introspector 会显示旧值!
这似乎是某种线程本地实现,但我无法在 java.beans.Introspector 的文档中找到任何指向该假设的内容。
有人知道为什么会发生这种情况以及如何解决吗?
目前,我将有关重新加载的 classes 的信息存储在单独的 class 中,并从请求线程重新加载该缓存中的所有内容,这是有效的。
感谢任何线索。
感谢@ddekany 和他在
似乎 JVM(至少 HotSpot 1.7)缓存每个线程组的 Introspector 缓存。这意味着,必须在相应的 ThreadGroup
.
Introspector.flushCaches
当我为应用程序中的所有线程组执行此操作时,一切又开始正常工作。
我找不到任何文档说明 java.beans.Introspector
是根据 ThreadGroup
缓存的,所以如果有人对此有可靠的信息,请添加评论 link。
谢谢。
更新:
来自 JDK7 源代码
/**
* 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;
}
这个肯定是JDK7添加的,因为我查了JDK6的代码,没有!