Bug 52776

Summary: Generator's JspFragment.invoke implementation does not reset ELContext[JspContext.class]
Product: Tomcat 7 Reporter: Karl von Randow <karl>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 7.0.26   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: Patch to correct the putting/resetting of the JspContext ELContext attribute

Description Karl von Randow 2012-02-27 00:46:22 UTC
If a developer captures a JspFragment themselves and calls invoke on it, the JspContext.class attribute in the enclosing pageContext's ELContext is set by the generated JspFragment subclass, but not reset to its original value afterwards. Therefore after invoking a JspContext any EL expressions will be searching the wrong jspContext for attribute values.

org.apache.jasper.compiler.Generator is responsible for creating the JspFragment subclass to represent the compiled fragment. The generatePostamble() method emits generated code to set the JspContext attribute in the ELContext:

out.printil("this.jspContext.getELContext().putContext(javax.servlet.jsp.JspContext.class,this.jspContext);");

However it doesn't later put back the original value.

If you are using the <jsp:invoke> tag to invoke the fragment (which is undoubtedly what most people are doing) then the code generated by visit(Node.InvokeAction n) in Generator explicitly restores the EL context:

out.printil("jspContext.getELContext().putContext(javax.servlet.jsp.JspContext.class,getJspContext());");

However if you call invoke(Writer) on the JspFragment yourself you don't get that tidy up code.

I suggest the resolution is to have the JspFragment.invoke method tidy up after itself. It "puts" the change to the JspContext.class attribute so it should also re"put" it. Then there shouldn't be any need to restore the EL context in the generated <jsp:invoke> code.

I have tested this solution successfully.
Comment 1 Mark Thomas 2012-03-07 15:51:15 UTC
If you have a working solution, care to provide a patch?
Comment 2 Karl von Randow 2012-03-07 22:32:19 UTC
Created attachment 28437 [details]
Patch to correct the putting/resetting of the JspContext ELContext attribute

Sorry about that, I wasn't 100% sure that the solution was the right way to do it. Specifically that it is appropriate to remove the resetting of the JspContext attribute from the visit(Node.InvokeAction n) method.

However the visit(Node.InvokeAction n) doesn't set the JspContext attribute, so it probably makes sense that it doesn't reset it. The set and reset is now in the one place in FragmentHelperClass.generatePostamble().
Comment 3 Mark Thomas 2012-03-09 11:54:50 UTC
Thanks for the patch.

This has been fixed in trunk and 7.0.x and will be included in 7.0.27 onwards.