tags:

views:

548

answers:

2

I'm running Tomcat 6.0.18 on Linux.

I have a JSP that uses a bean like this:

<jsp:useBean id="helper"
             type="com.example.SomeType"
             scope="request"/>

The page references an attribute of helper with the expression language like this:

<!-- This works properly, but could fail silently if the bean name is incorrect. -->
<div><p>Here's some stuff: ${helper.stuff}</div>

During some refactoring in which I missed an occurrence of the name helper, I noticed that no error is raised if the name helper is written incorrectly. Not on the screen, and not in my log files. Nothing is produced for the expression language snippet in the output:

<!-- Wrong name! "foo" should be "helper" but no error is observed (other than missing ouput)! -->
<div><p>Here's some stuff: ${foo.stuff}</div>

Now, an error is raised (my custom error page displays and I see an exception in my log file) if I use the following JSP syntax with an incorrect name for helper:

<!-- Wrong name, but an error is raised. -->
<div><p>Here's some stuff: <jsp:getProperty name="foo" property="stuff"/></div>

In this case, the log records this entry:

SEVERE: requestURI: /some.jsp servletName: jsp statusCode: 500
org.apache.jasper.JasperException: Attempted a bean operation on a null object.

For completeness, the jsp:getProperty syntax works properly when the bean name is correct:

<!-- Works properly, protects me from an incorrect name, but is more verbose than EL. -->
<div><p>Here's some stuff: <jsp:getProperty name="helper" property="stuff"/></div>

Why don't I see an error when I write ${foo.stuff}? Is there some configuration option that controls error reporting in such cases?

+2  A: 

That's just the way that EL works.

${helper} evaluates to null so EL just returns "" and doesn't attempt to evalulate the rest of the expression.

It's kinda handy feature in some cases:

${myBean.property1.name}

will work if even if property1 is null, thus I don't have to write just to prevent an NPE:

<c:if test="${not empty myBean.property1}">${myBean.property1.name}</c:if>
Gareth Davis
+4  A: 

This behaviour is covered in section 1.6 of the Expression Language Specification Version 2.1.

To evaluate expr-a[expr-b]:

If value-a is null:

  • If expr-a[expr-b] is the last property being resolved:
    • If the expression is a value expression and ValueExpression.getValue(context) was called to initiate this expression evaluation, return null.
    • Otherwise, throw PropertyNotFoundException. trying to de-reference null for an lvalue
  • Otherwise, return null.

(EL unifies the . and [] operators)

McDowell
Thanks for this answer @McDowell. To clarify: "ValueExpression.getValue(context)" == using the EL to read a value (which is what I'm doing in this question), and "trying to de-reference null for an lvalue" == using the EL to write a value. Section 1.4 of the spec discusses the rationale for the observed behavior. Oh, and "return null" means "produce the empty string" in this context - Spec section 1.18.2
Greg Mattes