Одновременный доступ вызывает ClassCastException (X не может быть приведен к X), или как решить такие проблемы загрузки класса в JBoss - PullRequest
3 голосов
/ 02 марта 2011

У меня проблема с JBoss и загрузкой классов.

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

Обычно это работает нормально, но в определенных ситуациях я получаю ClassCastException . Дело в следующем: Пользователь использует веб-приложение, которое вызывает приложение в первом экземпляре JBoss (назовем его приложением A). И приложение A вызывает приложение B (во втором случае). Этот конкретный вызов занимает несколько секунд, чтобы успешно. Если другой пользователь пытается использовать веб-приложение в аналогичном контексте (вызов приложения A, которое вызывает приложение B), и если этот вызов происходит во время первого вызова пользователя, я систематически получаю ClassCastException: X cannot be cast to X (где X - это мой служебный класс, общий для обоих приложений).

Я нашел некоторую информацию и понял, что это проблема загрузки классов. Действительно, в этом конкретном контексте одновременных вызовов мой служебный класс не загружается одним и тем же загрузчиком классов. Я поставил команду печати, чтобы увидеть, какой загрузчик классов используется. В обычном поведении org.jboss.mx.loading.UnifiedClassLoader3 используется для загрузки классов. В описанном выше конкретном случае приложение B, похоже, использовало загрузчик другого класса для второго пользователя. Моя команда печати дала мне следующее:

WebappClassLoader
  delegate: false
  repositories:
    /WEB-INF/classes/----------> Parent Classloader:java.net.FactoryURLClassLoader@de8209

Я предполагаю, что приложение B возвращает экземпляр моего служебного класса, загруженного этим WebappClassLoader , а приложение A (которое использует UnifiedClassLoader3) не может его привести.

Но я не понимаю, почему UnifiedClassLoader3 не может использоваться в этом случае в приложении B. И почему используется этот WebappClassLoader?

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

<jboss-app>
  <module-order>strict</module-order>  
  <loader-repository>applicationAorApplicationB.ear</loader-repository>
</jboss-app>

Есть ли у вас какие-либо советы по решению этой проблемы? Как я могу настроить загрузчик классов jboss, чтобы избежать исключения приведения классов?

Я уточняю, что горячего развертывания нет: каждый раз, когда я развертываю приложения, я очищаю сервер.

Спасибо за ваше время.

1 Ответ

0 голосов
/ 02 марта 2011

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

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

...