You are viewing a plain text version of this content. The canonical link for it is here.
Posted to taglibs-dev@jakarta.apache.org by Shawn Bayern <ba...@essentially.net> on 2001/05/21 23:56:10 UTC

AT_BEGIN, AT_END

This may not really be the best place to raise this question, but it's
related to tag development and may affect the way tags should be designed.

The JSP (1.2 PFD2) spec calls for AT_BEGIN and AT_END to provide for
availability of scripting variables from the appropriate point "until the
end of the page."

I don't see any way of accomplishing that without also making the
variables accessible earlier on the page as well.  A scripting-variable
declaration approximately adjacent to the calls to doStartTag() and
doEndTag() -- which is where Jasper locates the declaration in the last
version I checked -- might be contained within a Java '{ ... }' block as
the result either of a scriptlet or of a block that the translator adds
because of a stack of tags.  Thus, the declaration would have only the
narrow lexical "block" scope necessitated by the Java language, and it
would not be available outside the containing block.

To make it concrete...  In the version of Jasper I tested with (with
Tomcat 4.0 b3), if <x:a> produces an AT_BEGIN scripting variable called
'status', it will not be accessible when it's used in the following
example:

	<x:b>
	    <x:a/>
	</x:b>
	<%= status %>

That may just be a bug in Jasper, or it may follow the intent of the spec.  
(I'm not sure -- I can't find anything in the spec that specifically
supports or refutes this example, other than the language that describes
AT_BEGIN as making a scripting variable available "until the end of the
page."  This makes me thing it's a bug.)

If this is a bug, though, then the problem is that any fix would require
the translator to declare a variable before any sub-block present on the
page, and this would make scripting variables available too early.  (The
spec doesn't seem to rule that out -- i.e., maybe there's no such thing as
"too early" -- but I could be wrong.)

Does anyone know how other container handle similar situations?  Any other
thoughts?  I might just be missing something obvious.

Shawn


Re: (JSP) Re: AT_BEGIN, AT_END

Posted by Eduardo Pelegri-Llopart <Ed...@Sun.COM>.
Hans says

> The only way the container could distinguish a) > from b) would be
> for it to look at the actual code, and we don't want that do we?

Yes, it would require that.  That is why I mentioned the other part of
Shawn's message. That portion is talking about blocks (in the sense of
"{"), which requires looking at the code.  My idea was just to define
things this way, without requiring the JSP container to do it (and
without really expecting most containers to do it).  Not ideal, but that
would define what is legal and what is not more clearly.  Seemed a
reasonable trade-off.

Repeating the relevant portion, I wrote...
> Shawn is asking clarifications on some of the scoping rules.
> 
> Let me start with his second question.  He asks whether the following is
> legal or illegal JSP:
> 
> 1 |  <% if (a == b) { %>
> 2 |    <x:tag>
> 3 |  <% } >
> 4 |
> 5 |       ...
> 6 | 
> 7 |  <% if (a == b) { %>
> 8 |    </x:tag>
> 9 |  <% } %>
> 
> Good point.  I think the answer should be "illegal" but I don't see
> where the spec specifically says so.
> 
> I propose we add some verbiage about matching blocks in scripting code
> to the spec (in this case, in lines 1 and 3, and then in 7 and 9) and
> specify that custom actions need to appear completely within them.
> 
> Regarding where this should be described, JSP.2.3.2 talks about
> start and end tags having to be in the same physical file (and same for
> <% and %>), so that would be a natural place where to say this.  But
> Chapter 6 defines what is legal scripting, so that is a natural
> place too.  I think I'll see about adding the restriction in 2.3.2 but
> define the concept or matching blocks in scriptlets to Chapter 6
> 

====

> I don't see why it's a problem that I need to use different variable names
> in these situations, as long as the container can tell me so with a clear
> error message during the translation phase.

It is not what is done by a number of implementations today, including
Jasper, so this will break existing code.

