2010-12-02 34 views
3

我有一个tomcat服务器有两个webapps(foo和bar),它们具有相同的部署战。部署使用标准的Spring/Hibernate设置。我认为这两个webapps可以启动并完全独立运行,但情况并非如此 - webapp foo加载正常,但webapp bar有一些奇怪的行为 - 就好像它使用的是来自webapp的一些相同的bean FOO。例如,当bar启动时(第二个webapp启动),c3p0会抱怨它已经被注册 - 可能是在webapp foo中。再次,我试图让这两个webapps完全独立,这样两个c3p0/hibernateSessionFactory bean就不应该彼此了解。多个Spring根WebApplicationContexts

在做一些研究时,我被引导认为在这两个webapps中都使用了相同的Spring根WebApplicationContext。如果是这样的话,我怎样才能让每个webapp(在同一个tomcat服务器上)完全独立于另一个?还有什么可能导致这个问题?从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

“抱怨它已经注册”是什么意思?例外?如果是这样,请告诉我们这个例外。 – skaffman 2010-12-02 10:56:40

+0

在日志中发出警告,说“c3p0已经被注册 - 这可能是由于上下文不能正确卸载并且可能导致内存泄漏” 我会在一个位置得到确切的日志消息 – Keith 2010-12-02 16:32:36

回答

1

我有一个suspision。是不是课堂加载问题的根源?

我想你的问题的直接原因是某些Spring类加载一次并在这两个WAR之间共享。我不知道类的确切名称,但Spring需要在一些静态字段中存储一些共享信息(至少是对应用程序上下文的引用)。然后当两个WAR看到同一个类的副本时,那么这两个应用程序都会看到这个静态字段的相同状态。我猜在你的设置中,Spring只创建一个应用程序上下文(当创建第二个应用程序时,Spring会查找现有的应用程序上下文并使用它)。

我看到潜在的两个理由这样一个问题:

  • 要么这是一个类加载问题。我不是那么想进入tomcat,也不知道如何配置它,但通常在JavaEE应用程序服务器中,有一些方法可以为WAR配置类加载。
  • 或者这是一种内存泄漏。也许这个类(和它的静态字段)是从以前的部署中重用的(不太可能,你的描述倾向于建议你在一个新的tomcat实例上遇到问题)。你可以通过确定问题出现在(重新)启动的tomcat之后来排除这种可能性。

更新: 如果这是关于类加载,我会试图找出哪些类(及其静态字段)导致问题。这可能不是你的课程,而是你在应用程序中使用的一些第三方库类。在阅读http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html后,你可以看到Tomcat为每个应用程序使用不同的无关类加载器。然而,如果他们不知道这个类,他们都会共享他们委派的父类加载器。 再一次,我不知道你的确切设置和一些Tomcat的特性,但是......在Tomcat中不可能将某些库(JAR),如c3p0或Spring,放在一些常见的'lib'文件夹中说$ CATALINA_HOME/lib)?在这种情况下,使用父类加载器(在tomcat文档中称为'Common')加载这些JAR中的类。这意味着它们只能加载一次。

为了简短起见,我猜想原因是你的$ CATALINA_HOME/lib中的一个JAR有一些依赖于某些静态字段的类。使用通用类加载器加载JAR的Tomcat策略会导致所有应用程序共享这些静态字段的状态。

我有没有告诉过你这只是一种怀疑和猜测?