You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This problem exists since Grails 3.0.12 and apparently only if an ErrorController is used for handling error logic.
I attached a project which reproduces this issue.
Just run it and request
http://localhost:8080/not-mapped-uri
This results in a
ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[grailsDispatcherServlet] - Servlet.service() for servlet grailsDispatcherServlet threw exception
java.lang.NullPointerException: null
at org.grails.web.sitemesh.GroovyPageLayoutFinder$LayoutCacheKey.hashCode(GroovyPageLayoutFinder.java:262) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[na:1.8.0_45]
at org.grails.web.sitemesh.GroovyPageLayoutFinder.findLayout(GroovyPageLayoutFinder.java:127) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.sitemesh.GroovyPageLayoutFinder.findLayout(GroovyPageLayoutFinder.java:94) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.sitemesh.GrailsLayoutView.renderTemplate(GrailsLayoutView.java:65) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:71) ~[grails-web-common-3.0.12.jar:3.0.12]
at org.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:55) ~[grails-web-common-3.0.12.jar:3.0.12]
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:720) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:468) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:391) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:439) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:305) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost] - Exception Processing ErrorPage[errorCode=404, location=/error]
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:979) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:720) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:468) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:391) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:439) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:305) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.28.jar:8.0.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_45]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.28.jar:8.0.28]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_45]
Caused by: java.lang.NullPointerException: null
at org.grails.web.sitemesh.GroovyPageLayoutFinder$LayoutCacheKey.hashCode(GroovyPageLayoutFinder.java:262) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[na:1.8.0_45]
at org.grails.web.sitemesh.GroovyPageLayoutFinder.findLayout(GroovyPageLayoutFinder.java:127) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.sitemesh.GroovyPageLayoutFinder.findLayout(GroovyPageLayoutFinder.java:94) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.sitemesh.GrailsLayoutView.renderTemplate(GrailsLayoutView.java:65) ~[grails-web-sitemesh-3.0.12.jar:3.0.12]
at org.grails.web.servlet.view.AbstractGrailsView.renderWithinGrailsWebRequest(AbstractGrailsView.java:71) ~[grails-web-common-3.0.12.jar:3.0.12]
at org.grails.web.servlet.view.AbstractGrailsView.renderMergedOutputModel(AbstractGrailsView.java:55) ~[grails-web-common-3.0.12.jar:3.0.12]
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) ~[spring-webmvc-4.1.8.RELEASE.jar:4.1.8.RELEASE]
... 24 common frames omitted
The main problem here is that this happens only if in production mode OR groovyPageLayoutFinder.setCacheEnabled(true) (the latter is used to "simulate" production behaviour in Bootstrap.groovy).
The view which should be rendered via ErrorController.notfound contains a <g:applyLayout name="main">...<g:applyLayout>
You could also remove this line completely which will end up in the same error.
BUT if you add a layout via
<meta name="layout" content="main">
the app behaves as expected.
What I can see when debugging the app is: GroovyPageLayoutFinder.findLayout just resolves page.getProperty("meta.layout").
public Decorator findLayout(HttpServletRequest request, Page page) {
if (LOG.isDebugEnabled()) {
LOG.debug("Evaluating layout for request: " + request.getRequestURI());
}
final Object layoutAttribute = request.getAttribute(LAYOUT_ATTRIBUTE);
if (request.getAttribute(RENDERING_VIEW_ATTRIBUTE) != null || layoutAttribute != null) {
String layoutName = layoutAttribute == null ? null : layoutAttribute.toString();
if (layoutName == null) {
layoutName = page.getProperty("meta.layout");
}
Decorator d = null;
if (GrailsStringUtils.isBlank(layoutName)) {
GroovyObject controller = (GroovyObject)request.getAttribute(GrailsApplicationAttributes.CONTROLLER);
if (controller != null) {
String controllerName = (String)controller.getProperty(ControllerDynamicMethods.CONTROLLER_NAME_PROPERTY);
String actionUri = (String)controller.getProperty(ControllerDynamicMethods.ACTION_URI_PROPERTY);
if (LOG.isDebugEnabled()) {
LOG.debug("Found controller in request, location layout for controller [" + controllerName
+ "] and action [" + actionUri + "]");
}
LayoutCacheKey cacheKey = null;
boolean cachedIsNull = false;
if (cacheEnabled) {
cacheKey = new LayoutCacheKey(controllerName, actionUri);
DecoratorCacheValue cacheValue = layoutDecoratorCache.get(cacheKey);
if (cacheValue != null && (!gspReloadEnabled || !cacheValue.isExpired())) {
d = cacheValue.getDecorator();
if (d == null) {
cachedIsNull = true;
}
}
}
if (d == null && !cachedIsNull) {
d = resolveDecorator(request, controller, controllerName, actionUri);
if (cacheEnabled) {
layoutDecoratorCache.put(cacheKey, new DecoratorCacheValue(d));
}
}
}
else {
d = getApplicationDefaultDecorator(request);
}
}
else {
d = getNamedDecorator(request, layoutName);
}
if (d != null) {
return d;
}
}
return null;
}
...and controllerName is also null.
The text was updated successfully, but these errors were encountered:
This problem exists since Grails 3.0.12 and apparently only if an ErrorController is used for handling error logic.
I attached a project which reproduces this issue.
Just run it and request
http://localhost:8080/not-mapped-uri
This results in a
The main problem here is that this happens only if in production mode OR groovyPageLayoutFinder.setCacheEnabled(true) (the latter is used to "simulate" production behaviour in Bootstrap.groovy).
The view which should be rendered via ErrorController.notfound contains a
<g:applyLayout name="main">...<g:applyLayout>
You could also remove this line completely which will end up in the same error.
BUT if you add a layout via
<meta name="layout" content="main">
the app behaves as expected.
What I can see when debugging the app is: GroovyPageLayoutFinder.findLayout just resolves page.getProperty("meta.layout").
...and controllerName is also null.
The text was updated successfully, but these errors were encountered: