我们已经在Tomcat 6.0.18上托管了我们的Web应用程序,并遇到了以下问题:
有两个Web应用程序WebApp1和WebApp2,它们都是相同的系统,但版本不同。
现在的问题是当tomcat运行一周或更长时间后,有时系统会给出NoClassDefFoundError!还有一些奇怪的问题,WebApp1的类加载器已经加载了WebApp2 jar中的类! WebApp1中也存在相同的jar,但版本不同。
当我们重新启动Tomcat时,一切正常!我们的JRE是1.5.10
如果您遇到此类问题,请与我们联系。
此致 Jatan Porecha
答案 0 :(得分:1)
我在Tomcat中遇到过很多种类的类加载器怪异 - 即使你自己不执行任何类加载器代码,Tomcat本身也很容易产生问题。最常见的问题似乎是反复卸载和重新加载webapp泄漏类加载器并最终运行Tomcat内存不足。
我看到版本不匹配的最常见原因是Tomcat确保某些类和jar(Tomcat本身的一部分)领先于webapp类路径中的任何其他类 - commons-logging似乎是最常见的示例 - 并且可以在你不期望的时候加载,卸载或保存类加载器。
你能否提供更多细节 - 如果罐子来自第三方,那么很有可能以前有人见过这个问题。如果它是你自己的jar,那么你在应用程序中是否有自己的类加载器代码?
答案 1 :(得分:1)
我仍然没有足够的代表添加评论,所以我必须发布另一个答案。 :)
这听起来好像MailSender.class被加载到Tomcat中,而不是加载到每个单独的webapp中。 WebApp2首先加载它并且它可以工作,即使它被加载到所有Tomcat而不是WebApp2私有。当WebApp1需要该类时,它已经将其加载到Tomcat父级中,并且不会尝试将一个私有加载到WebApp1。
我首先建议你检查你的Tomcat,JRE等目录,看看是否有某种方式的jar或类的路径副本。之后,我将从两个jar文件中的每个文件中手动删除该类,然后重新启动Tomcat或Web应用程序以查看会发生什么 - 您会期望它失败并生成堆栈跟踪,这将告诉您类首次加载的位置谁试图加载它。 (例如,从类名称,您可能有一个邮件API,加载到Tomcat JVM中,将类加载到Tomcat中,而不是加载到您的webapp中)。
答案 2 :(得分:1)
您是否有特殊原因要在同一台服务器上托管完全相同代码的2个版本?
拥有2个不同的jar,名称完全相同,包含相同名称空间的类,并且具有相同的类名,似乎会导致各种问题(其中最重要的是人为错误)。
答案 3 :(得分:0)
感谢Chris的回复。
jar已经成为系统的一部分,并且有一些由其他进程共享的公共类。
让我们调用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 !!
希望这会给你带来一些好处。