> It's also exactly what one part
> of JSP 1.1 says (AT_BEGIN/AT_END variables can be used "in the rest of the
> page")

Yes, that is what that part says, but then item 4 in 6.4 specifically
talks about scriptlets affecting scoping of scripting variables, and it
also says that the scope of the object needs not match that of the
scripting variable.

> and it is supported by the requirement that an "id" attribute value
> must be unique within a translation unit (we removed this in 1.2, but that
> was because the spec doesn't mandate that "id" is used to name all variables,
> and to make it possible to use "id" also for NESTED variables).

I don't think that the clause about "id" applies here.  That clause
talked about attribues with name "id", and here we are talking about the
exact meaning of AT_BEGIN and AT_END.  Maybe I am missing your point?

	- eduard/o

====


Hans Bergsten wrote:
> 
> Eduardo Pelegri-Llopart wrote:
> >
> > See intermixed...
> >
> > Hans said..
> > > I see two problems with going this way:
> > >
> > > 1) The container will likely have a hard time to deal with these two
> > >    cases consistently:
> > >
> > >    a)
> > >       <foo:if ...>
> > >         <x:a id="status" />
> > >       </foo>
> > >       <%= pageContext.getAttribute("status") %>
> > >
> > >    b)
> > >       <% if (...) { %>
> > >         <x:a id="status" />
> > >       <% } %>
> > >       <%= pageContext.getAttribute("status") %>
> > >
> > >   In a) it can remove "status" from the pageContext but it's not as easy
> > >   for it to do so in b). To a JSP page author, these cases are the same
> > >   though.
> >
> > If we add the concept of matching scripting blocks, as it seems needed
> > to declare the other fragment mentioned in Shawn's mail illegal, the
> > container could do it.
> 
> I'm not sure I understand what you mean with "matching scripting blocks".
> If it's what I think it is, how would it help the container do the
> right thing in these two situations:
> 
>    a)
>       <% if (...) { %>
>         <x:a id="status" />
>       <% } %>
>       <%= pageContext.getAttribute("status") %>
> 
>    b)
>       <% String a = "foo"; %>
>       <x:a id="status" />
>       <% String b = "bar" %>
>       <%= pageContext.getAttribute("status") %>
> 
> With your reasoning, I assume a) should fail ("status" is not in scope,
> and should have been removed by the container) while b) should work (there's
> no nesting of blocks here). The only way the container could distinguish a)
> from b) would be for it to look at the actual code, and we don't want that
> do we?
> 
> > I do agree that I am not thrilled with trying to add this at this stage
> > of the JSP 1.2 spec.
> >
> > > 2) In general, explaining to a non-programmer the concept variable
> > >    visibility and how the different interactions of custom actions and
> > >    scripting elements affect where a variable can be used doesn't
> > >    thrill me ;-)
> >
> > I agree, the area is tricky.
> >
> > >    It's so much easier to say that "you can use it anywhere
> > >    in the page after this custom action".
> >
> > I think your "it" means "both scripting variable and the object in the
> > pageContext, right?
> 
> Right.
> 
> > That seems a very strong requirement to me.  It seems to require
> > defining the scripting variable at the beginning of the page, which has
> > its own set of usability problems.  It also means you cannot do things
> > like
> >
> >  <x:iterate id="x">
> >    <x:transmogrify out="item" in="x"/>
> >    ... you can use item here ...
> >  </x:iterate>
> >
> >  ... enough stuff here to make it hard to remember what you did ...
> >
> >  <x:iterate ...>
> >    <x:transmogrify out="item" .../>
> >  </x:iterate>
> >
> > Or even more complicated interactions, like adding "item" somewhere in a
> > page and then, through a typo, using it further below in the page.
> 
> I don't see why it's a problem that I need to use different variable names
> in these situations, as long as the container can tell me so with a clear
> error message during the translation phase. It's also exactly what one part
> of JSP 1.1 says (AT_BEGIN/AT_END variables can be used "in the rest of the
> page") and it is supported by the requirement that an "id" attribute value
> must be unique within a translation unit (we removed this in 1.2, but that
> was because the spec doesn't mandate that "id" is used to name all variables,
> and to make it possible to use "id" also for NESTED variables).
> 
> Similar to what Tom said in reply to my previous mail, I rather be forced to
> *always* use different names than have any confusion about *when* I have to.
> 
> Hans
> --
> Hans Bergsten           hans@gefionsoftware.com
> Gefion Software         http://www.gefionsoftware.com
> Author of JavaServer Pages (O'Reilly), http://TheJSPBook.com

Re: (JSP) Re: AT_BEGIN, AT_END

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
Eduardo Pelegri-Llopart wrote:
> 
> See intermixed...
> 
> Hans said..
> > I see two problems with going this way:
> >
> > 1) The container will likely have a hard time to deal with these two
> >    cases consistently:
> >
> >    a)
> >       <foo:if ...>
> >         <x:a id="status" />
> >       </foo>
> >       <%= pageContext.getAttribute("status") %>
> >
> >    b)
> >       <% if (...) { %>
> >         <x:a id="status" />
> >       <% } %>
> >       <%= pageContext.getAttribute("status") %>
> >
> >   In a) it can remove "status" from the pageContext but it's not as easy
> >   for it to do so in b). To a JSP page author, these cases are the same
> >   though.
> 
> If we add the concept of matching scripting blocks, as it seems needed
> to declare the other fragment mentioned in Shawn's mail illegal, the
> container could do it.

