2

I'm running a web application in Tomcat 7.0.53. I implement a ServletContextListener (call it InitListener) and correctly define it as a Listener in the web.xml:

  <listener>
    <description>listener that initializes common web app/service resources</description>
    <listener-class>x.y.z.InitListener</listener-class>
  </listener>

During the contextDestroyed event I would like to clean-up some code (e.g., shutdown a org.jboss.netty.channel.group.ChannelGroup using close ()), but my code always fails in this method with the error:

SEVERE: Exception sending context destroyed event to listener instance of class x.y.z.InitListener
java.lang.NoClassDefFoundError: org/jboss/netty/util/internal/ConcurrentHashMap$Values

Now, if I already use the ConcurrentHashMap$Values during the contextInitialized part of the InitListener by, e.g., calling close () on the ChannelGroup, then the shutdown works without problems.

It seems to me that during the contextDestroyed event Tomcat is not able to load the class any longer, but if it has been loaded beforehand, that there's no problem. But this can't be the solution, as I have other classes used in the contextDestroyed with the same problem. I would have to pre-load all classes I would like to use later on. Sounds like a hack to me.

What am I doing wrong? Why is Tomcat not able to load a new class any longer at this stage?

EDIT: As an additional information, the problem only occurs when I do a remote deployment of my web application. When I reload or undeploy the web application on the Tomcat it always shuts down gracefully. Just during remote deployment, the shutdown fails.

Michael
  • 202
  • 2
  • 8
  • Interesting problem. Tomcat loads each web application in its own private classloader to be able to isolate web application classpaths from each other so it might have something to do with that... but I wouldn't be able to explain why that would cause this problem. As a sort of ultra-hack-test to possibly take possibilities off the list, if you put the offending jar in tomcat/lib rather than your web application, does the problem then "go away" ? – Gimby Oct 20 '14 at 14:28
  • Did you try copying the jar in the webapp's runtime classpath, such as `WEB-INF/lib`? – Cristian Greco Oct 20 '14 at 14:44
  • @Gimby Your "ultra-hack-test" works. When I copy the libs containing the not loadable classes (there are two) to the tomcat/lib folder, then the problem during remote deployment is gone. But as you call it ultra hack, this is not really a feasable solution for production. – Michael Oct 21 '14 at 10:06
  • @CristianGreco What do you mean with "copy the jar"? Where to? They all are in the WEB-INF/lib folder. – Michael Oct 21 '14 at 10:08
  • No it was only a test. So it probably has to do with how Tomcat handles cleaning up the classloader for a web application... At this point I wouldn't have a clue how to proceed other than what you have already found - to force preloading of classes you need during cleanup. It might be interesting to take this question to some form of Tomcat mailing list where the developers can see it – Gimby Oct 21 '14 at 11:23
  • Thanks, I have just filed a bug report with Tomcat. I'll keep you posted if they confirm this is a bug and fix it. – Michael Oct 21 '14 at 11:52

1 Answers1

2

I just got an answer from the Tomcat developers. As Gimby already assumed, the problem was due to a bug in Tomcat. It is fixed in version 7.0.54 and higher.

Thanks for your help.

Michael
  • 202
  • 2
  • 8
  • 1
    Original issue ticket that represents the fix: https://issues.apache.org/bugzilla/show_bug.cgi?id=56321 – Gimby Oct 21 '14 at 15:36