Announcement Announcement Module
Collapse
No announcement yet.
Using null variables in SpEL causes SpelEvaluationException Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using null variables in SpEL causes SpelEvaluationException

    I am using the <spring:eval> tag in a JSP:

    <spring:eval expression="'today is ' + today" />

    Where today is a java.util.Date. Everything works just fine, as long as the today variable is not null. When today is null, I get

    Code:
    org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Field or property 'today' cannot be found on null
        org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:243)
        org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:112)
        org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:107)
        org.springframework.expression.spel.ast.OpPlus.getValueInternal(OpPlus.java:70)
        org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
        org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:98)
        org.springframework.web.servlet.tags.EvalTag.doEndTag(EvalTag.java:126)
        org.apache.jsp.WEB_002dINF.views.admin.inbox_jsp._jspx_meth_s_005feval_005f1(inbox_jsp.java:195)
        org.apache.jsp.WEB_002dINF.views.admin.inbox_jsp._jspService(inbox_jsp.java:120)
        org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:954)
        org.apache.jasper.runtime.PageContextImpl.doInclude(PageContextImpl.java:684)
        org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.java:678)
        org.apache.tiles.request.jsp.JspRequest.doInclude(JspRequest.java:123)
        org.apache.tiles.request.AbstractViewRequest.dispatch(AbstractViewRequest.java:47)
        org.apache.tiles.request.render.DispatchRenderer.render(DispatchRenderer.java:45)
        org.apache.tiles.request.render.ChainedDelegateRenderer.render(ChainedDelegateRenderer.java:68)
        org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
        org.apache.tiles.template.InsertAttributeModel.renderAttribute(InsertAttributeModel.java:188)
        org.apache.tiles.template.InsertAttributeModel.execute(InsertAttributeModel.java:132)
        org.apache.tiles.jsp.taglib.InsertAttributeTag.doTag(InsertAttributeTag.java:299)
        org.apache.jsp.WEB_002dINF.views.common.main_002dlayout_jsp._jspx_meth_tiles_005finsertAttribute_005f2(main_002dlayout_jsp.java:243)
        org.apache.jsp.WEB_002dINF.views.common.main_002dlayout_jsp._jspService(main_002dlayout_jsp.java:103)
        org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.apache.tiles.request.servlet.ServletRequest.forward(ServletRequest.java:265)
        org.apache.tiles.request.servlet.ServletRequest.doForward(ServletRequest.java:228)
        org.apache.tiles.request.AbstractClientRequest.dispatch(AbstractClientRequest.java:57)
        org.apache.tiles.request.render.DispatchRenderer.render(DispatchRenderer.java:45)
        org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:259)
        org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:397)
        org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:238)
        org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:221)
        org.apache.tiles.renderer.DefinitionRenderer.render(DefinitionRenderer.java:59)
        org.springframework.web.servlet.view.tiles3.TilesView.renderMergedOutputModel(TilesView.java:145)
        org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:264)
        org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208)
        org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
        org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
        org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
        org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:152)
        org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
        org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:183)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
        org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
        org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
        org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
        org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
        org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    So I tried checking for null with Elvis operator:

    <spring:eval expression="'today is ' + (today ?: 'null date!') " />

    but that gives the exact same exception.

    After stepping into the Spring PropertyOrFieldReference code with a debugger, what I found was that it does not seem to be able to handle null variables. The crux of the problem seems to be that the canRead() method of org.springframework.web.servlet.tags.EvalTag.JspPr opertyAccessor uses pageContext.findAttribute(). It then assumes that if findAttribute returns null, that the attribute was not set, and is thus unreadable. So it can't handle the case where the attribute is present, but with a null value. Perhaps a better test would be testing the return value of pageContext.getAttributesScope() to see if it is set in any scope (i.e. - return value > 0)?
Working...
X