ClassCastException при загрузке одного и того же класса из двух разных войн в одно ухо из-за разных загрузчиков классов - PullRequest
0 голосов
/ 24 декабря 2018

Я работаю над существующим приложением ADF, где внутри EAR развернуты два разных проектных модуля, развернутых в weblogic.1. Модельный проект с ВО, ВБ и AM (содержит реализацию прикладного модуля)2. Проект пользовательского интерфейса (война создается для этого проекта с использованием файлов сборки модельного проекта)

Я добавил еще один файл войны для включения служб отдыха вместе с пользовательским интерфейсом.Причиной различных войн является то, что война пользовательского интерфейса требует веб-аутентификации, и мы хотим обойти это в Rest war, предоставляя аутентификацию с несколькими токенами.Итак, теперь у нас есть две войны и три модуля.
1. Модельный проект
2. Проект пользовательского интерфейса
3. Rest Project (использует файлы сборки из проекта пользовательского интерфейса и модельного проекта)

Теперь проблема в том, что реализация прикладного модуля извлекается с использованием

ApplicationModuleHandle amHandle = Configuration.createRootApplicationModuleHandle("**.**.classpackage","config_name");

amImpl = (MyAMImpl) amHandle.useApplicationModule();

И если одна из войн создает объект моего MyAMImplдругой получает

ClassCastException.

Мой запрос - есть ли способ загрузить обе войны с помощью одного загрузчика классов, используя weblogic-application.xml.Или любая другая конфигурация на уровне кода.

PS: я избегаю путать мой код с пользовательскими загрузчиками классов или принудительно загружать тот же загрузчик классов внутри кода приложения, поскольку это уже существующее приложение.

Любая помощь высоко ценится.

РЕДАКТИРОВАТЬ: Сначала есть еще один модуль, который содержит объект-одиночка.Который для дальнейшей ясности - Кварцевый Синглтон.И проект пользовательского интерфейса содержит Trigger Listener, который вызывает прикладной модуль.

Поэтому я с большим количеством проблем нашел причину и решение для этого.

Причина: в обеих войнах используется отдельный классзагрузчики и создадут разные экземпляры Quartz Singleton.У каждого будут свои экземпляры TriggerListener.
Таким образом, когда один из модулей вызывает QuartzScheduler и Trigger Listener, он создает прикладной модуль (который сохраняется в приложении и не освобождается).
Теперь, когда второе приложение вызывает QuartzSingleton, создается новый экземпляр того же самого и Trigger Listener для загрузчика второго класса, но возвращается тот же экземпляр Application Module.Поскольку загрузчик второго класса не имеет понятия о возвращаемом модуле приложения, он генерирует исключение ClassCastException.

Решение: Добавьте проект, содержащий Quartz Scheduler на уровне EAR, и добавьте выходные данные сборки проекта в военные проекты (поэтому они этого не делают.выбросить исключения времени компиляции).Это позволило бы всему приложению иметь один экземпляр Quartz Scheduler Singleton с использованием Class Loader приложения, которое фактически является загрузчиком родительского класса для двух войн.Что позволяет обеим войнам иметь возможность найти Класс в родительском загрузчике классов, и исключение не генерируется, поскольку теперь все три экземпляра, например, Quartz Scheduler Singleton, TriggerListener и Application Module, находятся в одном загрузчике классов.

PS: я знаю, что это был не очень объясненный запрос в начале, потому что я сам не был уверен в причине.Приносим извинения за это.И у приложения были определенные недостатки дизайна.Это все еще имеет хотя.Надеюсь, кто-то найдет это полезным

1 Ответ

0 голосов
/ 27 декабря 2018

Я также добавил причину и решение в запрос.

Причина: в обеих войнах используются отдельные загрузчики классов, и они будут создавать разные экземпляры Quartz Singleton.У каждого будут свои экземпляры TriggerListener.Поэтому, когда один из модулей вызывает QuartzScheduler и Trigger Listener, он создает прикладной модуль (который сохраняется в приложении и не освобождается).Теперь, когда второе приложение вызывает QuartzSingleton, создается новый экземпляр того же самого и Trigger Listener для загрузчика второго класса, но возвращается тот же экземпляр Application Module.Поскольку загрузчик второго класса не имеет понятия о возвращенном модуле приложения, он генерирует исключение ClassCastException.

Решение: добавьте проект, содержащий Quartz Scheduler, на уровне EAR и добавьте выходные данные сборки проекта в военные проекты (чтобы они не делали этого).выбросить исключения времени компиляции).Это позволило бы всему приложению иметь один экземпляр Quartz Scheduler Singleton с использованием Class Loader приложения, которое фактически является загрузчиком родительского класса для двух войн.Что позволяет обеим войнам иметь возможность найти Класс в родительском загрузчике классов, и исключение не выдается, поскольку теперь все три экземпляра, например, Quartz Scheduler Singleton, TriggerListener и Application Module, находятся в одном загрузчике классов.

...