Bonjour,

J'ai un problème qui semble concerner le class loading avec JBoss.

J'ai deux instances JBoss, sur chaque instance une application java qui tourne, appelons les application A et application B.
Le schéma d'utilisation du système est le suivant : l'utilisateur se connecte sur une appli web, qui demande des informations à l'application A, qui elle même demande des informations à l'application B.

J'ai donc des classes utilitaires pour effectuer la communication entre l'application A et l'application B, ces classes sont packagées dans chacune des 2 archives déployées sur les 2 instances.

Tout cela fonctionne très bien, sauf dans le cas particulier suivant :
- un 1er utilisateur effectue une requête qui prend plusieurs secondes avant de se terminer avec succès (cette requête utilise intensivement l'application B, qui retourne les résultats à l'application A, qui les retourne à l'application web pour affichage).
- un 2ème utilisateur souhaite effectuer une requête similaire (web app -> app A -> app B), mais il se produit alors une ClassCastException : X cannot be cast to X, où X est le nom d'une classe utilitaire partagée par les 2 applications A et B.

Après un peu de recherche, j'ai compris que bien que ces deux classes soient identiques au niveau de leur byte code, elles ne peuvent être castées car le class loader utilisé pour charger les classes est différent.

Et en effet, en mettant des Print dans le code, je m'aperçois que dans ce cas particulier d'accès concurrent, ma classe utilitaire n'est pas chargée par le même class loader.

Dans le cas normal, mes classes sont chargées par le class loader org.jboss.mx.loading.UnifiedClassLoader3, qui semble être le class loader central d'une architecture JBoss.
Et dans le cas particulier décrit plus haut, le print me retourne la chaine suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
WebappClassLoader
  delegate: false
  repositories:
    /WEB-INF/classes/----------> Parent Classloader:java.net.FactoryURLClassLoader@de8209
Ainsi, un autre class loader est utilisé dans ce cas : le WebappClassLoader.

Je ne comprends pas trop pourquoi dans ce cas particulier ce class loader est utilisé plutôt qu'un autre. Est-ce parce que le UnifiedClassLoader3 est intensivement utilisé par la requête du 1er utilisateur et qu'il n'est ainsi pas disponible ?

Comment faire pour configurer JBoss afin de n'utiliser que le UnifiedClassLoader3 dans tous les cas et ainsi éviter des ClassCastException pour une même classe ?

En cherchant un peu, j'ai compris que la communication entre applications n'est pas forcément une chose aisée, et que le passage d'instances par référence, bien que performant, peut poser ce genre de problèmes. Une piste serait apparemment de passer les instances par valeur, ce qui voudrait dire (si j'ai bien compris) sérialiser l'instance par l'application B puis la désérialiser par l'application A.

Qu'en dites vous ? Avez vous d'autres pistes pour expliquer ce comportement ?