Issue
Edit: I solved my problem. (See below.)
The problem
I'm new to NetBeans, and I'm having a problem that involves loading a resource to my servlet application, which runs via NetBeans using Tomcat as the server. Everything is fine until I try to build my response using the Mustache template library (in Java). At that point, an exception is thrown:
com.github.mustachejava.MustacheException: File not under root: /opt/catalina/bin
This exception is thrown right at the point in my code where I try to compile the template file. I feed the path to the resource (the template file) to the compile
method of the MustacheFactory
. My code looks like this:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(getFormTemplatePath());
My research
I took a look at the Mustache code, and as best as I can tell, here is what's happening. Mustache does a security check when it loads the resource, trying to ensure that the resource is under the application's root in the file system. Because NetBeans is working some kind of magic to run the code on the Tomcat server, while the project's code is actually somewhere else on the file system, Mustache thinks something fishy is going on.
In other words, it can find the file; it just doesn't like where it's finding it. It seems like Mustache takes /opt/catalina/bin
as the application's root, while the template file is actually at a path more like: ~/NetBeansProjects/MyProject/WEB-INF/template_file.mst
.
The Mustache code looks like this (just so you can check my reasoning):
try {
// Check to make sure that the file is under the file root or current directory.
// Without this check you might accidentally open a security whole when exposing
// mustache templates to end users.
File checkRoot = fileRoot == null ? new File("").getCanonicalFile() : fileRoot.getCanonicalFile();
File parent = file.getCanonicalFile();
while ((parent = parent.getParentFile()) != null) {
if (parent.equals(checkRoot)) break;
}
if (parent == null) {
throw new MustacheException("File not under root: " + checkRoot.getAbsolutePath());
}
// [Try-catch block continues...]
I found the Mustache code online at the following URL:
My hypothesized solution
I'm guessing there must be some way to configure the application in NetBeans, when I'm choosing and configuring the server, to reconcile this issue. What I have tried is googling variations of Mustache NetBeans servlet "File not under root" exception
and so forth, and nothing much comes up. I'm guessing that I don't even know enough about NetBeans to know what key words I should be searching with. It's even possible that I've found the solution, but don't recognize it when I see it.
Does anybody know what I might try? Thanks.
Solution
Where to put the template file?
I solved this on my own, though I solved it by doing something better with the template file. Originally, I was putting the template file in the WEB-INF
directory and then building the path to the file using the servlet context. That doesn't seem like best practice.
Taking another look at the Mustache source code I realized that Mustache first tries to use the classloader to get the file. If you let Mustache do it in its preferred way, you don't need to give the full path, only the file's name. But the classloader only looks in certain places, the WEB-INF/lib
directory being one. A number of people on the Web recommend putting the Mustache template in the WEB-INF/lib
directory.
Since mine is a Maven project, I moved my template file to the src/main/resources
directory. (In NetBeans, this is "Other Sources" in the Projects pane.) At build, Maven takes anything in there and dumps it into the WEB-INF/lib
. I then only had to change my source code to use the file name, instead of the real path to the file (as I had been doing). Everything works.
So, as far as I'm concerned, my problem stemmed from putting the template file in what turns out to be an awkward location for Mustache. If anyone has a better idea, or anything else to add, I'm all ears.
Answered By - Mario
Answer Checked By - Cary Denson (JavaFixing Admin)