I'm not sure I understand what you mean with "matching scripting blocks".
If it's what I think it is, how would it help the container do the
right thing in these two situations:

   a)
      <% if (...) { %>
        <x:a id="status" />
      <% } %>
      <%= pageContext.getAttribute("status") %>

   b)
      <% String a = "foo"; %>
      <x:a id="status" />
      <% String b = "bar" %>
      <%= pageContext.getAttribute("status") %>

With your reasoning, I assume a) should fail ("status" is not in scope,
and should have been removed by the container) while b) should work (there's
no nesting of blocks here). The only way the container could distinguish a)
from b) would be for it to look at the actual code, and we don't want that
do we?


> I do agree that I am not thrilled with trying to add this at this stage
> of the JSP 1.2 spec.
> 
> > 2) In general, explaining to a non-programmer the concept variable
> >    visibility and how the different interactions of custom actions and
> >    scripting elements affect where a variable can be used doesn't
> >    thrill me ;-)
> 
> I agree, the area is tricky.
> 
> >    It's so much easier to say that "you can use it anywhere
> >    in the page after this custom action".
> 
> I think your "it" means "both scripting variable and the object in the
> pageContext, right?

Right.

> That seems a very strong requirement to me.  It seems to require
> defining the scripting variable at the beginning of the page, which has
> its own set of usability problems.  It also means you cannot do things
> like
> 
>  <x:iterate id="x">
>    <x:transmogrify out="item" in="x"/>
>    ... you can use item here ...
>  </x:iterate>
> 
>  ... enough stuff here to make it hard to remember what you did ...
> 
>  <x:iterate ...>
>    <x:transmogrify out="item" .../>
>  </x:iterate>
> 
> Or even more complicated interactions, like adding "item" somewhere in a
> page and then, through a typo, using it further below in the page.

I don't see why it's a problem that I need to use different variable names
in these situations, as long as the container can tell me so with a clear
error message during the translation phase. It's also exactly what one part
of JSP 1.1 says (AT_BEGIN/AT_END variables can be used "in the rest of the
page") and it is supported by the requirement that an "id" attribute value
must be unique within a translation unit (we removed this in 1.2, but that
was because the spec doesn't mandate that "id" is used to name all variables,
and to make it possible to use "id" also for NESTED variables).

Similar to what Tom said in reply to my previous mail, I rather be forced to 
*always* use different names than have any confusion about *when* I have to.

Hans
-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com
Author of JavaServer Pages (O'Reilly), http://TheJSPBook.com

Re: (JSP) Re: AT_BEGIN, AT_END

Posted by Hans Bergsten <ha...@gefionsoftware.com>.
Eduardo Pelegri-Llopart wrote:
> 
> Shawn is asking clarifications on some of the scoping rules.
> 
> Let me start with his second question.  He asks whether the following is
> legal or illegal JSP:
> 
> 1 |  <% if (a == b) { %>
> 2 |    <x:tag>
> 3 |  <% } >
> 4 |
> 5 |       ...
> 6 |
> 7 |  <% if (a == b) { %>
> 8 |    </x:tag>
> 9 |  <% } %>
> 
> Good point.  I think the answer should be "illegal" but I don't see
> where the spec specifically says so.
> 
> I propose we add some verbiage about matching blocks in scripting code
> to the spec (in this case, in lines 1 and 3, and then in 7 and 9) and
> specify that custom actions need to appear completely within them.
> [...]

I agree.

> Shawn is also asking about the visibility for an example of the form:
> 
> > >       <x:b>
> > >           <x:a/>
> > >       </x:b>
> > >       <%= status %>
> 
> where x:a is defining a scripting variable "status" as AT_BEGIN
> (AT_END would do as well).
> 
> There are two parts.  One is the life of the object within the
> pageContext object; the other is the scope of the scripting variable.
> I.e. the first is part is, when can I do a page.getAttribute("status")
> and get that object.  The second is where can one use the "status"
> scripting variable.
> 
> The spec seems to suggest that the scope of the object in pageContext
> is from the moment the start tag is invoked until the end of
> the page.  But the transformation in Section JSP.6.4, and the comment at
> the end of that section (plus Shawn's observation about implementation
> details) says that the scripting variable is actually scoped by the
> <x:b> and </x:b>
> 
> This is a bit strange, so one possibility would be to clarify the two
> scopes should be the same, e.g. modify the semantics of AT_BEGIN and
> AT_END so they are interpreted within the enclosed scope of the tag,
> using some verbiage similar to that in 6.4.4.  That would require
> changes in Section 10.5.8 (page 200).
> 
> This also requires implementation changes, i.e. the JSP container would
> be responsible for removing the pageContext binding for "status" after
> the end tag in x:b.
> 
> I would appreciate opinions on this.

I see two problems with going this way:

1) The container will likely have a hard time to deal with these two
   cases consistently:

   a)
      <foo:if ...>
        <x:a id="status" />
      </foo>
      <%= pageContext.getAttribute("status") %>

   b)
      <% if (...) { %>
        <x:a id="status" />
      <% } %>
      <%= pageContext.getAttribute("status") %>

  In a) it can remove "status" from the pageContext but it's not as easy
  for it to do so in b). To a JSP page author, these cases are the same 
  though.

