【问题标题】:Strange java.beans.Introspector behavior on WebLogic with DCEVM and HotSwapAgent带有 DCEVM 和 HotSwapAgent 的 WebLogic 上的奇怪 java.beans.Introspector 行为
【发布时间】:2015-02-27 15:16:52
【问题描述】:

我在 JVM 1.7 上运行 WebLogic,带有 DCEVM(完整实现)和带有自定义插件的 HotSwapAgent,每个 onClassLoad 都会触发该插件。

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

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

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

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

感谢您提供任何线索。

【问题讨论】:

    标签: weblogic hotswap dcevm


    【解决方案1】:

    感谢@ddekany 以及他在Freemarker removeIntrospectionInfo does not work with DCEVM after model hotswap 上对相关问题的回答

    似乎 JVM(至少 HotSpot 1.7)为每个线程组缓存了 Introspector 的缓存。这意味着,Introspector.flushCaches 必须在对应的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的代码,没有!

    【讨论】:

    • 如果这个功能作为插件嵌入到 HotSwapAgent 中就更好了。我会研究一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2011-08-07
    • 1970-01-01
    • 2014-04-13
    • 2012-11-12
    • 2019-08-19
    相关资源
    最近更新 更多