Bug 15703 - Illegal scope attribute without var in "fmt:setLocale" tag
Illegal scope attribute without var in "fmt:setLocale" tag
Status: RESOLVED FIXED
Product: Taglibs
Classification: Unclassified
Component: Standard Taglib
1.1
PC Windows XP
: P3 normal (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on: 25610
Blocks:
  Show dependency tree
 
Reported: 2002-12-29 15:09 UTC by Dieter van Baarle
Modified: 2004-11-16 19:05 UTC (History)
2 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dieter van Baarle 2002-12-29 15:09:28 UTC
(Using Standard-Taglib version 1.0.2 - I was not able to select this in the 
Version dropdown on the Bug Entry page)

The org.apache.taglibs.standard.tlv.JstlFmtTLV Validator complains about a 
missing attribute "var" when using the attribute "scope".

Two remarks:
1. according to the fmt.tld there IS no attribute 'var' for the setLocale tag.

2. According to the spec "var" is not required. If you do not specify it, it 
replaces the default Locale.

So as I understand it, I just put <fmt:setLocale value="${param.lang}" 
scope="session" /> on a page that sets the default Locale for this session and 
all subsequent pages that are called in the user's session will use that Locale.
Comment 1 Pierre Delisle 2003-01-02 23:47:48 UTC
This works for me. Please provide a simple JSP page that triggers
the problem.
Comment 2 Dieter van Baarle 2003-02-07 14:11:38 UTC
With which servlet-runner did it work for you?
I'm running into this problem on Resin 2.1.6. It does work on JRun4...

My feeling is that JRun4 is not validating the usage of the tags by calling the 
org.apache.taglibs.standard.tlv.JstlFmtTLV Validator. I think it only checks 
usage by what attributes are specified in the TLD.
Comment 3 Pierre Delisle 2003-02-26 21:09:54 UTC
It works on Tomcat. You may want to check with the Resin support team.
If you want to reopen that bug, *please* submit sample code that
triggers the problem.
Comment 4 Pavel Kolesnikov 2003-08-18 06:46:24 UTC
it does NOT work for me:

my JSP:

--- start ---
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/tlds/fmt.tld" prefix="fmt" %>

<fmt:setLocale value="cs_CZ" scope="session"/>
--- end ---

error message: 'Illegal scope attribute without var in "fmt:setLocale" tag'

I suppose it should set locale "cs_CZ" for all request in current session
instead, please let me know if I'm wrong.

I also suppose it shouldn't throw such a confising exception (AFAIK JSTL specs
as well as fmt.tld don't say anything about "var" attribute of this tag).

web container: Tomcat 4.1.24

taglib version: 1.0.3
Comment 5 Martin Fuhrer 2003-08-18 18:26:19 UTC
I suppose the problem is based in the fact that the 
method "JstlBaseTLV.isFmtTag" uses the explicit 
URI "http://java.sun.com/jstl/fmt" to determine if the current tag is a format 
tag. Therefore the test "!isFmtTag(ns, ln, SETLOCALE)" 
in "JstlFmtTLV.Handler.startElement" doesn't match if the tag library is 
declared by referencing the TLD file directly instead of using the logical URI 
(i.e. "<%@ taglib prefix="fmt" uri="/WEB-INF/tlds/fmt-1_0.tld" %>").
Comment 6 Felipe Leme 2003-08-22 11:17:45 UTC
I agree with Martin about the reason of the bug.

Regarding the solution, we should changed the isXXXTag methods to check the
constants (like FMT_EL) against real URI of the tag.

To get the real URI I guess we need to call TagLibraryInfo.getReliableURN(). The
problem is: how do we get a reference to the TagLibraryInfo while we are
validating the page? There is no such method on TagLibraryValidator. I did a
google search on TagLibraryInfo and found a post with the same question, but no
answer:

http://groups.google.com/groups?q=TagLibraryInfo&hl=en&lr=&ie=UTF-8&safe=off&selm=bbf0af98.0306131643.28e3206f%40posting.google.com&rnum=1

Maybe this is not possible at all (although I think it would be just a matter of
adding a getTagLibratyInfo() on TagLibraryValidator). In that case, maybe it
should be responsability of the JSP compiler to do the translation. On Tomcat,
for instance, I guess that could be achieve by changing the following line in
TagLibraryInfoImpl:
from:
        return tlv.validate(getPrefixString(), getURI(), thePage);
to:
        return tlv.validate(getPrefixString(), getReliableURN(), thePage);

I haven't tried that yet, but I can try it later. 

Felipe
Comment 7 Pierre Delisle 2003-08-23 00:09:14 UTC
Thanks Martin and Felipe for digging the cause of this problem.

Unfortunately, as pointed out by Felipe, there is not much we can
do about this problem because the JSP spec does not currently provide 
a reliable way for a TLV to tell whether an element of the JSP page being
processed belongs to a specific tag library.

Given the following release note in JSP 2.0:

------------------------------------------------------------------
Where possible, JSP 2.0 attempts to be fully backwards compatible with
JSP 1.2.  In some cases, there are ambiguities in the JSP 1.2
specification that have been clarified in JSP 2.0.  Because some JSP 1.2
containers behave differently, some applications that rely on
container-specific behavior may need to be adjusted to work correctly in
a JSP 2.0 environment.

The following is a list of known backwards compatibility issues JSP
developers should be aware of:

1. Tag Library Validators that are not namespace aware and that rely
    solely on the prefix parameter may not correctly validate some JSP
    2.0 pages.  This is because the XML view may contain tag library
    declarations in elements other than jsp:root, and may contain the
    same tag library declaration more than once, using different
    prefixes.  The uri parameter should always be used by Tag Library
    Validators instead.  Existing JSP pages with existing tag libraries
    will not have any problems.
------------------------------------------------------------------ 

it appears that the intent of the spec is to feed the *reliable* URI 
to the TLV (which is what makes sense), not the one specified in the taglib
directive.

Unfortunately, this is not what the JSP spec currently says:

public ValidationMessage[] validate(java.lang.String prefix, java.lang.String uri,
PageData page)
Validate a JSP page. This will get invoked once per unique tag library URI in
the XML view. This method will return null if the page is valid; otherwise the
method should return an array of ValidationMessage objects. An array of
length zero is also interpreted as no errors.

Parameters:
prefix - the first prefix with which the tag library is associated, in the XML
view. Note that some tags may use a different prefix if the namespace is
redefined.
uri - the value of the uri argument in the directive
page - the JspData page object
Returns: A null object, or zero length array if no errors, an array of
ValidationMessages otherwise.

The JSP spec lead has been informed of this issue.

In the meantime, you can get your page to compile if you 
simply use the URI defined in the
TLD of the tag library. In your case, this is 
http://java.sun.com/jstl/fmt.



Comment 8 Felipe Leme 2003-08-28 03:07:59 UTC
> In the meantime, you can get your page to compile if you simply use the URI 
> defined in the TLD of the tag library. In your case, this is 
> http://java.sun.com/jstl/fmt.

Pierre,

Couldn't we mention that on the ReleaseNotes.html?

Felipe
Comment 9 Pierre Delisle 2003-12-12 01:04:31 UTC
The JSP 2.0 spec now states the following:

TagLibraryValidator() 

  public ValidationMessage[] 
    validate(java.lang.String prefix, 
             java.lang.String uri,
             PageData page)

...
uri - the tag library’s unique identifier

(uri used to be defined as: 
"uri - the value of the uri argument in the directive")

This change to the spec means that this bug should now be solved with a JSP 2.0
container. But I still get an error with Tomcat 5.0.16. Thanks for looking into
this!
Comment 10 Jan Luehe 2003-12-15 17:54:28 UTC
This seems to be a bug in the JSTL TLVs, which currently ignore the "uri"
argument passed to their validate() method and use the hardcoded unique
identifier (http://java.sun.com/jsp/jstl/xxx) instead.

JSP.13.9.6 mentions that the "uri" parameter in TLV.validate()
corresponds to the taglib's uri in the XML view.

The javadocs of TLV.validate() describe the "uri" param as follows:

 @param uri the tag library's unique identifier
 
The JSP spec lead confirmed that the javadocs of TLV.validate() need
to be clarified to match the spec.

The JSP container will invoke a TLV with the necessary uri namespace
to be searched in the XML view, and TLV implementors must not hardcode
this namespace in their TLV but rather search for the provided value.

This way, TLVs will be able to locate the XML view elements they are supposed to
validate.
Comment 11 Felipe Leme 2003-12-15 18:55:28 UTC
Pierre/Jan,

The problem is not the validate() method itself, but the halpers (isFmtTag(),
isCoreTag(), etc...) used while parsing the PageData (right now, validate() is
defined in a super class - JstlBaseTLV - but the parsing code is spread throught
the sub-classes).

I think the easiest solution would be to redefine validate() in each sub-class,
setting the proper mapping between the TLV's taglib and its URI. Something like
this:

On JstlBaseTLV
--------------

private String fmtUri = null;

protected void setFmtUri( String uri ) { this.fmtUri = uri; }

protected boolean isFmtTag(String tagUri, String tagLn, String target) {
        return ( this.fmtUri != null &&
                 isTag(tagUri, tagLn, FMT, target)
              || isTag(tagUri, tagLn, FMT_EL, target)
              || isTag(tagUri, tagLn, FMT_RT, target));
    }


On JstlFmtTLV
-------------

    public synchronized ValidationMessage[] validate(
            String prefix, String uri, PageData page) {
         setFmtUri( uri );
         super.validate( prefix, uri, page );

    }

What do you think? If you're ok with that, I can do these changes on JSTL's code.

Felipe
Comment 12 Felipe Leme 2003-12-18 03:25:22 UTC
Moved bug back to Jakarta Standard (and create a new Tomcat bug for the javadoc
issue).
Comment 13 Felipe Leme 2004-01-07 00:45:43 UTC
Committed changes on CVS; waiting for TCK build report before closing the bug.