apache / apache/grails-core

"Template not found" when WAR deployed in Tomcat

Open
#14,306 17 comments 0 reactions 0 assignees View on GitHub
relates-to: grails-views
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.