[SPR-15810] TemplateAwareExpressionParser.parseExpression does not accept null ParserContext anymore Created: 24/Jul/17  Updated: 11/Sep/17  Resolved: 25/Jul/17

Status: Closed
Project: Spring Framework
Component/s: Core, Core:SpEL
Affects Version/s: 5.0 RC2, 5.0 RC3
Fix Version/s: 5.0 RC4

Type: Bug Priority: Major
Reporter: Alpheratz Assignee: Juergen Hoeller
Resolution: Complete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Reference URL: https://jira.spring.io/browse/SWF-1706
Days since last comment: 51 weeks ago
Last commented by a User: false
Last updater: St├ęphane Nicoll

 Description   

I initailly raised this as https://jira.spring.io/browse/SWF-1706 but I think this is really a spring expression issue.

With 5.0.0.RC3, I am seeing:

24-Jul-2017 20:39:30.654 SEVERE [http-nio-8080-exec-2] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [/TCE] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
 java.lang.NullPointerException
	at org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression(TemplateAwareExpressionParser.java:66)
	at org.springframework.binding.expression.spel.SpringELExpressionParser.parseSpelExpression(SpringELExpressionParser.java:96)
	at org.springframework.binding.expression.spel.SpringELExpressionParser.parseExpression(SpringELExpressionParser.java:77)
	at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseEvaluateAction(FlowModelFlowBuilder.java:870)
	at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseActions(FlowModelFlowBuilder.java:845)
	at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.parseAndAddActionState(FlowModelFlowBuilder.java:565)
	at org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder.buildStates(FlowModelFlowBuilder.java:212)
	at org.springframework.webflow.engine.builder.FlowAssembler.directAssembly(FlowAssembler.java:106)
	at org.springframework.webflow.engine.builder.FlowAssembler.assembleFlow(FlowAssembler.java:91)
	at org.springframework.webflow.engine.builder.DefaultFlowHolder.assembleFlow(DefaultFlowHolder.java:109)
	at org.springframework.webflow.engine.builder.DefaultFlowHolder.getFlowDefinition(DefaultFlowHolder.java:84)
	at org.springframework.webflow.definition.registry.FlowDefinitionRegistryImpl.getFlowDefinition(FlowDefinitionRegistryImpl.java:60)
	at org.springframework.webflow.executor.FlowExecutorImpl.launchExecution(FlowExecutorImpl.java:138)
	at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:263)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:981)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:915)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at tce.MDCFilter.doFilter(MDCFilter.java:44)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

This does not happen with 4.3.x and earlier.

I THINK this traces to a change in org.springframework.expression.common.TemplateAwareExpressionParser.parseExpression.

In 5.0.0, it looks like:

	@Override
	public Expression parseExpression(String expressionString) throws ParseException {
		return parseExpression(expressionString, NON_TEMPLATE_PARSER_CONTEXT);
	}

	@Override
	public Expression parseExpression(String expressionString, ParserContext context) throws ParseException {
		if (context.isTemplate()) {
			return parseTemplate(expressionString, context);
		}
		else {
			return doParseExpression(expressionString, context);
		}
	}

In earlier versions, a null context is explicitly protected against:

	@Override
	public Expression parseExpression(String expressionString) throws ParseException {
		return parseExpression(expressionString, NON_TEMPLATE_PARSER_CONTEXT);
	}

	@Override
	public Expression parseExpression(String expressionString, ParserContext context)
			throws ParseException {
		if (context == null) {
			context = NON_TEMPLATE_PARSER_CONTEXT;
		}

		if (context.isTemplate()) {
			return parseTemplate(expressionString, context);
		}
		else {
			return doParseExpression(expressionString, context);
		}
	}

I am coming across this when upgrading a Spring Webflow application to SWF 2.4.5.RELEASE.

I have found that I can use the bulk of 5.0.0.RC3 IFF I force expression to an earlier version:

    final SPRING_VERSION = '5.0.0.RC3'
    compile "org.springframework:spring-aop:${SPRING_VERSION}"
    compile "org.springframework:spring-aspects:${SPRING_VERSION}"
    compile "org.springframework:spring-beans:${SPRING_VERSION}"
    compile "org.springframework:spring-context-support:${SPRING_VERSION}"
    compile "org.springframework:spring-context:${SPRING_VERSION}"
    compile "org.springframework:spring-core:${SPRING_VERSION}"
//    NO compile "org.springframework:spring-expression:${SPRING_VERSION}"
//    YES compile "org.springframework:spring-expression:4.2.9.RELEASE", { force = true }
    // YES:
    compile "org.springframework:spring-expression:4.3.10.RELEASE", { force = true }
    compile "org.springframework:spring-web:${SPRING_VERSION}"
    compile "org.springframework:spring-webmvc:${SPRING_VERSION}"

So: this is not quite a blocker for me, but may be worth looking at before 5 goes live?



 Comments   
Comment by Juergen Hoeller [ 25/Jul/17 ]

Good catch! Restored for 5.0 RC4, albeit in a different fashion (namely consistent use of null as non-template ParserContext).

Generated at Wed Jul 18 05:14:30 UTC 2018 using JIRA 7.9.0#79000-sha1:3ca552e944c2fe83b21589bc06f155b9b428cc2b.