2) In general, explaining to a non-programmer the concept variable
   visibility and how the different interactions of custom actions and
   scripting elements affect where a variable can be used doesn't 
   thrill me ;-) It's so much easier to say that "you can use it anywhere
   in the page after this custom action".

Tom Reilly said in another mail in this thread:
> The other solution is to modify things so that the scope of the
> scripting variable matches the scope of the variable in the 
> pageContext.  This has two ramifications:
> 
> - the JSP engine has to lift the declaration of the variable out of 
> any scopes its in
> - the scripting variable is available before its set, presumably
> initialized to null (the bit about the compiler throwing errors on
> uninitialized variables doesn't work when the value gets set inside
> a conditional block as Shawn pointed out to me).

This looks like a much better solution to me. But Tom also goes on to
say, in yet another mail:
> [...] the engine is smart about not declaring the same variable twice, 
> which is easy if all AT_END and AT_BEGIN variables are declared in the same 
> place).

I would prefer if this is still controlled by the declare value in 
VariableInfo. In other words, if declare=true, both of Tom's examples would
be invalid (needed to be reported by the container directly, not indirectly 
as a Java compilation error):

  1)
    <tag id="foo"/>
      ...
    <tag id="foo"/>

  2)
    <if ...>
      <tag id="foo"/>
    </if>

    <if ...>
      <tag id="foo"/>  
    </if>


Hans
-- 
Hans Bergsten		hans@gefionsoftware.com
Gefion Software		http://www.gefionsoftware.com
Author of JavaServer Pages (O'Reilly), http://TheJSPBook.com

Re: AT_BEGIN, AT_END

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

This looks to me like it really is a bug in Tomcat, based on the
description of how AT_BEGIN and AT_END are supposed to work (for example,
on p. 200 of JSP 1.2 PFD2).  The "status" variable exposed by the <x:a>
tag should really be visible where you have it accessed.

However, the question of "how early is too early" is an interesting
one.  I've cc'd the JSR-053 expert group (responsible for the JSP
spec) for more feedback on that question.

Craig McClanahan



On Mon, 21 May 2001, Shawn Bayern wrote:

> This may not really be the best place to raise this question, but it's
> related to tag development and may affect the way tags should be designed.
> 
> The JSP (1.2 PFD2) spec calls for AT_BEGIN and AT_END to provide for
> availability of scripting variables from the appropriate point "until the
> end of the page."
> 
> I don't see any way of accomplishing that without also making the
> variables accessible earlier on the page as well.  A scripting-variable
> declaration approximately adjacent to the calls to doStartTag() and
> doEndTag() -- which is where Jasper locates the declaration in the last
> version I checked -- might be contained within a Java '{ ... }' block as
> the result either of a scriptlet or of a block that the translator adds
> because of a stack of tags.  Thus, the declaration would have only the
> narrow lexical "block" scope necessitated by the Java language, and it
> would not be available outside the containing block.
> 
> To make it concrete...  In the version of Jasper I tested with (with
> Tomcat 4.0 b3), if <x:a> produces an AT_BEGIN scripting variable called
> 'status', it will not be accessible when it's used in the following
> example:
> 
> 	<x:b>
> 	    <x:a/>
> 	</x:b>
> 	<%= status %>
> 
> That may just be a bug in Jasper, or it may follow the intent of the spec.  
> (I'm not sure -- I can't find anything in the spec that specifically
> supports or refutes this example, other than the language that describes
> AT_BEGIN as making a scripting variable available "until the end of the
> page."  This makes me thing it's a bug.)
> 
> If this is a bug, though, then the problem is that any fix would require
> the translator to declare a variable before any sub-block present on the
> page, and this would make scripting variables available too early.  (The
> spec doesn't seem to rule that out -- i.e., maybe there's no such thing as
> "too early" -- but I could be wrong.)
> 
> Does anyone know how other container handle similar situations?  Any other
> thoughts?  I might just be missing something obvious.
> 
> Shawn
> 
>