我正在使用DCEVM(完全实现)在JVM 1.7上运行WebLogic,在每个onClassLoad上使用自定义插件运行HotSwapAgent。
我遇到了使用java.beans.Introspector的Freemarker的问题。我发现的事实是,当我在HotSwapAgent调用的方法(通过ReflectionCommand)上调用Introspector.flushCaches时,Introspector中的BeanInfo正确无效(在该线程中使用调试器进行检查)。但是,当我向WLS应用程序服务器发出请求时,工作线程的Introspector会显示旧值!
这看起来像是一些线程本地实现,但我无法在java.beans.Introspector的文档中找到任何指向该假设的内容。
有没有人知道为什么会发生这种情况以及如何解决这个问题?
目前,我将有关重新加载的类的信息存储在单独的类中,并从请求线程重新加载该缓存中的所有内容,该线程有效。
感谢任何线索。
答案 0 :(得分:3)
感谢@ddekany及其对Freemarker removeIntrospectionInfo does not work with DCEVM after model hotswap
相关问题的回答似乎JVM(至少HotSpot 1.7)为每个ThreadGroup缓存了Introspector的缓存。这意味着,必须在相应的Introspector.flushCaches
中运行的线程中调用ThreadGroup
。
当我为应用程序中的所有ThreadGroup执行此操作时,一切都开始正常工作。
我无法找到任何文档为什么java.beans.Introspector
按ThreadGroup
进行缓存,所以如果有人对此有可靠的信息,请添加带链接的评论。
感谢。
更新
来自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代码并且它不存在!。