I'm using Struts 1.2. I've upgrade from tomcat 6.0.20 to 6.0.24 and nothing works. The jsp compilation throws many error (i use the tag bean:define with same variable many times in jsp): During jsp precompilation: "my_variable" is already defined in _jspService(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) and at runtime: 26-gen-2010 10.16.43 org.apache.catalina.core.ApplicationDispatcher invoke GRAVE: Servlet.service() for servlet jsp threw exception org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 459 in the generated java file Duplicate local variable configurationExists An error occurred at line: 576 in the generated java file Duplicate local variable configurationExists An error occurred at line: 693 in the generated java file Duplicate local variable configurationExists An error occurred at line: 810 in the generated java file Duplicate local variable configurationExists An error occurred at line: 927 in the generated java file Duplicate local variable configurationExists An error occurred at line: 1.045 in the generated java file Duplicate local variable configurationExists An error occurred at line: 1.162 in the generated java file Duplicate local variable configurationExists An error occurred at line: 1.279 in the generated java file Duplicate local variable configurationExists An error occurred at line: 1.396 in the generated java file Duplicate local variable configurationExists An error occurred at line: 1.531 in the generated java file Duplicate local variable patientsExists An error occurred at line: 1.660 in the generated java file Duplicate local variable patientsExists An error occurred at line: 1.777 in the generated java file Duplicate local variable patientsExists An error occurred at line: 1.897 in the generated java file Duplicate local variable multiportionExists An error occurred at line: 2.014 in the generated java file Duplicate local variable multiportionExists An error occurred at line: 2.131 in the generated java file Duplicate local variable multiportionExists An error occurred at line: 2.251 in the generated java file Duplicate local variable generalExists An error occurred at line: 2.368 in the generated java file Duplicate local variable generalExists An error occurred at line: 2.485 in the generated java file Duplicate local variable generalExists An error occurred at line: 2.605 in the generated java file Duplicate local variable messagesExists An error occurred at line: 2.722 in the generated java file Duplicate local variable messagesExists An error occurred at line: 2.842 in the generated java file Duplicate local variable printFindExists An error occurred at line: 2.959 in the generated java file Duplicate local variable printFindExists Stacktrace: at org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHandler.java:92) at org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.java:330) at org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:439) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:334) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:312) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:299) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:589) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551) at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488) at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968) at org.apache.jsp.WEB_002dINF.pages.login.mainPage_jsp._jspService(mainPage_jsp.java:206) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1062) at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:386) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:229) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.java:1062) at org.apache.struts.action.RequestProcessor.processForwardConfig(RequestProcessor.java:386) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:229) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:558) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619) Before upgrading to 6.0.24 all works fine. Reading the documentation of bean:define in struts javadoc i see this message: USAGE NOTE - There is a restriction in the JSP 1.1 Specification that disallows using the same value for an id attribute more than once in a single JSP page. Therefore, you will not be able to use <bean:define> for the same bean name more than once in a single page. But i've not specify any jsp version. So, is this a tomcat 6.0.24 regression bug? I've not particular compilation type/version specified in my app.
If you could attach the simplest possible JSP that demonstrated this issue that would be very helpful. As a work-around, try using the following in your web.xml: <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> ... </webapp>
Hi Mr, Thanks for reply, My web.xml is alredy 2.5 version...i've try your code with no results. I have an application with only struts (1.2.8). I have a welcome page. <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <bean:define id="configurationExists" toScope="request" value="0"/> //some code, <bean:define id="configurationExists" toScope="request" value="1"/> //other code, not necessary <bean:define id="configurationExists" toScope="request" value="3"/> This page will not be compiled (during build or runtime). I'll try to create and send a simple app later. Thanks in advidce, Agharta
See this. http://struts.apache.org/1.2.8/userGuide/struts-bean.html#define
Created attachment 24890 [details] the test case PART 1
Created attachment 24891 [details] test case part 2
The file is a zip splitted in 2 parts
Created attachment 24892 [details] PART1
Created attachment 24893 [details] PART2
Please see the file pages/Welcome.jsp for error simulation. Thanks, Aghart
We are also seeing the issue with our code running on Windows XP SP 2, 32bit OS using struts version 1.3.10.
Thanks for the test case. I can now reproduce this error. Looking at it now...
The regression is caused by the fix for bug42390. I'll put together a test case that covers both and then see what can be done to find a fix that allows both to work correctly.
Thanks for the test case. It speed up the process of fixing this considerably. The regression has been fixed in trunk and proposed for 6.0.x.
(In reply to comment #13) > Thanks for the test case. It speed up the process of fixing this considerably. > > The regression has been fixed in trunk and proposed for 6.0.x. Fantastic! I'll wait next version with enthusiasm! Many thanks for your work! Regards, Agharta
Reviewing the fix to this issue, I cannot find any provision in the JSP specification to support the requested behaviour. The question is, when we are requested to declare a Java variable whether we should try to reuse existing declaration, or we should always declare it anew. I cannot find anything in the spec that says about reusing existing declaration. The only place relevant is chapter JSP.9.4.4 "Actions", and it says that when we do a custom action, it is translated into Java code as declare AT_BEGIN variables { declare NESTED variables transformation of foo } declare AT_END variables It just says "declare". Looking at the example provided in Comment 2: In struts 1.2.8 the bean:define tag is a BodyTag, which in its *Tei class declares a variable with the scope of VariableInfo.AT_END See http://svn.apache.org/viewvc/struts/struts1/tags/STRUTS_1_2_8/src/share/org/apache/struts/taglib/bean/DefineTag.java?view=markup http://svn.apache.org/viewvc/struts/struts1/tags/STRUTS_1_2_8/src/share/org/apache/struts/taglib/bean/DefineTei.java?view=markup The OP's problem is that such a tag defines both a scoped variable and a Java variable ("scripting variable"). It is OK to put a value into pageContext under the same name, but duplicate Java variables are not allowed. To be able to implement behaviour, requested in Comment 2, Tomcat would have to track which Java variables were declared. So, to not define a variable when it is created by the second time. But, consider the following example of mixing scriptlets and those tags: <% { %> <bean:define id="configurationExists" toScope="request" value="0"/> <% } { %> <bean:define id="configurationExists" toScope="request" value="1"/> <% } %> There is no way to reliably tell the difference between the above example and the one in Comment 2. To conclude, I would recommend the OP to use the following construct (using the JSTL tag library). I think, that it should be safe: <c:if test="${true}"> <bean:define id="configurationExists" toScope="request" value="0"/> </c:if> <c:if test="${true}"> <bean:define id="configurationExists" toScope="request" value="1"/> </c:if> Or, use <c:set /> from the same JSTL library. Thus, I think that this issue should be closed either as WONTFIX, or as INVALID.
The page mentioned contridicts itself: http://struts.apache.org/1.2.8/userGuide/struts-bean.html#define *. Unconditionally creates (or replaces) a bean under the specified identifier and *. USAGE NOTE - There is a restriction in the JSP 1.1 Specification that disallows using the same value for an id attribute more than once in a single JSP page. Therefore, you will not be able to use <bean:define> for the same bean name more than once in a single page I think if you are no longer going to allow a variable to be overwritten, then add a environment variable so we can turn the old behaviour on. For us there is to many pages to change and would make the page hard to code using dozens of variables... The comment about checking am not quite getting as one variable defined you can't use again: <c:if test="${true}"> <bean:define id="configurationExists" toScope="request" value="0"/> </c:if> <c:if test="${true}"> <bean:define id="configurationExists" toScope="request" value="1"/> </c:if> My personal view is you should be able to overwrite a variable. You could then mention scope, but thats the whole page, not block of code.
(In reply to comment #15) > Reviewing the fix to this issue, > I cannot find any provision in the JSP specification to support the requested > behaviour. > > The question is, when we are requested to declare a Java variable whether we > should try to reuse existing declaration, or we should always declare it anew. > > I cannot find anything in the spec that says about reusing existing > declaration. The only place relevant is chapter JSP.9.4.4 "Actions", and it > says that when we do a custom action, it is translated into Java code as > > declare AT_BEGIN variables > { > declare NESTED variables > transformation of foo > } > declare AT_END variables > > It just says "declare". > > > Looking at the example provided in Comment 2: > > In struts 1.2.8 the bean:define tag is a BodyTag, which in its *Tei class > declares a variable with the scope of VariableInfo.AT_END > > See > http://svn.apache.org/viewvc/struts/struts1/tags/STRUTS_1_2_8/src/share/org/apache/struts/taglib/bean/DefineTag.java?view=markup > > http://svn.apache.org/viewvc/struts/struts1/tags/STRUTS_1_2_8/src/share/org/apache/struts/taglib/bean/DefineTei.java?view=markup > > > The OP's problem is that such a tag defines both a scoped variable and a Java > variable ("scripting variable"). It is OK to put a value into pageContext under > the same name, but duplicate Java variables are not allowed. > > To be able to implement behaviour, requested in Comment 2, Tomcat would have to > track which Java variables were declared. So, to not define a variable when it > is created by the second time. But, consider the following example of mixing > scriptlets and those tags: > > <% { %> > > <bean:define id="configurationExists" toScope="request" value="0"/> > > <% } { %> > > <bean:define id="configurationExists" toScope="request" value="1"/> > > <% } %> > > There is no way to reliably tell the difference between the above example and > the one in Comment 2. > > > To conclude, I would recommend the OP to use the following construct (using the > JSTL tag library). I think, that it should be safe: > > <c:if test="${true}"> > <bean:define id="configurationExists" toScope="request" value="0"/> > </c:if> > <c:if test="${true}"> > <bean:define id="configurationExists" toScope="request" value="1"/> > </c:if> > > Or, use <c:set /> from the same JSTL library. > > > Thus, I think that this issue should be closed either as WONTFIX, or as > INVALID. Hi Mr, Thanks for reply, Sorry, but i'm not right with you (IMHO, i'm an end user of tomcat). First, why previous versions of tomcat works right (6.0.20 and prior)? Second, i don't use JSTL, i use the <logic:notEmpty> and <logic:notEqual> strut's tags.....and your solution (transated in struts) does not work. //example using notEmpty tag <logic:notEmpty name="myVar" scope="request"> <bean:define id="configurationExists" toScope="request" value="0"/> </logic:notEmpty> <logic:notEmpty name="myVar" scope="request"> <bean:define id="configurationExists" toScope="request" value="1"/> </logic:notEmpty> <logic:notEmpty name="myVar" scope="request"> <bean:define id="configurationExists" toScope="request" value="2"/> </logic:notEmpty> To confirm it, please download and run the attached example, it contains this code (in pages/Welcome.jsp) as the test case (it uses notEqual tag): <%-- HERE THE INCRIMINATED CODE --%> <bean:define id="configurationExists" toScope="request" value="0"/> <logic:notEqual name="configurationExists" value="1"> <bean:define id="configurationExists" toScope="request" value="1"/> </logic:notEqual> <logic:notEqual name="configurationExists" value="2"> <bean:define id="configurationExists" toScope="request" value="2"/> </logic:notEqual> <%-- END --%> I think that this code could appear in many projects. ......i think that exists many other projects that still using stuts 1.2.x. This is only my opinion, in my world and in my case. Please correct me if i am wrong. Regards, Agharta
The fix/workaround mentioned in this ticket does not work. My last reply was replying to the comment before that doing checks would be a nightmare (to many code changes/testing) and that solution still has the same problem. The problem is redeclaring a bean with the same ID. The page I mention seems to contradict itself. Although now fixed in trunk which I haven't tested, someone else mentioned they think the new behaviour that a define can only be used once on a pge is correct. If that is the rulling we need a backward compatible param for people like you and I. My personal view is the variable is for the whole page, so you should be able to replace its value.
(In reply to comment #18) > The fix/workaround mentioned in this ticket does not work. My last reply was > replying to the comment before that doing checks would be a nightmare (to many > code changes/testing) and that solution still has the same problem. The > problem is redeclaring a bean with the same ID. The page I mention seems to > contradict itself. > > Although now fixed in trunk which I haven't tested, someone else mentioned they > think the new behaviour that a define can only be used once on a pge is > correct. If that is the rulling we need a backward compatible param for people > like you and I. My personal view is the variable is for the whole page, so you > should be able to replace its value. Hi, You are right (i've don't read your post, sorry, my mistake. And, sorry Mr Konstantin Kolinko), but i hope that the patch provided by Mr Mark Thomas works better than your solution (i hope that no code will be rewrited by end users). When patch will be freezed in new version i'll test it. Thanks again. Agharta
Created attachment 24991 [details] 2010-02-16_tc7_bug42390_bug48616.patch Patch for trunk that - reverts r905145, - provides an alternative fix for bug 48616 and bug 42390, - replaces Vector -> List, Hashtable -> HashMap in the affected API. The essence of this fix is that all those java variable declarations are not needed when we are inside a JspFragment, because it is scriptless. That simplifies a lot and fixes bug 42390 and bug 48616 along the way. ScriptingVariabler provides a list of Java variables to be declared, filtering out those names that are already declared in the parent scopes (because those are still visible). That logic does not work when we enter a JspFragment, because a fragment is implemented in the generated servlet as a method, and does not see those variables in the calling scope. Instead of trying to fix ScriptingVariabler to detect being in those fragments and provide better lists, I make observation that in those fragments the Java variables can be not used at all. Thus, we can ignore ScriptingVariabler exactly in those cases when it is wrong. Future optimization might be to change ScriptingVariabler#ScriptingVariableVisitor and Generator#declareTemporaryScriptingVars#ScriptingVarVisitor to do not descend into fragments, as what they do will be ignored, but that will require to reimplement all code paths how Generator#GenerateVisitor#generateJspFragment() is called. I see 3 such code paths, and while they are not too complicated, they are not too trivial either, and I am afraid to introduce bugs when implementing them.
Created attachment 24992 [details] 2010-02-16_tc6_bug42390_bug48616.patch Patch for Tomcat 6.0
Created attachment 24993 [details] 2010-02-16_tc55_bug42390_bug48616.patch Patch for Tomcat 5.5
Trunk patch looks good to me. Feel free to apply it (reverting my previous fix).
Applied to trunk (r910792), proposed for 6.0 and 5.5.
This has been fixed in trunk and applied to 6.0.x. It will be included in 6.0.25 onwards.
Re-open to track to 5.5.x
*** Bug 48879 has been marked as a duplicate of this bug. ***
This patch was applied to 5.5.x in r935941 and will be in 5.5.30 onwards.
*** Bug 49434 has been marked as a duplicate of this bug. ***