有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

长时间运行Tomcat进程的类加载器中的java问题

我们在Tomcat 6.0.18上托管了web应用程序,遇到了以下问题:

有两个web应用程序WebApp1和WebApp2,它们都是相同的系统,但版本不同

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

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

如果您遇到此类问题,请告诉我

问候,, 贾坦·波雷查


共 (4) 个答案

  1. # 1 楼答案

    我在Tomcat中遇到了许许多多奇怪的类加载器——即使你自己不执行任何类加载器代码,Tomcat本身也很容易产生问题。最常见的问题似乎是反复卸载和重新加载webapp会泄漏类加载器,最终导致Tomcat内存不足

    我所看到的版本不匹配的最常见原因是Tomcat确保某些类和JAR(Tomcat本身的一部分)在webapp类路径中领先于任何其他类(commons logging似乎是最常见的例子),并且类加载器可以在你意想不到的时候加载、卸载或保留

    你能提供更多的细节吗?如果这个罐子来自第三方,很可能有人以前见过这个问题。如果它是您自己的jar,那么您在应用程序中有自己的类加载器代码吗

  2. # 2 楼答案

    我仍然没有足够的代表添加评论,所以我必须发布另一个答案。:)

    这听起来像是邮件发送者。类被加载到Tomcat中,而不是每个单独的webapp中。WebApp2首先加载它,然后它就可以工作了,即使它被加载到所有Tomcat中,而不是WebApp2专用的。当WebApp1需要这个类时,它已经看到它的类被加载到Tomcat父类中,并且不会尝试将一个私有类加载到WebApp1

    我首先建议你检查一下你的Tomcat,JRE等等。。。查看这些路径中是否有jar或类的副本。之后,我将手动从两个jar文件中删除该类,并重新启动Tomcat或web应用程序,看看会发生什么情况——您可能认为它会失败并生成堆栈跟踪,这将告诉您第一次加载类的位置以及试图加载它的人。(例如,从类名来看,您可能有一个邮件API,加载到Tomcat JVM中,将类加载到Tomcat中,而不是您的webapp中)

  3. # 3 楼答案

    您在同一台服务器上托管两个版本的完全相同的代码,有什么特别的原因吗

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

  4. # 4 楼答案

    谢谢克里斯的回复

    jar是系统的一部分,它有一些公共类,这些类由其他进程共享

    让我们称之为罐子comutils。所以这个场景是这样的

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

    这个MailSender类是singleton

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

    希望这能给你一些线索