On Mon, 3 Feb 2003, Gary McGath wrote:

> Date: Mon,  3 Feb 2003 09:13:47 -0500
> From: Gary McGath <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: [EMAIL PROTECTED]
> Subject: Custom tag life cycle
>
> The webapp which I am developing (see http://www.timeczar.com for
> details) uses a moderately complex custom tag library, and I've found
> the lifecycle of a TagSupport object to be very confusing.
>
> As I understand it, a TagSupport object may (but is not guaranteed to)
> be reused for subsequent occurrences of the same tag in a JSP.  This
> means that attribute variables can't safely be initialized in the
> constructor, because they may not get reinitialized for subsequent
> occurrences of the tag.  (Here I'm assuming that setter functions for
> attributes simply set an instance variable.)
>
> After some digging, I found that the recommended way to reset attribute
> instance varaibles is to use the doEndTag method.  This probably doesn't
> work if a tag is nested within a tag of the same name, but I can live
> with that.
>
> Doing this works fine in Tomcat.  However, I recently ported my webapp
> to Resin and found that it doesn't work there.  Here's a cut-back
> excerpt from my JSP:
>
> <caltags:eventset>
>     <caltags:evtstartdate mode="date" length="m"/> -
>     <caltags:evtenddate mode="date" length="m"/>
> </caltags:eventset>
>
> The class which implements eventset includes the tag body once for each
> event in the set.  The evtstartdate and evtenddate tags are implemented
> by a class called DateTag, which extends TagSupport. Under Tomcat,
> DateTag.setMode and DateTag.SetLength get called once for each tag in
> each inclusion of the tag body.  Under Resin, only two calls (one for
> each of the date tags) are made to each of setMode and setLength.  If I
> clear the mode and length fields when I call doEndTag, then all
> occurrences of the date tags except the first take on their default
> attributes, which is not the behavior I want.
>
> Are both Tomcat and Resin within spec in implementing different
> behaviors here?  If so, what is the correct point in the lifecycle to
> reset attribute values in a TagSupport object?
>

Sounds like they are to me.  The JSP page compiler has the option to
optimize out the second call to the setters, because tag instances can
only be shared if the combination of attribute values is identical (as
they are in your case above), but it's not required.

The easiest way to create tags that work portably and reliably across
containers is to *never* modify the values of the properties set via tag
attributes within the tag itself.  Think of them as being readonly from
the perspective of your tag's code.

A common variation on this theme is to reset the references to null in the
release() method of the tag:

    public class MyTag ... {

        private String mode = null;
        public void setMode(String mode) {
            this.mode = mode;
        }

        private String length = null;
        public void setLength(String length) {
            this.length = length;
        }

        public void doStartTag() throws JspException {
            ... use but do not modify "mode" and "length" ...
        }

        public void doEndTag() throws JspException {
            ... use but do not modify "mode" and "length" ...
        }

        public void release() {
            mode = null;
            length = null;
        }

    }

which will release object references when the page is through using your
tag instance, but not modify them in between reuses.

> Gary McGath       http://www.mcgath.com/
>

Craig

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to