On 13/06/17 15:27, Chris Cheshire wrote:
> On Tue, Jun 6, 2017 at 2:29 PM, Mark Thomas <ma...@apache.org> wrote:
> 
>> On 31/05/17 23:31, Chris Cheshire wrote:
>>> I am using tomcat 7 on CentOS 7 and I need to pass a null value to tag
>>> attributes of type Long/Integer/Float, however it is *always* coerced to
>>> zero.
>>>
>>> <%@attribute name="parentId" required="true" rtexprvalue="true"
>>> type="java.lang.Long" %>
>>>
>>> Changing required to false does nothing. I tried setting the system
>>> property org.apache.el.parser.COERCE_TO_ZERO to false in tomcat.conf
>>> (-Dorg.apache.el.parser.COERCE_TO_ZERO=false with my other JAVA_OPTS)
>> but
>>> this does nothing.
>>
>> As expected. That system property only affects evaluation of EL
>> expressions.
>>
>>
> But isn't <tag:thing val="${val}" /> evaluation of an EL expression? Why is
> it treated differently than the evaluation of ${val} when it is used in the
> same scope as it is declared/assigned?
> 
> For instance, this tests in a JSP :
> 
> <core:set var="l" value="${null}" />
> <core:if test="${l eq null}"><p>l is null</p></core:if>

value in the set tag has the type object doesn't it? That would explain
the lack of coercion.


> 
> will succeed.
> 
> The moment I pass l into a tag and try the exact same evaluation inside, it
> fails because it has been coerced to 0.
> 
> 
>>
>>> How do I pass a null Long/Float/Integer as a tag attribute and have it
>> kept
>>> as null and not turned into an incorrect value?
>>
>> Use parentId="<%=null%>" rather than parentId=""
>>
>> Ugly, but it does the job. Scriplets aren't coerced.
>>
>> Mark
>>
> 
> 
> I can't use that because I'm not trying to pass the value null, rather a
> variable that possibly equates to null.
> 
> Also, if I have a custom bean
> 
> public class Foo {
>   private Long val;
> 
>   public Foo() { }
>   public Long getVal() { return val; }
>   public void setVal(Long val) { this.val = val; }
> }
> 
> and I pass an instance of Foo into a tag, then val stays as null.
> 
> It seems the only solutions are to use a sentinel value that "shouldn't"
> get used (cringeworthy in its own right), or to wrap everything in a custom
> bean (also extremely ugly).
> 
> I'm bewildered at why tomcat operates this way when it comes to Numbers and
> Strings. Why is it insistent on coercion when null and zero are absolutely
> not the same value.  If this is because of autoboxing, then isn't that a
> bug? A long is not a Long, and when tag attributes must be objects and not
> atomic types, shouldn't they be treated accordingly?

Tomcat behaves this way because the specification says it has to. Plenty
of folks disagree strongly with the specification but Tomcat has to
implement it. COERCE_TO_ZERO is a specification breaking configuration
option to workaround this particular behaviour.

I've been digging in to this some more and it appears that
COERCE_TO_ZERO has been given a wider scope in later versions of Tomcat.
The test case you present above behaves the way you want with
COERCE_TO_ZERO set to false in 8.0.x and above. I need to dig into why
that wider scope wasn't applied to 7.0.x.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to