2013-06-15 5 views
4

JBoss EAP 6.1 serveur standloneOracle JDBC conflit de pilotes

application déployée en tant que fichier de guerre jette une exception d'exécution

java.lang.ClassCastException: oracle.sql.ARRAY cannot be cast to oracle.sql.ARRAY 

à la ligne

oracle.sql.ARRAY obj = (oracle.sql.ARRAY) rs.getObject("RATINGOBJ"); 

JDBC libary inclus est ojdbc6.jar (WEB_INF/lib). Toutes les bibliothèques sont incluses dans le fichier war et aucune librairie "globale" n'est configurée sur le serveur. J'ai vérifié qu'aucune autre bibliothèque jdbc n'est incluse dans l'application. Afin de créer une source de données JDBC, j'ai créé un déploiement pour ojdbc6.jar. C'est la seule source possible de conflit que je peux penser. Lorsque je supprime le fichier ojdbc6.jar du fichier war, j'obtiens une exception ClassNotFound à la place de ClassCastException.

Chaque autre partie de l'application fonctionne bien, sauf cette ligne. Comment est-ce que je débogue ceci plus loin?

+0

Peut-être essayer et exécuter une application de test très simple avec seulement votre pilote JDBC en tant que dépendance? – fge

+0

Cela ne se produit-il qu'occasionnellement? Redémarrez-vous le serveur chaque fois que vous redéployez l'application? –

+0

Chaque fois que je déploie l'application, je redémarre le serveur. Je ne pense pas que ce soit nécessaire, mais je le fais quand même. – BBS

Répondre

2

Je ne sais pas pourquoi le chargement à partir de web-inf/lib ne fonctionnera pas. Très probablement les classloaders sont différents.

Effectuez les deux premières étapes pour le diagnostic. Après cela, essayez l'une des deux alternatives ci-dessous pour résoudre le problème.
1) Vérifiez si les chargeurs de classes sont identiques en comparant les rs.getObject().getClass('RATINGOBJ').getClassLoader() et oracle.sql.ARRAY.class.getClassLoader() Si vous faites equals entre les deux chargeurs de classe, il doit retourner false car il semble que les chargeurs de classe soient différents. Vérifiez une explication à ClassCastException when casting to the same class

Ce problème a déjà été signalé plus tôt dans un autre forum à https://forums.oracle.com/message/9330314. Le déplacement des jars dans jboss entraînera toujours les mêmes problèmes.

2) Trouvez les fichiers sources à partir desquels les classes sont chargées et supprimez le fichier dont vous n'avez pas besoin. Trouver les pots pour les deux classes différentes en vérifiant
rs.getObject().getClass('RATINGOBJ').getProtectionDomain().getCodeSource().getLocation() oracle.sql.ARRAY.class.getProtectionDomain().getCodeSource().getLocation() - Determine which JAR file a class is from

Solutions possibles:

a) Si vous avez besoin à la fois les pots, y'll doivent déplacer le pot de rs.getObject().getClass('RATINGOBJ').getProtectionDomain().getCodeSource().getLocation()

et de créer le module comme spécifié au http://www.javaworld.com/community/node/8184.

b) Si vous ne pouvez toujours pas charger les classes comme vous le souhaitez, spécifiez la bibliothèque dans la bibliothèque du serveur jboss.

c) La dernière solution pour forcer le chargement de classes à partir d'un fichier jar particulier consiste à spécifier le fichier jar dans le chemin bootclass.

+0

'******* Objet classloader = ModuleClassLoader pour le module" deployment.ojdbc5.jar: principal "de Service Module Loader ******* Class classloader = ModuleClassLoader for Module" déploiement. Dispatch.war: main "de Service Module Loader ******* Objet jarLoc = vfs: /content/ojdbc5.jar ******* Classe jarLoc = vfs: /content/Dispatch.war/WEB -INF/lib/ojdbc5.jar ********* Classloaders sont différents *********** ' Imprimé les valeurs que vous avez suggéré. Les chargeurs de classe semblent différents. Il y a 2 déploiements sur le serveur, ojdbc5.jar pour créer une source de données et l'application elle-même qui inclut ojdbc5.jar – BBS

+0

Je n'ai toujours pas réussi à localiser la bibliothèque du serveur pour JBoss EAP. Si je supprime ojdbc5.jar de WEB_INF/lib, j'obtiens ClassNotFound et si je l'inclue. il est en conflit avec le même fichier jar que j'ai installé en tant que module à utiliser lors de la création de DataSource. Je vais essayer et tester vos solutions possibles demain. Merci. – BBS

+0

J'ai été en mesure de résoudre ce problème en utilisant la solution A. Créé un module avec ojdbc6.jar. Utilisé pour définir le pilote et créer la source de données. Ajout de jboss-deployment-structure.xml à la guerre d'application pour faire référence à ce module au lieu de l'inclure dans WEB-INF/lib. Classloaders montrent maintenant la même chose et tout semble bien fonctionner pour le moment. Ce qui complique un peu les choses, c'est que je suis nouveau chez JBoss et que j'ai échoué à réaliser les différences entre JBoss EAP 6 de RedHat et JBoss AS 7. Merci pour votre contribution. – BBS

3

Vous ne devriez pas avoir de fichiers JAR de pilote JDBC au niveau WEB-INF/lib. Les serveurs d'applications Java EE ont besoin qu'ils soient au niveau du serveur d'applications. Déplacez-le dans le répertoire serveur/lib par défaut et voyez si c'est mieux.

+0

N'est-ce pas seulement si vous voulez que le conteneur fournisse, par ex. mise en pool de connexion de base de données? Si vous faites tout vous-même, vous n'avez pas à le faire. –

+0

Assez vrai, mais pourquoi utiliser un serveur d'application et * pas * utiliser le pool de connexion? Tomcat en fait maintenant une exigence, et le servlet JBOSS/JSP est un fork de Tomcat. – duffymo

+0

Je suis d'accord. Je pense que c'est une chose ClassLoader. – darijan