Bug 36802

Summary: Embeded Tomcat Initialises Context Twice
Product: Tomcat 5 Reporter: Darran Lofthouse <darran>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 5.5.9   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: Update to StandardContext to prevent double initialisation.

Description Darran Lofthouse 2005-09-24 22:38:53 UTC
Using JBoss 4.0.2 (With embeded Tomcat 5.5.9) when a web application is deployed
the context is initialised twice.  If you deploy a web application with a valve
defined in 'WEB-INF/context.xml' of the application the valve will be registered
twice and invoked twice for any invocation of the application.

When Tomcat is run stand alone the deployer instantiates a new StandardContext
and adds it as a child to the StandardHost, this in turn invokes the init method
of the StandardContext - This correctly initialses the context based on the
configuration.

When Tomcat is embeded in JBoss the StandardContext is initialised, the host at
this stage is not available so JBoss invokes init on the StandardContext.  At
the top of the init method the context checks if it is associated with a parent
host as it is not the parent host is identified and the StandardContext added to
the parent.  The process of adding the context to the host causes the init
method of the context to be invoked again.

Although I have reported this against an older Tomcat version the affected code
has not been altered in the recent releases.

I will attach a patch that contains a proposed fix.  The proposed fix simply
checks if the context has been initialised before performing the initialisation,
if the initialisation has already been performed the initialisation is skipped.
Comment 1 Darran Lofthouse 2005-09-24 22:40:35 UTC
Created attachment 16519 [details]
Update to StandardContext to prevent double initialisation.
Comment 2 william.barker 2005-09-25 00:31:24 UTC
In 5.5.9, the call to init from addChild only happens if you are deploying the 
Context into a Host that has already been started.  In that case, your patch 
doesn't do anything useful since the 'initialized' variable still won't be set 
on the second call to init.
Comment 3 Darran Lofthouse 2005-09-25 01:28:07 UTC
Thank you for your comment.

The host has already been started by the time the web application is deployed.

The getParent method constructed the correct ObjectName for the host and it was
found correctly.

Yes for the second call initialized will not be set, however the first call will
be blocked on the invoke on line 5005.

The second call will complete and control will return to the first, initialized
will now be true so the initialisation will not happen again (for the first call).
Comment 4 william.barker 2005-09-25 02:33:10 UTC
Ok, I see now.  I was thinking that you were trying to stop init being called 
twice (which doesn't seem possible with the current JMX-deployment scheme).

You're patch is still sending the JMX Notification twice, so by the time you 
add that, it seemed much simplier to simply do:
  if( initialized ) {
      return;
  }
So that is what got committed to the CVS, and will appear in 5.5.13.