2008-11-25 89 views
2

我们已经举办了在Tomcat 6.0.18 Web应用程序,并经历了以下几个问题:问题的类加载器在长时间运行的Tomcat进程

有两个Web应用程序WebApp1和webapp2的,都是同一个系统,但不同的版本。

现在的问题是,当tomcat已经运行了一周或更长的时间,然后有时系统会给出NoClassDefFoundError!我们也遇到了一些奇怪的问题,WebApp1的Class Loader加载了WebApp2 jar中的类! WebApp1中也存在相同的jar,但版本不同。

当我们重新启动Tomcat时,一切都开始正常工作!我们的JRE是1.5.10

请让我知道你是否遇到过这样的问题。

问候, Jatan Porecha

回答

1

我遇到使用Tomcat的类加载器古怪的很多很多味道 - 即使你自己都不执行任何代码的类加载器,它很容易为Tomcat本身产生的问题。最常见的问题似乎是反复卸载并重新加载Web应用程序泄漏类加载器,并最终运行Tomcat内存不足。

我发现版本不匹配的最常见原因是Tomcat确保某些类和jar(Tomcat本身的一部分)在webapp类路径中的任何其他类之前 - commons-logging似乎是最常见的示例 - 当你不期望的时候,可以加载,卸载类装载器,或者保持它。

您能否提供一些更多的细节 - 如果jar是来自第三方,那么以前有人很可能会看到这个问题。如果它是你自己的jar,那么你在应用程序中是否有你自己的classloader代码?

0

感谢克里斯的回应。

该jar已成为系统的一部分,并具有一些其他进程共享的公共类。

让我们称之为罐子comutils.jar所以情况是一样的东西,

 
WebApp1 (ver 1) 
    | 
    |- comutils.jar (ver 1) 
     | 
     |- MailSender.class (ver 1) 


WebApp2 (ver 2) 
    | 
    |- comutils.jar (ver 2) 
     | 
     |- MailSender.class (ver 2) 

这MailSender类是单身。

现在有时会发生什么情况是,每当WebApp1的代码在使用getInstance方法检索其实例后调用MailSender的任何方法时,实际调用将转到MailSender(版本2)而不是版本1!

希望这会给你一些主角。

+0

我认为这是_far_你就越有可能在WebApp1的类路径中某处部署comutils.jar额外的版本比它是Tomcat的ClassLoader是突然从外面的类路径加载类...检查MailSender.class仅位于一个地方。 – 2008-11-25 19:21:45

1

我还没有足够的代表添加评论,所以我不得不张贴另一个答案。 :)

这听起来像MailSender.class越来越加载到Tomcat,而不是每个单独的Web应用程序。 WebApp2首先加载并运行,即使它被加载到所有非WebApp2专用的Tomcat中。当WebApp1需要该类时,它已经将其加载到Tomcat父级中,并且不会尝试将一个私有加载到WebApp1。

我首先建议你检查一下你的Tomcat,JRE等目录,看看有没有某种方式的jar或这些路径中的类的副本。之后,我会手动从两个jar文件中删除这个类,并重新启动Tomcat或Web应用程序,以查看会发生什么 - 您会希望它失败并生成堆栈跟踪,并且会告诉您您的类首次加载的位置谁试图加载它。 (例如,从类名中可能会得到一个邮件API,加载到Tomcat JVM中,将类加载到Tomcat中,而不是加载到Web应用程序中)。

1

是否有一个特定的原因,你在同一台服务器上托管2个完全相同的代码版本?

拥有2个不同的名称完全相同的jar包含相同名称空间中的类,并且具有相同的类名似乎会导致各种问题(其中最重要的是人为错误)。

相关问题