Странное поведение java.beans.Introspector в WebLogic с DCEVM и HotSwapAgent

Я запускаю WebLogic на JVM 1.7 с DCEVM (полная реализация) и HotSwapAgent с настраиваемым плагином, который запускается при каждой загрузке onClassLoad.

У меня возникают проблемы с Freemarker, который использует java.beans.Introspector. Что я обнаружил, так это тот факт, что когда я вызываю Introspector.flushCaches для метода, вызываемого HotSwapAgent (через ReflectionCommand), то BeanInfo в Introspector становится недействительным (проверено с помощью отладчика в этом потоке). Однако, когда я делаю запрос на сервер приложений WLS, Introspector для рабочего потока показывает старые значения!

Это похоже на локальную реализацию потока, но я не смог найти ничего, что указывало бы на это предположение в документации java.beans.Introspector.

Кто-нибудь знает, почему это происходит и как это решить?

В настоящее время я храню информацию о перезагруженных классах в отдельном классе и перезагружаю все, что находится в этом кеше, из потока запросов, который работает.

Спасибо за любую подсказку.


person Martin Macak    schedule 27.02.2015    source источник


Ответы (1)


Нашел это благодаря @ddekany и его ответу на связанную проблему в Freemarker removeIntrospectionInfo не работает с DCEVM после горячей замены модели

Кажется, что 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, и его там нет!

person Martin Macak    schedule 01.03.2015
comment
Было бы неплохо, если бы этот функционал был встроен в HotSwapAgent в виде плагина. Я посмотрю на это. - person Martin Macak; 01.03.2015