Arqan
Arqan

Reputation: 386

Velocity's FileResourceLoader can't find resources

I use Velocity in order to load email templates. Those templates are first downloaded from the FTP server and then saved as temporary files.

However, when I try to load the template I get an exception: org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'C:\Users\someUsername\AppData\Local\Temp\template1526050996884865454.html'

And I'm sure the file is there and it's not damaged.

That's how I try to load the template:

template = velocityEngine.getTemplate(tempFile.getCanonicalPath());

Here's the velocity.properties file that I load (and I've checked that the properties are properly initialized!)

file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader=file
file.resource.loader.path=.

So where lies the problem? Is it because AppData folder is hidden by default?

Upvotes: 0

Views: 2989

Answers (2)

Christopher Schultz
Christopher Schultz

Reputation: 20837

In addition to @MOles's answer, there is a third solution.

Solution 3: Configure more than one file resource loader: one for absolute resources and one for relative ones. Something like this:

resource.loader=absolute-file, relative-file
absolute-file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader
absolute-file.resource.loader.path=
relative-file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader
relative-file.resource.loader.path=.

This will allow files to be loaded either relatively or absolutely, since FileResourceLoader evidently gets confused when you try to use a single instance for either type of path.

Upvotes: 0

M0les
M0les

Reputation: 111

I think there's a design flaw in the Velocity FileResourceLoader. Basically if your file.resource.loader.path is anything other than an empty string, it'll mangle any absolute paths handed to it as the file. Additionally it has Unix/Linux-specific code to "nip off" (paraphrasing the actual code comment) an absolute file-path handed to it (Giving a broken absolute path re-rooted to the current path setting).

Solution 1: Set the file.resource.loader.path to an empty string (prior to init()) and use absolute file-paths as the file parameter

ve.setProperty("file.resource.loader.path", "");
ve.init();
Template template = ve.getTemplate("C:\\Users\\someUsername\\AppData\\Local\\Temp\\template1526050996884865454.html");

Solution 2: Set the path to be the common root for your temp files and only hand it paths relative to that:

ve.setProperty("file.resource.loader.path", "C:\\Users\\someUsername\\AppData\\Local\\Temp");
ve.init();
Template template = ve.getTemplate("template1526050996884865454.html");

Ultimately I think the FileResourceLoader class would be better if it detected any absolute path handed to it as a file-name and not try to mash the path setting into it.

Upvotes: 2

Related Questions