本文介绍了带有DCEVM和HotSwapAgent的WebLogic上奇怪的java.beans.Introspector行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

I run into problems with Freemarker, which uses java.beans.Introspector. What I discovered is the fact that when I call Introspector.flushCaches on the method called by HotSwapAgent (through ReflectionCommand), then the BeanInfo in Introspector is invalidated properly (checked with debugger in that thread). However when I make request to the WLS appserver, then Introspector for the worker thread shows the old values!

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

This seems like some thread-local implementation, but I was not able to find anything that would point to that assumption in java.beans.Introspector's documentation.

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

Does anybody have any clue why this is happening and how to resolve that?

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

Currently I store the information about reloaded classes in separate class and reload everything that's in that cache from the request thread, which works.

感谢任何线索.

推荐答案

感谢@ddekany及其对相关问题的解答,请访问

Found this thanks to @ddekany and his answer to related problem at Freemarker removeIntrospectionInfo does not work with DCEVM after model hotswap

似乎JVM(至少是HotSpot 1.7)按线程组缓存了Introspector的缓存.这意味着必须在相应的ThreadGroup中运行的线程中调用Introspector.flushCaches.

It seems that JVM (at least HotSpot 1.7) caches Introspector's cache per ThreadGroup. This means, that Introspector.flushCaches must be called in a thread that runs in corresponding ThreadGroup.

当我对应用程序中的所有线程组执行此操作时,一切都将再次正常运行.

When I executed this for all the ThreadGroups in the application then everything started working again properly.

我找不到任何文档说明为什么每个ThreadGroup都缓存java.beans.Introspector,因此,如果有人对此有可靠的信息,请添加带有链接的评论.

I wasn't able to find any documentation why the java.beans.Introspector is cached per ThreadGroup so if anybody has an reliable information to this, please add a comment with 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代码,但它不存在!.

This has been definitely added in JDK7, because I checked JDK6 code and it's not there!.

这篇关于带有DCEVM和HotSwapAgent的WebLogic上奇怪的java.beans.Introspector行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 23:39