"Template not found" when WAR deployed in Tomcat
- Dominant language
- Groovy
- Stars
- 2.9k
- Forks
- 975
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 92
Description
**Symptoms:**
When a GSON view references a template in another subfolder, the view renders correctly using grails run-app, but fails with a 500 error when the assembled war is deployed to Tomcat:
**Steps to reproduce:**
1. Clone the demo project: https://github.com/rmorrise/grails-gson-not-found
2. grails run-app
3. Verify that the test JSON is rendered correctly:
`{"message":{"value":"SHOULD BE UPPERCASE"}}`
4. gradlew assemble
5. Deploy the WAR to Tomcat (9.0.1 used in my test)
6. Visit the context root in the web browser
**Expected behavior:**
The test JSON should be rendered:
`{"message":{"value":"SHOULD BE UPPERCASE"}}`
The resolution of the template path should be consistent, whether using run-app or running from the WAR.
Ideally, the target template should always be resolved relative to the root of the /views folder.
**Actual behavior:**
The JSON is partially rendered, but displays an internal server error.
`{{"message":"Internal server error","error":500}`
**Stack trace:**
```
Template not found for name message/message. Stacktrace follows:
java.lang.reflect.InvocationTargetException: null
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: grails.views.ViewRenderException: Error rendering view: Error rendering view: Template not found for name message/message
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:73)
at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:111)
at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
at grails.gson.not.found.TestController.show(TestController.groovy:8)
... 14 common frames omitted
Caused by: grails.views.ViewRenderException: Error rendering view: Template not found for name message/message
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$6.writeTo(DefaultGrailsJsonViewHelper.groovy:786)
at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:119)
at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:142)
at grails_gson_not_found_test_show_gson.run(grails_gson_not_found_test_show_gson:7)
at grails.plugin.json.view.JsonViewWritableScript.doWrite(JsonViewWritableScript.groovy:28)
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:40)
... 20 common frames omitted
Caused by: grails.views.ViewException: Template not found for name message/message
at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper.render(DefaultGrailsJsonViewHelper.groovy:793)
at grails.plugin.json.view.api.internal.TemplateRenderer.invokeMethod(TemplateRenderer.groovy:44)
at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.cloneDelegateAndGetContent(StreamingJsonBuilder.java:793)
at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.access$000(StreamingJsonBuilder.java:478)
at grails.plugin.json.builder.StreamingJsonBuilder.call(StreamingJsonBuilder.java:238)
at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:69)
at grails_gson_not_found_test__test_gson.run(grails_gson_not_found_test__test_gson:7)
at grails.plugin.json.view.JsonViewWritableScript.doWrite(JsonViewWritableScript.groovy:28)
at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:40)
... 26 common frames omitted
```
Contributor guide
Research direction
Reproduce with the linked grails-gson-not-found demo: run grails run-app, then gradlew assemble and deploy the WAR to Tomcat. Start at TestController.groovy:8 and the DefaultGrailsJsonViewHelper entries in the stack trace; done when the nested template resolves consistently in both modes and the expected JSON is rendered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100