aspose file tools*
The moose likes JSP and the fly likes Problems with custom Tag Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » JSP
Bookmark "Problems with custom Tag" Watch "Problems with custom Tag" New topic
Author

Problems with custom Tag

Chris Brat
Ranch Hand

Joined: May 22, 2003
Posts: 108
Hi,

Is it correct to assume that a a web (servlet/JSP) container can create a single instance of a custom tag which it shares between mutliple pages?

Or is it expected that a new object will be created for each tag declaration on each JSP?

I created a custom tag (call it MyCustomTag) and am using it in a JSP page
and from what I see only one instance is created and is being 'shared' between multiple pages (it seems to be a single instance used application wide) and this is corrupting the data?

How do I force a single instance of this tag per page? Or at least force the tag to clear itself once it is finished (the release() method?)

Lotsa questions... ;-)

Thanks
Chris


SCJP 1.2, SCJP 5, SCBCD
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61420
    
  67

I have never seen a custom tag instance shared across pages. What container are you using?

Contaienrs are allowed to share instances of a custom tags created using JSP 1.x classic handlers withn the same. They cannot share instances of JSP 2.0 SimpleTag


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
ramprasad madathil
Ranch Hand

Joined: Jan 24, 2005
Posts: 489


Or at least force the tag to clear itself once it is finished (the release() method?)


If what you say is true regarding the tag object being reused, you cant do the clean up act in the release() method. You can try to reset the instance variables (tag attributes) in the doEnd() method after you have finished processing.

ram.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61420
    
  67

Originally posted by ramprasad madathil:


You can try to reset the instance variables (tag attributes) in the doEnd() method after you have finished processing.


No, no, no, no, NOOOOOOOOOOOOOO

Did I get my point across?

The container assumes that it is the only thing setting the properties that represent the attribute values. Trust me, you start mucking aorund with those and there is no end to the pain and suffering. Want to see my scars?

Rule #1: hands off the attribute properties!
ramprasad madathil
Ranch Hand

Joined: Jan 24, 2005
Posts: 489


The container assumes that it is the only thing setting the properties that represent the attribute values. Trust me, you start mucking aorund with those and there is no end to the pain and suffering. Want to see my scars?


Point taken . The jsp spec does warn at several places against user code tampering with the container's 'knowledge' of the attributes.

However just to clear this up, where exactly does the container do with the tag object after the doEnd() method which, I believe, is the last of the lifecycle methods to be called for a tag invocation . And on next invocation, doesnt it call the setter() methods on the attributes again?
The spec specifically states that the container resets all attributes where the values differ between each invocation.


The JSP container may reuse classic tag handler instances for multiple
occurrences of the corresponding custom action, in the same page or in different pages, but only if the same set of attributes are used for all occurrences. If a tag handler is used for more than one occurence, the container must reset all attributes where the values differ between the custom action occurrences. Attributes with the same value in all occurrences must not be reset. If an attribute value is set as a
request-time attribute value (using a scripting or an EL expression), the container must reset the attribute between all reuses of the tag handler instance.


And if it was the same value in all occurences, the original poster wouldnt have faced the 're-use' problem at all - he wouldnt have even noticed it.

I am not arguing a case for misuse - just not able to figure the why of it.

thanks,
ram.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61420
    
  67

A small example:

Let's say that you are using classic tags (which can be re-used), and you use two instances of the tag on a page:



Note that on the 2nd invocation, that the value of x has not changed. The container can optimize by not calling the setter for x on the 2nd invocation since it already set it to 213.

So if you have changed the value of the x property behind the container's back...
[ May 09, 2006: Message edited by: Bear Bibeault ]
ramprasad madathil
Ranch Hand

Joined: Jan 24, 2005
Posts: 489

Yes I had thought of that and can see it even more clearly now thanks to your example. For me, it would seem a bigger headache for the container to determine
1. If the instance is being reused
2. Figure out those properties which havent changed since last invocation
3. Selectively call setter methods on the changed ones.

However that may just be me. Moreover if the specs state that's the way it ought to be, then that's how it is. Bear, many thanks for your time and patience. Let me not hijack this thread anymore and leave it to the original poster to get his issue clarified.

Thanks,
Ram.
Chris Brat
Ranch Hand

Joined: May 22, 2003
Posts: 108
Hi guys,

Thanks for all your input.

Im using Tomcat 5.5 and I eventually looked inside the generated JSP class files (that Tomcat generates) to see if I could see anything.

It looks like Tomcat maintains a pool of tag instances (my tag extended BodyTagSupport) that it stores in the servlet context - I'm guessing this is for performance reasons. And this to me explains why I was getting application wide access to it.


I never manipulate the tag attributes (setting them to null etc), but I was passing values from a few nested child tags to their common parent ... something like this :

<cb arentTag>
<cb:childTag name="1" attr="val1">
<cb:childTag name="2" attr="val2">
</cb arentTag>

So child 1 and 2 both passed the attr values ("val1" and "val2" respectively) through to the parent (the child tags have no body) by calling a protected method of the parent tag (that I looked up with getParent()).

The parent keeps the supplied attr values in a list and then in the doEndTag() method it does some processing and outputs the results.

Hope this is making sense.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61420
    
  67

Since the tag code is reused with classic tags, it's best to never store any state within the tag itself. That means no instance variables that carry over, and (as mentioned) no mucking about with the attribute properties.

If you need state, you could perhaps set some scoped variables in the page context rather than within the tag itself.

As an alternative, you could look into using the SimpleTag meshanism rather than classic tags.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Problems with custom Tag