Bug 52776 - Generator's JspFragment.invoke implementation does not reset ELContext[JspContext.class]
Summary: Generator's JspFragment.invoke implementation does not reset ELContext[JspCon...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 7.0.26
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-02-27 00:46 UTC by Karl von Randow
Modified: 2012-03-09 11:54 UTC (History)
0 users



Attachments
Patch to correct the putting/resetting of the JspContext ELContext attribute (1.44 KB, patch)
2012-03-07 22:32 UTC, Karl von Randow
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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.