2010-06-19 5 views
2

Si j'ai des classes qui doivent être partagées entre ma webapp et Tomcat (par exemple un domaine et un domaine personnalisés), où va le fichier .jar contenant ces classes?Classloaders et partage de fichiers .jar avec Apache Tomcat

Actuellement, je mets le .jar dans $ {CATALINA_HOME}/lib. Ce résultat est une exception ClassCastException lors de l'attribution de références à partir de classes du même type. Voici un exemple:

MyCustomPrincipal principal = (MyCustomPrincipal)FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); 

La méthode ci-dessus génère une exception ClassCastException. La méthode renvoie un type MyCustomPrincipal réel (puisque c'est ce que mon domaine personnalisé a donné à Tomcat lors de l'authentification) qui, apparemment, a été créé par un chargeur de classe différent. Comment puis-je résoudre ce problème afin que Tomcat et ma webapp puissent utiliser MyCustomPrincipal?

http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

Toute aide est appréciée. Andrew

+0

Avez-vous une autre copie du JAR dans votre webapp? –

+0

Oui, le fichier .war qui est déployé sur Tomcat contient MyCustomPrincipal.class. – Andrew

Répondre

4

Il semble que vous ayez 2 copies chargées, une fois dans Tomcat et une fois dans vos fichiers jar WEB-INF/lib ou autre classpath de votre application déployée.

La raison pour laquelle vous obtenez une exception classpath réside dans la façon dont un WAR recherche des classes. Contrairement aux règles Java normales, une guerre regarde d'abord à l'intérieur de la guerre pour une classe et passe ensuite la requête au classloader parent.

L'identité d'une classe dépend du chargeur de classe et la même classe chargée dans 1 classloader générera une exception de classification lorsqu'elle est castée dans l'autre chargeur de classe.

La solution est de s'assurer que la guerre ne contient pas les classes qui devraient être fournies par le conteneur. Si vous utilisez maven vous pouvez marquer ces dépendances comme 'fournies', si vous utilisez ant, vous devez diviser votre liste de classes en 2 et compiler les deux, mais n'utilisez que celles dont vous avez besoin pour construire la guerre.

+0

ok, cela a du sens. Si je comprends bien, je dois être sûr qu'il n'y a qu'une seule source pour le fichier de classe. J'utilise NetBeans, qui utilise Ant pour générer le fichier .war. Actuellement, j'ai mis à jour le build.xml pour pré-déployer le fichier .jar contenant mon principal et domaine personnalisé à $ {CATALINA_HOME}/lib. Puis-je simplement mettre à jour le build.xml et dire à Ant de ne pas déployer MyCustomPrincipal.class dans le fichier .war? – Andrew

+0

oui, si c'est le seul, ajoutez une ligne d'exclusion. S'il y a plus de doublons, il vaut mieux garder 2 listes. –

+0

Merci beaucoup pour votre aide. J'apprécie vraiment cela. – Andrew