Bug 29093 - When reloading context IllegalStateException is not catched
Summary: When reloading context IllegalStateException is not catched
Status: RESOLVED WONTFIX
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 5.0.24
Hardware: PC Linux
: P3 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-05-19 15:44 UTC by Igor
Modified: 2004-11-16 19:05 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Igor 2004-05-19 15:44:58 UTC
We have noticed the following behaviour of manager application: sometimes when 
reloading context, it is stopped and than it is not started. It happens when 
server is heavily loaded.

We think, that the reason of it is the following:

org.apache.catalina.core.StandardContext, method reload()

...
        try {
            stop();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardContext.stoppingContext"), e);
        }

        try {
            start();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardContext.startingContext"), e);
        }
...

Method stop() can throw a runtime exception 
(org.apache.catalina.session.StandardSession):

    public void removeAttribute(String name, boolean notify) {

        // Validate our current state
        if (!isValid())
            throw new IllegalStateException
                (sm.getString("standardSession.removeAttribute.ise"));

        removeAttributeInternal(name, notify);

    }



Is it possible to catch this exception:


        try {
            stop();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardContext.stoppingContext"), e);
        } catch (IllegalStateException illegalStateException) {
            log.error(sm.getString("standardContext.stoppingContext"), 
illegalStateException);
        }


Stack trace is provided:

java.lang.IllegalStateException: removeAttribute: Session already invalidated
        at org.apache.catalina.session.StandardSession.removeAttribute
(StandardSession.java:1144)
        at org.apache.catalina.session.StandardSession.removeAttribute
(StandardSession.java:1119)
        at org.apache.catalina.session.StandardSession.writeObject
(StandardSession.java:1401)
        at org.apache.catalina.session.StandardSession.writeObjectData
(StandardSession.java:899)
        at org.apache.catalina.session.StandardManager.doUnload
(StandardManager.java:539)
        at org.apache.catalina.session.StandardManager.unload
(StandardManager.java:485)
        at org.apache.catalina.session.StandardManager.stop
(StandardManager.java:687)
        at org.apache.catalina.core.StandardContext.stop
(StandardContext.java:4474)
        at org.apache.catalina.core.StandardContext.reload
(StandardContext.java:3015)
        at org.apache.catalina.manager.ManagerServlet.reload
(ManagerServlet.java:1014)
        at org.apache.catalina.manager.HTMLManagerServlet.reload
(HTMLManagerServlet.java:477)
        at org.apache.catalina.manager.HTMLManagerServlet.doGet
(HTMLManagerServlet.java:100)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:157)
        at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:214)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:104)
        at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:520)
        at org.apache.catalina.core.StandardContextValve.invokeInternal
(StandardContextValve.java:198)
        at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:152)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:104)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke
(AuthenticatorBase.java:540)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:102)
        at org.apache.catalina.valves.RequestFilterValve.process
(RequestFilterValve.java:287)
        at org.apache.catalina.valves.RemoteAddrValve.invoke
(RemoteAddrValve.java:84)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:102)
        at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:520)
        at org.apache.catalina.core.StandardHostValve.invoke
(StandardHostValve.java:137)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:104)
        at org.apache.catalina.valves.ErrorReportValve.invoke
(ErrorReportValve.java:117)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:102)
        at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:520)
        at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:109)
        at org.apache.catalina.core.StandardValveContext.invokeNext
(StandardValveContext.java:104)
        at org.apache.catalina.core.StandardPipeline.invoke
(StandardPipeline.java:520)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
        at org.apache.coyote.tomcat5.CoyoteAdapter.service
(CoyoteAdapter.java:160)
        at org.apache.coyote.http11.Http11Processor.process
(Http11Processor.java:793)
        at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnectio
n(Http11Protocol.java:702)
        at org.apache.tomcat.util.net.TcpWorkerThread.runIt
(PoolTcpEndpoint.java:571)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run
(ThreadPool.java:644)
        at java.lang.Thread.run(Thread.java:534)
Comment 1 Igor 2004-06-07 05:05:54 UTC
Could somebody please comment this bug? It was opened two weeks ago ...

I think, code should be changed to:

        try {
            stop();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardContext.stoppingContext"), e);
        } catch (IllegalStateException illegalStateException) {
        }
Comment 2 Remy Maucherat 2004-06-07 07:27:33 UTC
Ok, I'll comment: I think not, this case requires user intervention. How about
trying to find the cause of the exception instead ? (which I don't get, but was
the only reason why I didn't close your bug as INVALID in the first place)
Comment 3 Igor 2004-06-07 09:36:41 UTC
Yes, I agree, I have to find a reason of this behavior. But please imagine the 
situation: server is loaded with 500 – 1000 sessions or even more. And there is 
a necessity of reloading context. And if this situation occurs, application 
will not be available for several minutes, because the only thing we can do – 
restart tomcat.

It is very convenient – possibility of context reload, but now we afraid reload 
context because if this happens, it is the same as tomcat restart.


I am sorry, I do not know tomcat structure well enough. I may be wrong, but I 
have a hypothesis how this can happen.

There is background thread that calls StoreBase.processExpires() method. This 
method walks through sessions and it may call StandardSession.recycle() or 
StandardSession.expire(). Both of this methods may set the following fields of 
Session object:

expiring         to          false;
isValid           to          false;
accessCount   to         0;



Suppose, we reloading context - in StandardManager.doUnload we walk through 
sessions and call writeObjectData on each session, which will call writeObject 
method. It calls removeAttribute method, which may throw a runtime exception, 
if isValid() == false.

isValid() == false 

if 

expiring == false;
isValid  == false;
accessCount == 0;

Suppose, at the same time background thread sets this fields to

expiring = false;
isValid  = false;
accessCount = 0;

Than we will have this situation.

I do not know is this hypothesis true or not. I may be wrong, but it is 
important for us that is why I am moving a suggestion.

Could you please tell your opinion?
Comment 4 Yoav Shapira 2004-06-10 23:50:46 UTC
I would probably -1 catching this exception, as I'd like tomcat's lifecycle 
handling code to handle lifecycle exceptions only, and leave other things 
higher up the hierarchy.

If you really need this functionality, at least for the time being, I suggest 
extending StandardContext with your own context.  This is why Tomcat is open-
source and why we have the className attribute on the Context element: it's 
trivial to extend and customize.  If over time you can't find a cause and are 
convinced your fix is essential to the global tomcat community, we can reopen 
this bug and/or re-discuss this issue on the tomcat-dev list.  So for now I'm 
closing it.  If you do customize StandardContext and it works, please post 
your findings to tomcat-user, to see if others find it helpful.