DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUGĀ· RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=42438>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED ANDĀ· INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=42438 Summary: Duplicate JSP temp variable declaration when jsp:attribute used in conjunction with custom tags Product: Tomcat 5 Version: 5.0.20 Platform: All OS/Version: All Status: NEW Severity: major Priority: P2 Component: Jasper AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] Here is an example of the bug in its most primitive form: WEB-INF/jsp/test.jsp: =================================== <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> <jsp:element name="a"> <jsp:attribute name="href">http://www.apache.org</jsp:attribute> </jsp:element> <t:test /> <c:if test="${true}">it's true!</c:if> =================================== WEB-INF/tags/test.tag: =================================== <%@ tag pageEncoding="UTF-8" body-content="scriptless" %> do nothing =================================== WEB-INF/tagPlugins.xml: =================================== <tag-plugins> <tag-plugin> <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class> <plugin-class>org.apache.jasper.tagplugins.jstl.core.If</plugin-class> </tag-plugin> </tag-plugins> =================================== Once you run this through Jasper, you will get the following java code: =================================== package org.apache.jsp.WEB_002dINF.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static java.util.List _jspx_dependants; static { _jspx_dependants = new java.util.ArrayList(1); _jspx_dependants.add("/WEB-INF/tags/test.tag"); } private org.apache.jasper.runtime.TagHandlerPool _jspx_tagPool_c_if_test; public Object getDependants() { return _jspx_dependants; } public void _jspInit() { _jspx_tagPool_c_if_test = org.apache.jasper.runtime.TagHandlerPool.getTagHandlerPool(getServletConfig()); } public void _jspDestroy() { _jspx_tagPool_c_if_test.release(); } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; String _jspx_temp0 = "http://www.apache.org"; out.write("<" + "a" + " href=\"" + _jspx_temp0 + "\"" + "/>"); if (_jspx_meth_t_test_0(_jspx_page_context)) return; boolean _jspx_temp0= ((java.lang.Boolean) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${true}", java.lang.Boolean.class, (PageContext)_jspx_page_context, null, false)).booleanValue(); if (_jspx_temp0){ out.write("it's true!"); } } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context); } } private boolean _jspx_meth_t_test_0(PageContext _jspx_page_context) throws Throwable { PageContext pageContext = _jspx_page_context; JspWriter out = _jspx_page_context.getOut(); // t:test org.apache.jsp.tag.web.test_tag _jspx_th_t_test_0 = new org.apache.jsp.tag.web.test_tag(); _jspx_th_t_test_0.setJspContext(_jspx_page_context); _jspx_th_t_test_0.doTag(); return false; } } =================================== Scan that code for the temp variable named _jspx_temp0. Notice that there is one String with that name and one boolean with that name. Thus, this results in a java compilation error once you ultimately try to compile the page: =================================== Compiling 2 source files to c:\work\marzen\tmp\jspc\classes c:\work\marzen\tmp\jspc\src\org\apache\jsp\WEB_002dINF\jsp\test_jsp.java:61: _jspx_temp0 is already defined in _jspService(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) boolean _jspx_temp0= ^ c:\work\marzen\tmp\jspc\src\org\apache\jsp\WEB_002dINF\jsp\test_jsp.java:63: incompatible types found : java.lang.String required: boolean if (_jspx_temp0){ ^ Note: c:\work\marzen\tmp\jspc\src\org\apache\jsp\WEB_002dINF\jsp\test_jsp.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 2 errors =================================== The problem is caused by the fact that the Node.NamedAttribute constructor directly uses JspUtil.nextTemporaryVariableName() to generate a variable name. I *believe* that if the variable was initialized just-in-time in the getter, that the problem would be solved. The flow goes like this: 1) When compiling test.jsp, Compiler.generateJava() calls JspUtil.resetTemporaryVariableName() to reset the temp variable name 2) The test.jsp file gets parsed immediately thereafter, thus creating a variable with name _jspx_temp0 for the "href" attribute 3) Shortly thereafter, tag files are loaded, which means that the test.tag file will be recompiled, thus resulting in JspUtil.resetTemporaryVariableName() being invoked again (thus setting the variable back to 0). 4) Since test.tag doesn't do anything to cause a temporary variable name to be recreated, the temp variable name remains at 0. 5) Upon returning to the compilation of the test.jsp, the If tag plugin is used to create yet another variable name with name _jspx_temp0, hence the conflict. I think step 2 is the root of the problem. If the NamedAttribute didn't get a temporary variable name assigned in the constructor and instead generated it just-in-time in the getter, then this issue wouldn't exist since the "href" attribute variable name would be created only after first compiling all of the tag files. I still think that the logic in the compilation is a bit strange given that the JSP will use temporary variable names starting at whatever point the last compiled tag file left off at. I think that issue could be resolved by moving the JspUtil.resetTemporaryVariableName() call in Compiler.generateJava() down after the call to loadTagFiles(). Note that you would probably also want to call JspUtil.resetTemporaryVariableName() in the ctxt.isPrototypeMode() scenario. Here is the diff that I would propose for Compiler.java based on the 5.5.20 codebase: =================================== 150,152d149 < // Reset the temporary variable counter for the generator. < JspUtil.resetTemporaryVariableName(); < 157a155,156 > // Reset the temporary variable counter for the generator. > JspUtil.resetTemporaryVariableName(); 179a179,181 > // Reset the temporary variable counter for the generator. > JspUtil.resetTemporaryVariableName(); > =================================== Here is the diff I would propose for Node.java: =================================== 1791d1790 < temporaryVariableName = JspUtil.nextTemporaryVariableName(); 1837a1837,1839 > if(temporaryVariableName==null) { > temporaryVariableName = JspUtil.nextTemporaryVariableName(); > } =================================== -- Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]