My webapp is deployed on Tomcat using XML config as directory. Config file looks like this:
<Context docBase="/home/work/myapp">
...
</Context>
Directory /home/work/myapp contains only /WEB-INF/lib/*.jar
Jar files contain /META-INF/resources/{anyFilesAndDirs}
In this configuration WebappTemplateLoader cannot find template.
Example.
/home/work/myapp/WEB-INF/lib/demo.jar contains /META-INF/resources/templates/demo.ftl
I'm looking for template /templates/demo.ftl
ServletContext.getRealPath("/templates/demo.ftl") returns File /home/work/myapp/templates/demo.ftl but this is not real file.
ServletContext.getResource("/templates/demo.ftl") return proper resource but WebappTemplateLoader does not call this because of non-nullable getRealPath().
It seems the solution is to remove this condition in WebappTemplateLoader.findTemplateSource
if(!file.isFile()) {
return null;
}
Indeed, Servlet 3.0 (JEE 6) has extended
ServletContext.getResourcewith looking for resources in/WEB-INF/lib/*.jar/META-INF/resources. (There was no such thing whenWebappTemplateLoaderwas written.) I wonder how to fix this without breaking thegetRealFilehack, which is also something that existing applications count on for template reloading. Certainly some new option has to be added for tryinggetResourceif the file system access has failed. Until that, have you tried usingClassTemplateLoader?Last edit: Dániel Dékány 2015-03-05
No, ClassTemplateLoader would not help to me.
Now I have temporary solution so I can wait for next release with WebappTemplateLoader fixed.
I'm just curious, why wouldn't
ClassTemplateLoaderwork?yourClassLoader.getResource("/META-INF/resources/template/demo.ftl")should work, and soClassTemplateLoadertoo.I cannot use "META-INF/resources" in resource names.
Deployment as directory with multiple JARs in /WEB-INF is one of variants.
Another one is directory with unpacked JARs. This way files from META-INF/resources lays as ususal inside webapp dir. I use this variant during development.
Fixed in the trunk. In the case of missing file, we always try loading via
ServletContext.getResource. (Also the direct file access hack can now be disabled like<param-value>/templates?settings(attemptFileAccess=false)</param-value>.)You may want to test this, to see if it works in all scenarios that you need. Like during development, I'm not sure if extracted
META-INF/resourcesworks, since AFAIK the Serlvet spec only promises that forWEB-INF/lib/*.jar/META-INF/resources.Last edit: Dániel Dékány 2015-06-11
Checked 2.3.23-rc01 in current project. It works!
Thanks.