-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Template not found" when WAR deployed in Tomcat #140
Comments
I can't reproduce the issue with your sample app. I deployed it both to a standalone tomcat instance and via |
Also tested on Tomcat 9.0.1 and it worked |
OK. I was able to rep it consistently using the steps above (copying the war created by gradlew assemble from build/libs/, renaming to ROOT.war, and dropping it in webapps.) I am on win7 x64, with Tomcat installed as a windows service. I will try to dig into it with the remote debugger and look for clues to what is going on. Any ideas about what I can do to help reproduce it are welcome. Here is my environment info: |
I noticed this code in ResolvableGroovyTemplateEngine, which seems relevant. Still in the process of debugging.
|
@rmorrise That shouldn't have any impact, as it attempts the other if the first didn't work |
In my environment, when the app is run from Tomcat, the
This path is not correct, since the JVM's current working directory is the Tomcat home directory. Grails is looking for the template at the following absolute path:
I am not sure what's different about your setup compared to mine, but I also see this issue on our RHEL web server, so I don't think it's a Windows-specific issue. |
I am debugging the |
I tried to work around this by setting the base dir:
I verified that the setting was applied using the debugger, but it didn't fix the issue. I think it's because the structure of the exploded WAR does not match the view folder structure in the source code. All of the views are flattened out into WEB-INF/classes. I'm guessing this is why class-based resolution is tried first in non-dev environments... path-based resolution does not work anymore. |
It seems that when the app goes to non-dev mode, it switches from path-based resolution to class-based resolution. The class-based resolution's behavior does not match the path-based resolution's behavior in the case of a relative path that backs up with ".." like the one given in the sample project. Here is the actual class compiled into the WAR: Here is the path the class-based resolver is looking for: |
@jameskleeh When you get the time, can you check in your debugger and see where your app's behavior is diverging from mine? Can you verify the paths given above? The path it is trying to load is: A good place to put a breakpoint is: |
I think this problem can be fixed by calling:
...somewhere in the process of template resolution. I'm not sure what the most appropriate place is. It could be done at the beginning of |
If using NIO is not desirable, java.net.URI can also be used: It seems to me like the only workaround right now is to eliminate the call to |
@rmorrise Does using absolute paths in |
@jameskleeh Aha! Yes, it does. I am able to get the desired behavior by changing the client code in the view to: This fixes my actual issue in the app. I still think adding the |
We are seeing something similar with |
Hello, I recently encountered this problem when calling the @Autowired
JsonViewTemplateEngine templateEngine
void myMethod() {
Template t = templateEngine.resolveTemplate('/book/show')
def writable = t.make(book: new Book(title:"The Stand"))
def sw = new StringWriter()
writable.writeTo(sw)
...
} As a solution, I override the json view template path url to solve the problem. I found two options for overriding urls:
Or
beans = {
jsonViewConfiguration(JsonViewConfiguration) {
templatePath = ... // your path
}
} I chose the second option and to resolve the path I read it from the classpath, something like this: templatePath = Paths.get(new ClassPathResource("book/").getURI()).getParent().toString() And that solved the problem. |
I just encountered the same issue in grails 4.1.4, and the workaround to use absolute paths to resolve templates does wotk. |
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:
{"message":{"value":"SHOULD BE UPPERCASE"}}
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:
The text was updated successfully, but these errors were encountered: