Bug 41661

Summary: JspConfig.init() is not synchronized
Product: Tomcat 5 Reporter: Doug Hauge <doug.hauge>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 5.5.20   
Target Milestone: ---   
Hardware: Other   
OS: other   
Attachments: Patch that synchronizes initialization in 'JspConfig.init'

Description Doug Hauge 2007-02-20 13:40:39 UTC
The 'JspConfig.init()' method can be called simultaneously from multiple threads
at the same time, but it is not synchronized, so the initialization code in the
body can be executed simultaneously by multiple threads. This can lead to a
'jsp-property-group' configuration being added twice to the 'jspProperties'
vector. The symptom we noticed was that on some runs, the contents of the
'include-prelude' and 'include-coda' elements would be included twice in all
compiled jsp files.

This bug is hard to reproduce because it requires a run where the first thing
that happens is that multiple jsp files are requested simultaneously. However,
after adding a field containing a synchronization object and synchronizing on it
across the 

if (!initialized) {
...
}

block, we haven't seen the problem reoccur.
Comment 1 Doug Hauge 2007-02-20 13:44:20 UTC
Created attachment 19615 [details]
Patch that synchronizes initialization in 'JspConfig.init'
Comment 2 Remy Maucherat 2007-02-20 14:05:41 UTC
No, this additional sync will not be added. The recompilation checks should be
sufficiently synchronized already.
Comment 3 Doug Hauge 2007-02-20 16:15:38 UTC
For each page, compilation is synchronized, but it is not synchronized between
pages. This is typically not a problem because most of the state for different
pages isn't shared, but the 'JspConfig' instance is via the shared
'EmbeddedServletOptions' instance. 

Here is the top of the stack when 'JspConfig.init()' is first called:

JspConfig.init() line: 202	
JspConfig.findJspProperty(String) line: 254	
AntCompiler(Compiler).generateJava() line: 112	
AntCompiler(Compiler).compile(boolean, boolean) line: 295	
AntCompiler(Compiler).compile(boolean) line: 276	
AntCompiler(Compiler).compile() line: 264	
JspCompilationContext.compile() line: 563	
JspServletWrapper.service(HttpServletRequest, HttpServletResponse, boolean)
line: 305
JspServlet.serviceJspFile(HttpServletRequest, HttpServletResponse, String,
Throwable, boolean) line: 314	
JspServlet.service(HttpServletRequest, HttpServletResponse) line: 264	
JspServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 861	

The only synchronization that occurs in that stack is in
'JspServletWrapper.service', which synchronizes on 'this'. Each page has a
separate 'JspServletWrapper' instance, but all instances share a common
'EmbeddedServletOptions', which contains the 'JspConfig'. Thus, the
synchronization does not protect against multiple pages being compiled
simultaneously and calling 'init()' on the same 'JspConfig' instance at the same
time.

Comment 4 Mark Thomas 2009-07-17 13:16:14 UTC
Thanks for the report and the analysis.

This has been fixed in trunk and proposed for 5.5.x and 6.0.x.
Comment 5 Mark Thomas 2009-08-12 04:32:19 UTC
This has been fixed for 5.5.x and will be included in 5.5.29 onwards.
Comment 6 Mark Thomas 2009-08-12 04:41:23 UTC
This has been fixed in 6.0.x and will be included in 6.0.21 onwards.