David Delbecq wrote:
I experienced a strange behaviour of tomcat a few minutes ago. Container
is configured to do webapp auto reloading when classes changes. I
updated a few WEB-INF/classes/*.properties. Tomcat decided it's time to
reload the webapp because classes did change. However, it killed it's
own webapp loader Thread using a ThreadDeath. As a result, the webapp is
not accessible anymore. I suppose it's a bug from the webapp reloader,
but before submission to bug tracker, i'd appreciate comments.
The result of this problem is
1) webapp does not exist anymore (404 while trying to access it)
2) webapp is marqued in manager as not started, but trying to start it
result in an 'already started' error
3) you must either restart tomcat, either undeploy/redploy the webapp to
get it back working
I have also experienced behavior similar to what you describe. I have
been able to categorize a few distinct variants. First of all, can you
reliably re-create the variant you have just witnessed ?
For some reason that I don't understand the container chooses to use a
logger instance that is loaded through the WebappClassLoader for its own
purposes. Maybe this is mandated in specifications, maybe this is so
that a web-app has some control internally over context related logging
events the container generates. But in my own testing if the container
sticks with its own logger instance (not loaded via WebappClassLoader)
then it remain inert to (mis)configuration effects the web-app chooses
to make.
I believe the variant you witnessed can be reduced into a simple
situation where the web-application might reconfigure its logger
instance (which it rightfully believes its own to do so) in such a way
to cause problems to the container when it tries to use it later. This
problem shows up in a future container logging event.
In your case I think
org.apache.catalina.core.StandardWrapper#loadServlet() made an innocent
call to log.error().
Unfortunately this resulted in an exception being thrown. This does not
have to be a ThreadDeath exception, it could be almost any Throwable,
the root problem here is that TC expects its logger to never throw an
exception no matter what and in some ways a best-effort logger should
behave this way. One solution could be to wrap all foreign logger
instance usage inside the container to catch and eat both Exceptions,
Errors (aka Throwables). Or make sure the container's internal code
never calls a foreign logger, i.e. keep the well configured on that the
JVM or StandardClassLoader seems to have. Back to your situation.
Then unfortunately TC was executing inside internal code at the time.
Then unfortunately the Thread of execution for
org.apache.catalina.core.StandardContext#loadOnStartup() in version
5.5.16 and older was not adequately protected against exceptions
occurring in the moment your stack trace show so the threads assigned
class loader got hosed. So even if it could have recovered its
remaining execution would have been with the wrong class loader.
Remy has committed a couple of patches a week or so ago, which would
address some of these matters for this particular variant, maybe the
background threads now survives to be invoked again, maybe the thread
classloader assignment is protected.
For me this is a major problem during development, where an integrated
IDE is modifying the file layout from under the container, this the
situation I am continuously getting stung in, maybe in the future some
guidelines and improvements could be made to allow more seamless
development in this way (even with major performance loss or complexity
to achieve) such a solution would result in even greater web-app
development speeds and much less headache.
--
Darryl L. Miles
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]