In Tomcat 4.1.12, the tag pooling functionality is enabled by default. This is fine except that the public void release()method is not called on the tag instances when they get re-used. This causes problems with our application runtime since the instance variables end up having the values from the first usage.
This is completely normal, and your tag is not spec compliant (see the lifecycle diagram). Release is only called when the instance will be marked for GCing. You can either disable tag pooling or fix your tag.
I dont agree, you are re-using the tag instance and the variables are not starting at a known state. The spec does say that you have to guarantee that release() is called during garbage collection, but the tag pooling feature also should reset the tag instance prior to re-use. This is a very practical part of the functionality. It is also a backward compatibility problem becuase tag pooling is on by default and existing applications will not run without turning it off.
Not a bug. See description of release() method in JSP.10.1.1.2 (JSP 1.2): Called on a Tag handler to release state. The page compiler guarantees that JSP page implementation objects will invoke this method on all tag handlers, but there may be multiple invocations on doStartTag() and doEndTag() in between. Also, see http://jakarta.apache.org/taglibs/guidelines.html Item 2: Private, invocation-specific state must be managed manually. Implications include that: release() is not necessarily called between invocations, which means that tag logic should not count on private invocation- specific state being reset by release()
Referencing the spec for this functionality is not applicable since it doesn't cover the lifecycle with respect to tag pooling. I consider it 'practical' to reset a tag prior to re-using it in the tag pooling feature.
I suggest you patch Jasper to implement the behavior you'd like, then ;-)
My preference is to have this fixed in the base release and to tell our customers that Tomcat works fine and that the tag pooling functionality works well with their applications without diabling this key feature. Why are you against such a practical change?
This will not be fixed, as the specification allows the kind of pooling we are doing. You should fix your tags instead (note that you are not alone: some tags from the examples and admin webapp had to be fixed also). Please do not reopen the bug.
Juan wrote: > Referencing the spec for this functionality is not applicable since it > doesn't cover the lifecycle with respect to tag pooling. Sure it does! When the spec mentions that "there may be multiple invocations on doStartTag() and doEndTag() in between" [calling release()], it does consider tag pooling. How else could doStartTag() and doEndTag() be called multiple times on the same tag handler, if the tag handler were not reused?
*** Bug 13570 has been marked as a duplicate of this bug. ***
*** Bug 13194 has been marked as a duplicate of this bug. ***
*** Bug 13741 has been marked as a duplicate of this bug. ***
I would think that this is certainly a bug: 1. judging by the number of duplicate bugs reports targeting it. 2. The behaviour is a gotcha for developers. 3. Other major appservers are handling the behaviour as expected. 4. Why should there be any differences in behaviour when tag pooling is turned on or off. Developers should be transparent to it. System Admin perhaps will be more interested, since it is system-tuning related. 5. It is normal to save tag attribute values in tag instance variables. If release() is not called, there is no way to reset them right. I hope no one is going to suggest saving the tag attribute value in the request's attribute, if so where should the code to remove these attributes be? in release()??? Maucherat, if this is a bug for the Jasper, could you just forward it to the person in charge? Or maybe we should clarify this issue with SUN or the tomcat community at large regarding http://jakarta.apache.org/taglibs/guidelines.html thanks.
If other containers call release() in between re-uses of the same tag, those containers are broken -- they violate the tag handler instance lifecycle as described in the JSP specification. Misbehavior by other implementations is NOT a valid reason to make Tomcat broken as well. Please do not bother to reopen this bug again. Craig McClanahan J2EE Web Layer Architect
OK! The Tomcat handling is correct but: a) at second TagHandler call at same page can changed the sematic with tag pooling is on. Strange! b) the class javax.servlet.jsp.tagext.TagSupport must clear all instance variable at release() called (s. my bug report 13742)
It's interesting that such a practical adjustment is not made. We could change Tomcat and support many tag libraries unchanged. The choice is made to have ALL the tag developers release new versions of their tag libraries.
If this is not compliant with the spec, it could have been broken at random by any particular implementation, unless all other implementors consider Jasper's behavior as the example to follow. It should be noted that unless there's heavy tag usage (such as in the admin webapp), tag pooling brings only a small performance increase, so it's fine to disable it.
Can we disable it by default?
*** Bug 15281 has been marked as a duplicate of this bug. ***
According to the specification the release method should be called before the tag is garbage collected. But the truth is when a programmer writes the code for a tag, he/she is expecting that it will be garbage collected at the end of the page. The tag pooling disable this behaviour which puts everybody in a tight spot. Still all tag handlers including the JSTL doesn't release the resources after they are done with them. I reviewed the guidlines posted on jakarta for creating tag library. But here is an example for your Remy, I have a page that uploads a file and creates a huge number of objects to be inserted into the database, it is like Access mapping of fields feature. At the end of the page with TagLibraries I am left with 20 MB of ram held in memory because both Struts Iterator tag and JSTL ForEachTag doesn't set the items collection to null until the release. Now i have to wait for the next iteration for this page to be called and still I will end up with 20 MB in memory. According to the guidelines these 20MB will never be released or garbage collected because the initial state of the tag will only be reinitialized in the doStartTag. I think there were too much discussion about this issue and I think practically every tag developer expects the release to be called at the end of the page. Disabling Tag Pooling is not an option for precompiled pages because JSPC Ant Task implementation returns a hardcoded true for the isPooling method. So now where can somebody go to fix this issue.
Please refer to Craig's comments.