Bug 37054

Summary: NoClassDefFoundError using ServletContextListener WITH CUSTOM LOADER
Product: Tomcat 5 Reporter: Christian Elsen <ehcapa.allizgub>
Component: UnknownAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED DUPLICATE    
Severity: normal CC: leroux_bruno, mabuffo
Priority: P3    
Version: 5.5.15   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Christian Elsen 2005-10-12 18:46:35 UTC
Since 5.5.12 using a ServletContextListener leads to a NoClassDefFoundError.
5.5.11 instead worked as expected with exactly the same code.

The class ServletListener is part of the web application. The web application of
course has no servlet-api.jar included as this must be provided by the servlet
engine through the appropriate classloader.

o JVM is Sun 1.5.0_05, I got the same error with 1.5.0_04.

o My web.xml:
<web-app>
   ...
    <listener>
        <listener-class>
        this.is.my.ServletListener
        </listener-class>
    </listener>   
</web-app>

o My listener class:
public class ServletListener implements ServletContextListener {
        public void contextInitialized(ServletContextEvent arg0) {...}
        public void contextDestroyed(ServletContextEvent arg0) {…}
}

o This is the error during startup:
09:09:12,579 ERROR [/myApp]:3643 - Error configuring application listener of
class this.is.my.ServletListener
java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at
org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:870)
        at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1305)
        at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1187)
        at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3640)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4127)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
        at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1012)
        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
        at org.apache.catalina.core.StandardService.start(StandardService.java:450)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:680)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:536)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:275)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
09:09:12,594 ERROR [/myApp]:3650 - Skipped installing application listeners due
to previous error(s)
Comment 1 Yoav Shapira 2005-10-16 23:33:28 UTC
Works for me on 5.5.12 right out of the box.  I'm attaching a WAR you can use to
test if you'd like, and closing this issue.
Comment 2 Christian Elsen 2005-10-20 18:18:36 UTC
Please attach the war, I'll try it against my installation and check why it
doesn't work.
Comment 3 Alfie Kirkpatrick 2006-01-04 17:44:40 UTC
I'm re-opening this as I have a project that worked fine in 5.5.9 and doesn't 
work in 5.5.12 (similar to the original poster).

I tracked the issue down to my server.xml (see below). I was using a <Loader> 
element under <Host> element. Even with an empty <Loader/> element I get the 
NoClassDefFoundError. When I take out the element completely it works.

My stack trace is:

SEVERE: Error configuring application listener of class 
org.springframework.web.context.ContextLoaderListener
java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener

My server.xml is:

<Server port="8005" shutdown="SHUTDOWN">
	<Listener className="org.apache.catalina.core.AprLifecycleListener" />
	<Listener 
className="org.apache.catalina.mbeans.ServerLifecycleListener" />
	<Listener 
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
	<Listener 
className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener" />

	<Service name="Catalina">
		<Connector port="8080" maxHttpHeaderSize="8192" 
maxThreads="150" minSpareThreads="25"
			maxSpareThreads="75" enableLookups="false" 
redirectPort="8443" acceptCount="100" connectionTimeout="20000"
			disableUploadTimeout="true" />

		<Connector port="8009" enableLookups="false" 
redirectPort="8443" protocol="AJP/1.3" />

		<Engine name="Catalina" defaultHost="localhost">
			<Host name="localhost" unpackWARs="true" 
autoDeploy="true" xmlValidation="false"
				xmlNamespaceAware="false">

				<Context path="" docBase="d:\jproj-3.1\iod-
guide\src\main\webapp">
					<Loader/>
				</Context>

			</Host>
		</Engine>
	</Service>
</Server>

This is causing trouble for me as I want to use a custom classloader derived 
from WebappClassLoader. Is there any workaround?

Thanks, Alfie.
Comment 4 Dani Pletter 2006-01-13 04:21:49 UTC
I also have a project that worked under 5.5.9, but under 5.5.15, I get this on
startup:

2006-01-12 19:00:02,351 [ERROR] main
org.apache.catalina.core.ContainerBase.[Catalina].[bolweb].[/] - Error
configuring application listener of class
org.apache.myfaces.webapp.StartupServletContextListener
java.lang.NoClassDefFoundError: javax/servlet/ServletContextListener

I am also using a loader tag in server.xml.  If i remove it, it works fine...but
I need it.
Comment 5 william.barker 2006-01-13 05:09:33 UTC
It is the responability of your custom Loader to correctly resolve the parent 
ClassLoader (by calling getParentClassLoader on the Container).  It's possible 
that the Tomcat developers could make this easier for people extending 
WebappLoader (which is why I'm not actually closing the bug), but in the 
meantime, something like:
  public void start() throws LifecycleException {
     Thread cthrd = Thread.currentThread();
     ClassLoader oldcl = cthrd.getContextClassLoader();
     cthrd.setContextClassLoader(getContainer().getParentClassLoader());
     super.start();
     cthrd.setContextClassLoader(oldcl);
  }

should do as a work-around.
Comment 6 Dani Pletter 2006-01-13 05:22:54 UTC
Thank you.  I also just found that it works if i add delegate="true" to the
loader tag.
Comment 7 Alfie Kirkpatrick 2006-01-13 21:16:07 UTC
Adding delegate="true" doesn't work for me. Even if I just have:

  <Loader delegate="true"/>

It doesn't work. NoClassDefFoundError: javax/servlet/ServletContextListener.

Also, can you confirm the sample code should go in WebappLoader and not 
WebappClassLoader. I'm overriding the latter and don't need to override 
WebappLoader (unless I need to to get this working!).

Thanks, Alfie.
Comment 8 Dani Pletter 2006-01-18 21:04:02 UTC
(In reply to comment #6)
> Thank you.  I also just found that it works if i add delegate="true" to the
> loader tag.

I was mistaken.  This actually did not work.  I also tried william's workaround
(getParentClassLoader), and it didn't help.
Comment 9 Yoav Shapira 2006-04-19 13:20:19 UTC
Changing summary text of this issue to indicate the key fact that you're using a
custom loader, and updating version to 5.5.15 per comment above.
Comment 10 Remy Maucherat 2006-04-24 13:52:52 UTC
*** Bug 37302 has been marked as a duplicate of this bug. ***
Comment 11 Remy Maucherat 2006-04-24 13:53:00 UTC
*** Bug 38877 has been marked as a duplicate of this bug. ***
Comment 12 Remy Maucherat 2006-04-24 13:58:05 UTC
- Using the setParentCL rule is not nice at all, as it (dumbly) overrides any
possible configuration which could be done when embedding.
- From what the related reports wrote, this does not affect context files (only
when the Context element is in server.xml). You should be using that
-> So overall, this bug should not get fixed (I will not bother closing it, as I
am sure it would be reopened right away, though).
Comment 13 Mark Thomas 2006-08-30 03:41:00 UTC

*** This bug has been marked as a duplicate of 39704 ***