2010-12-02 21 views
3

J'ai un serveur Tomcat avec deux webapps (foo et bar) qui ont une guerre de déploiement identique. Le déploiement utilise l'installation Spring/Hibernate standard. J'ai supposé que ces deux webapps démarreraient et fonctionneraient complètement indépendamment l'une de l'autre, mais ce n'est pas le cas - fappe de foo de webapp normalement, mais la barre de webapp a un comportement étrange - c'est comme si elle utilisait certains des mêmes beans de webapp foo. Par exemple, quand la barre démarre (la deuxième webapp démarre), c3p0 se plaint qu'elle est déjà enregistrée - probablement dans webapp foo. Encore une fois, j'essaie de rendre les deux webapps complètement indépendants, de telle sorte qu'il ne devrait pas y avoir moyen pour les deux beans c3p0/hibernateSessionFactory de se connaître les uns les autres.racine de printemps WebApplicationContexts

En faisant des recherches, j'ai été amené à croire que le même WebApplicationContext de Spring Spring est utilisé dans les deux webapps. Si tel est le cas, comment puis-je rendre chaque webapp (sur le même serveur Tomcat) complètement indépendant l'un de l'autre? Y a-t-il autre chose qui pourrait causer ce problème?

extraits pertinents de web.xml:

<web-app> 
    <context-param> 
     <param-name>org.hibernate.tags.sessionFactory</param-name> 
     <param-value>hibernate/SessionFactory</param-value> 
    </context-param> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/context/*Context.xml</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>fooServlet</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
</web-app> 
+0

Que signifie "se plaint qu'il est déjà enregistré"? Une exception? Si oui, montrez-nous l'exception. – skaffman

+0

un avertissement dans le journal qui indique que quelque chose comme "c3p0 a déjà été enregistré - cela peut être dû à un contexte ne déchargeant pas correctement et peut entraîner une fuite de mémoire" je vais obtenir le message de journal exact dans un peu – Keith

+0

l'avertissement exact est: com.mchange.v2.c3p0.management.ActiveManagementCoordinator: 56 - Un mbean C3P0Registry est déjà enregistré. Cela signifie probablement qu'une application utilisant c3p0 n'a pas été déployée, mais toutes les PooledDataSources n'ont pas été fermées avant le déploiement. Cela peut entraîner des fuites de ressources au fil du temps. Veuillez prendre soin de fermer toutes les PooledDataSources. – Keith

Répondre

1

J'ai un suspision. La classe ne charge-t-elle pas la racine de votre problème?

Je suppose que la raison directe de votre problème est qu'une classe Spring est chargée une fois et partagée entre ces deux WAR. Je ne connais pas le nom exact de la classe, mais Spring doit stocker certaines informations partagées (au moins la référence au contexte de l'application) dans un champ statique. Ensuite, lorsque deux WAR voient la même copie de la classe, les deux applications voient le même état de ce champ statique. Je suppose que dans votre configuration, Spring ne crée qu'un seul contexte d'application (lorsque le second doit être créé, Spring trouve un contexte d'application existant et l'utilise à la place).

Je vois deux raisons possibles pour un tel problème:

  • soit c'est une question de chargement de classe. Je ne suis pas dans Tomcat et n'ai aucune idée de comment et si vous pouvez configurer cela, mais généralement dans les serveurs d'applications JavaEE il y a un moyen de configurer le chargement des classes pour les WAR.
  • ou c'est une sorte de fuite de mémoire. Peut-être que la classe (et son champ statique) est réutilisée depuis un déploiement précédent (peu probable, votre description tend à suggérer que vous rencontrez le problème sur une nouvelle instance de tomcat). Vous pouvez exclure cette possibilité en vous assurant que le problème apparaît juste après votre (re) démarrage de Tomcat.

MISE À JOUR: Si ceci est au sujet de chargement de classe, je voudrais essayer de comprendre quelle classe (et son champ statique) pose des problèmes. Ce n'est probablement pas votre classe mais une classe de bibliothèque tierce que vous utilisez dans votre application. Après avoir lu http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html, vous pouvez voir que Tomcat utilise différents chargeurs de classes indépendants pour chaque application. Cependant, les deux partagent les chargeurs de classe parent auxquels ils délèguent s'ils ne connaissent pas la classe. Encore une fois, je ne connais pas votre configuration exacte et certaines particularités de Tomcat, mais ... N'est-il pas possible dans Tomcat de mettre une librairie (JAR), comme c3p0 ou Spring, dans un répertoire 'lib' commun (les docs dit $ CATALINA_HOME/lib)? Dans ce cas, les classes de ces fichiers JAR sont chargées à l'aide du chargeur de classe parent (celui appelé «Common» dans les documents tomcat). Cela implique qu'ils ne sont chargés qu'une seule fois. Pour rendre l'histoire courte, je suppose que la raison en est que l'un des fichiers JAR de votre $ CATALINA_HOME/lib a une classe qui dépend fortement de certains champs statiques. La règle Tomcat pour charger les fichiers JAR à l'aide du chargeur de classe Commun aboutit à toutes les applications partageant l'état de ces champs statiques.

Est-ce que je vous ai dit que ce n'est qu'un soupçon et deviner?

+0

la première raison semble probable. Donc, pour décoller où Grzegorz s'est arrêté, quelqu'un sait comment faire Tomcat utiliser un chargeur de classe différente pour chaque application Web? – Keith

+1

@Keith, avez-vous mis (ou avez-vous par d'autres moyens) Spring ou c3p0 dans le $ CATALINA_HOME/lib? –

+0

Je n'ai rien d'inhabituel dans $ CATALINA_HOME/lib, et le doc semble suggérer que tant que tous mes jars sont dans leur webapp respective (qu'ils sont), il devrait y avoir aucun conflit. Peut-être que c'est un problème spécifique c3p0/hibernate. – Keith