|Summary:||Jasper creates duplicate variable names|
|Product:||Tomcat 6||Reporter:||Stefan Birkner <Stefan.Birkner>|
|Component:||Jasper||Assignee:||Tomcat Developers Mailing List <dev>|
WAR of a test application to reproduce the bug
Patch to be applied to the package org.apache.jasper.compiler
Description Stefan Birkner 2008-08-26 07:23:33 UTC
Sometimes a JSP's Java code, which have been generated by Jasper, has duplicate variable names. Therefore the JSP cannot be compiled and tomcat delivers an HTTP status code 500. You get an error message like this org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 10 in the jsp file: /test1.jsp Duplicate local variable _jspx_temp0 7: <c:set var="a"> 8: <jsp:attribute name="value"><%= new java.util.Date().toString() %></jsp:attribute> 9: </c:set> 10: <c:set var="b"> 11: <jsp:attribute name="value"><%= new java.util.Date().toString() %></jsp:attribute> 12: </c:set> 13: <h1>Test 1</h1> The reason of this error is the generation of variable names like _jspx_temp0, which are created for <jsp:attribute> tags. At the beginning of parsing a JSP file a counter is reset to 0. Every time an <jsp:attribute> tag occurs, the counter is used to build a variable name _jspx_temp<counter>. Thereafter the counter will be incremented. Unfortunately the counter is a static member of the JspUtil class. Suppose there's a thread 1, which created _jspx_temp4. The counter is 5. Now a second thread (thread 2) starts and resets the counter. Afterwards thread 2 creates _jspx_temp0 to _jspx_temp3. The counter is 4 by now. Then thread 2 stops and thread 1 continues. The next variable's name in thread 1 will be _jspx_temp4, which already exists. Therefore the generated java class cannot be compiled.
Comment 1 Stefan Birkner 2008-08-26 07:31:41 UTC
Created attachment 22482 [details] WAR of a test application to reproduce the bug Here is a WAR, which can be used to replay the bug. After installing the war, you have to start your tomcat and a debugger. Then do the following steps: * set a breakpoint on JspUtil.nextTemporaryVariableName() * open /duplicateVariableName/test1.jsp in your browser * your debugger stops at JspUtil.nextTemporaryVariableName() * resume the debugger * again your debugger stops at JspUtil.nextTemporaryVariableName() * open /duplicateVariableName/test2.jsp in your browser * your debugger stops at JspUtil.nextTemporaryVariableName() * switch to the thread of /duplicateVariableName/test1.jsp * resume the debugger * the browser window of /duplicateVariableName/test1.jsp shows the error
Comment 2 Stefan Birkner 2008-08-26 07:49:41 UTC
Created attachment 22483 [details] Patch to be applied to the package org.apache.jasper.compiler This patch changes two classes: org.apache.jasper.compiler.Generator and org.apache.jasper.compiler.Node. Instead of creating the variable names of NamedAtttributes when parsing the JSP code, the names are created when the Generator generates the java code. The Generator class has two additional members: an HashMap<NamedAttribute, String> variableNamesOfNamedAttributes, which stores the mapping between NamedAttributes and there variable names, and a variableNameCounter, which is used to create the variables' names. The new method getVariableName(NamedAttribute) returns the variable names. The member temporaryVariableName and its getter getTemporaryVariableName() are removed from the node class.
Comment 3 Mark Thomas 2008-08-31 07:05:46 UTC
I have fixed this in trunk with a more general fix that should address all possible issues if this nature. The fix has been proposed for 6.0.x
Comment 4 Mark Thomas 2008-10-24 14:03:33 UTC
This has been applied to 6.0.x and will be included in 6.0.19 onwards.