You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Gary McGath <gm...@panix.com> on 2003/02/03 15:13:47 UTC

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?

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

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Re: Custom tag life cycle

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Mon, 3 Feb 2003, Gary McGath wrote:

> Date: Mon,  3 Feb 2003 09:13:47 -0500
> From: Gary McGath <gm...@panix.com>
> Reply-To: Tomcat Users List <to...@jakarta.apache.org>
> To: tomcat-user@jakarta.apache.org
> 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: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org