DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUGĀ·
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=37498>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED ANDĀ·
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=37498


[EMAIL PROTECTED] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|NPE in                      |[PATCH] NPE in
                   |org.apache.catalina.core.Con|org.apache.catalina.core.Con
                   |tainerBase.removeChild      |tainerBase.removeChild
            Version|5.5.12                      |5.5.16




------- Additional Comments From [EMAIL PROTECTED]  2006-03-16 03:40 -------
Okay my first patch doesn't work I've deleted it, but highlights another problem
I will generate a test case for at a later date.

I have attached a WAR test case for this bug now (works for me on 5.5.16).  A
recap of the steps needed to reproduce:

* Unzip the WAR and work with exploded WAR it to a dir TCBug37498
* Start up TC (without it deployed but with autoDeploy enabled in the webapps
directory).
* Move the TCBug37498 directory into the webapps directory and wait 30 seconds
for it to deploy.
* Then move the webapps/TCBug37498 directory outside the webapps directory maybe
into /tmp.
* Now watch the TC logs and try to access the context (or any context) from that
point on.


I found the problem is caused by a loging statement generated by TC, but it is
somehow using a logger instance that was loaded by the WebappClassLoader.

My web-application has local copies of apache-commons-logging and log4j as I
expect the to be 100% isoloted from the logging mechanism TC itself uses.


The problem occur at this point and the extra code helps you see the problem in
org/apache/catalina/core/StandardContext.java:3768 inside #listenerStop()

try {
    fireContainerEvent("beforeContextDestroyed", listener);
    listener.contextDestroyed(event);
    fireContainerEvent("afterContextDestroyed", listener);
} catch (Throwable t) {
    fireContainerEvent("afterContextDestroyed", listener);
    try {
        // This call uses the web-app's logger not TCs
        //  because some classes to perform this call are coming from the
        //  contexts WEB-INF/lib/*.jar files WebappClassLoader this call 
        //  spits out a ClassNotFoundException and that breaks TCs
        //  undeployment mechanism by now allowing #stop() to complete
        // vvvvvvvvvvvvv
        getLogger().error
         (sm.getString("standardContext.listenerStop",
         listeners[j].getClass().getName()), t);
    } catch(Throwable tt) {
        // vvvvvv I added this catch() block and the extra debug output
        // the catch block fixes the problem by returning control to TC
        // so it can complete undeployment
        System.err.println("listenerStop(): exception in ");
        tt.printStackTrace();
        System.err.println("listenerStop(): ...from... ");
        t.printStackTrace();
        System.err.println("ClassLoader on getLogger() is " +
getLogger().getClass().getClassLoader());
        System.err.println("ClassLoader on context is " +
context.getClass().getClassLoader());
        System.err.println("ClassLoader on this is " +
this.getClass().getClassLoader());
    }
    ok = false;
}


getLogger().getClass().getClassLoader() == WebappClassLoader
this.getClass().getClassLoader() == StandardClassLoader

Maybe this is 100% correct and expected behaviour.  But the problem that occurs
is the call to log the Tomcat Container situation relys on the web-apps class
files (which we just deleted/removed).

I would have expected the logger TC itself uses to be isolated from the logger
my web-app is using by the different class loaders being used.  I would guess
the $CATALINA_HOME/bin/commons-logging-api.jar would be the instance
StandardContext.getLogger() would always return.


This is the output I got with the above code in place.

Mar 16, 2006 9:41:26 AM org.apache.catalina.startup.HostConfig checkResources
INFO: Undeploying context [/TCBug37498]
DEBUG 09:41:26,106 (SecurityContextFilter.java:destroy:41)  -Executing filter
#destroy()
DEBUG 09:41:26,106 (ApplicationLifecycleListener.java:contextDestroyed:27) 
-contextDestroyed on "TCBug37498"
INFO  09:41:26,107 (ApplicationLifecycleListener.java:contextDestroyed:30) 
-contextDestroyed on "TCBug37498"  done!
listenerStop(): exception in
java.lang.NoClassDefFoundError: org/apache/log4j/spi/ThrowableInformation
        at org.apache.log4j.spi.LoggingEvent.<init>(LoggingEvent.java:154)
        at org.apache.log4j.Category.forcedLog(Category.java:388)
        at org.apache.log4j.Category.log(Category.java:853)
        at 
org.apache.commons.logging.impl.Log4JLogger.error(Log4JLogger.java:193)
        at
org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:3774)
        at 
org.apache.catalina.core.StandardContext.stop(StandardContext.java:4340)
        at
org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:892)
        at
org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1013)
        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1172)
        at
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:292)
        at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at
org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1305)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1569)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1578)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1558)
        at java.lang.Thread.run(Thread.java:595)
listenerStop(): ...from...
java.lang.NoClassDefFoundError: org/apache/log4j/helpers/NullEnumeration
        at org.apache.log4j.Category.getAllAppenders(Category.java:410)
        at org.apache.log4j.Category.closeNestedAppenders(Category.java:223)
        at org.apache.log4j.Hierarchy.shutdown(Hierarchy.java:447)
        at org.apache.log4j.LogManager.shutdown(LogManager.java:227)
        at
testpackage.ApplicationLifecycleListener.contextDestroyed(ApplicationLifecycleListener.java:34)
        at
org.apache.catalina.core.StandardContext.listenerStop(StandardContext.java:3770)
        at 
org.apache.catalina.core.StandardContext.stop(StandardContext.java:4340)
        at
org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:892)
        at
org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1013)
        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1172)
        at
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:292)
        at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
        at
org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1305)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1569)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1578)
        at
org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1558)
        at java.lang.Thread.run(Thread.java:595)
ClassLoader on getLogger() is WebappClassLoader
  delegate: false
  repositories:
    /WEB-INF/classes/
----------> Parent Classloader:
[EMAIL PROTECTED]

ClassLoader on context is [EMAIL PROTECTED]
ClassLoader on this is [EMAIL PROTECTED]


Okay.. I think I may have a proper path for this problem, during the setup of
the Context in StandardContext#start() we zap the logger instance for use while
re run some web-app related method.

I think we should also zap it again when we unbind and return that thread back
to the containter execution context so all future logging is done with TCs
logging instances from StandardClassLoader.

Please explain any specific objections to that.  I realize logging and
ClassLoaders are a nightmare.

This new patch correctly makes the error message get reported by TC and
undeployment seems to complete allowing a new deployment for the same context to
occur again.

There are other places in the StandardContext where bind and unbind are used so
maybe flipping which logging via what ClassLoader we are using should be a part
of that bind/unbind process.


-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to