Here is a quick fix that should solve the problem in a single threaded
environment. And you are right on about the race conditions, where multiple
paralell compilations could cause a race, but there is a lock in JspServlet
where it locks on "this" that solves most races, but in the case where a
pool of servlet instances services the JspServlet there could be a
colission. IIRC such pooling is not barred by the spec, (and there are
other ways to induce that race) so synching on TagGeneratorBase.class in
lines 178-183 of .../jasper/compiler/Compiler.java should end that race, it
appears to me to be the best gate point around the JspParseEventListener
class, which is the only class to use instances of TagGeneratorBase
sub-classes and classes. A better long-term solution would be to move the
services provided by those static classes into the JspCompliationContext
class (which would require an API change which instantly makes it a 3.3
target)
But I digress, here is a patch you can try.
Index: TagBeginGenerator.java
===================================================================
RCS file:
/home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/TagBegin
Generator.java,v
retrieving revision 1.14
diff -U3 -r1.14 TagBeginGenerator.java
--- TagBeginGenerator.java 2000/06/14 22:51:52 1.14
+++ TagBeginGenerator.java 2000/07/03 05:46:16
@@ -199,11 +199,13 @@
String attrName = attributes[i].getName();
Method m = tc.getSetterMethod(attrName);
- if (m == null)
+ if (m == null) {
+ tagEnd();
throw new CompileException
(start, Constants.getString
("jsp.error.unable.to_find_method",
new Object[] { attrName }));
+ }
writer.println(thVarName+"."+m.getName()+"("+attrValue+");");
}
----- Original Message -----
From: "Hans Bergsten" <hans@gefionsoftware.com>
To: <tomcat-dev@jakarta.apache.org>
Sent: Sunday, July 02, 2000 9:56 PM
Subject: Incorrect code for custom actions [Was: Re: 3.2 beta status update]
> Hans Bergsten wrote:
> > [...]
> > I've tested the 3.2 beta with two tag libraries that were working fine
with
> > Tomcat 3.1, using JDK 1.3 and JDK 1.2.2 on Windows NT. I noticed the
> > following problems:
> > [...]
> > 3) Incorrect code generated for some custom actions.
>
> Okay, I believe I have tracked down this problem now. But since the code
for
> generating the JSP implementation class is far from obvious, I would
appreciate
> if someone who's familiar with the code can confirm my findings.
>
> The problem occurs in this scenario. First, the generation of the JSP
> implementation
> class for one page fails, due to a missing setter method for a custom
action
> attribute. This results in a CompileException being thrown by the
> TagBeginGenerator
> generateSetters() method. This is the expected behavior.
>
> After this failure, though, processing of *any* page containing a custom
action
> results in invalid code being generated. Example:
>
> com.ora.jsp.tags.counter.IncrementCounterTag
_jspx_th_ora_incrementCounter_0 =
> new com.ora.jsp.tags.counter.IncrementCounterTag();
> _jspx_th_ora_incrementCounter_0.setPageContext(pageContext);
> _jspx_th_ora_incrementCounter_0.setParent(_jspx_th_iob_dbStore_0);
>
> The _jspx_th_iob_dbStore_0 variable refers to the tag handler in the first
page,
> i.e. the one with the missing setter method; it's not defined at all in
this
> page.
>
> The reason is that the state of a static variable in TagGeneratorBase is
busted:
>
> static private Stack tagHandlerStack = new Stack();
>
> This Stack seems to be intended to hold the nesting hierarchy for action
> elements within a page. I have not traced through all code, but it seems
like
> if the code generation goes well, the state of the Stack is maintained by
an
> equal number of push() and pop() calls, but if the code generation fails,
junk
> is left on the Stack.
>
> I can't understand why this is a static variable; making it a regular
instance
> variable should solve the problem since a new instance of TagGeneratorBase
is
> created for each page. Having it as a static probably means that there are
> multi-threading issues as well, even though I haven't run into them yet.
> There's one more static in this class:
>
> static private Hashtable tagVarNumbers = new Hashtable();
>
> I'm not sure how it's used, but it can probably cause similar problems.
>
> My suggestion is to simple make both these variables regular instance
variables.
> If I'm missing something, please let me know.
>
> Hans
> --
> Hans Bergsten hans@gefionsoftware.com
> Gefion Software http://www.gefionsoftware.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org
>
>