使用DCEVM和HotSwapAgent在WebLogic上发生奇怪的java.beans.Introspector行为

时间:2015-02-27 15:16:52

标签: weblogic hotswap dcevm

我正在使用DCEVM(完全实现)在JVM 1.7上运行WebLogic,在每个onClassLoad上使用自定义插件运行HotSwapAgent。

我遇到了使用java.beans.Introspector的Freemarker的问题。我发现的事实是,当我在HotSwapAgent调用的方法(通过ReflectionCommand)上调用Introspector.flushCaches时,Introspector中的BeanInfo正确无效(在该线程中使用调试器进行检查)。但是,当我向WLS应用程序服务器发出请求时,工作线程的Introspector会显示旧值!

这看起来像是一些线程本地实现,但我无法在java.beans.Introspector的文档中找到任何指向该假设的内容。

有没有人知道为什么会发生这种情况以及如何解决这个问题?

目前,我将有关重新加载的类的信息存储在单独的类中,并从请求线程重新加载该缓存中的所有内容,该线程有效。

感谢任何线索。

1 个答案:

答案 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.IntrospectorThreadGroup进行缓存,所以如果有人对此有可靠的信息,请添加带链接的评论。

感谢。

更新

来自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代码并且它不存在!。