Yeah its definitely an issue where Velocity can't reliably load resources
using the web app's class path.  I found a workaround by by using a
FileResourceLoader an setting its path to the calculated path of the
webapp's WEB-INF/classes folder and that does appear to work reliably.
Sure would be good to use class path only though as my workaround will only
work if container expands the archives.

-Dave

On Sun, Dec 20, 2015 at 12:14 PM, David Hoffer <dhoff...@gmail.com> wrote:

> I'm getting ResourceNotFoundException errors using Velocity (1.7) in a web
> application.  The following is the error I get but its somewhat random.
>
> org.apache.velocity.exception.ResourceNotFoundException: Unable to find
> resource 'Body-1_v2.vm'
>
> Or
>
> org.apache.velocity.exception.ResourceNotFoundException: Unable to find
> resource 'Body-1.vm'
>
> My application is an EAR running in Wildfly.  The EAR has several web apps
> (Wars).  Each of the Wars is a service that uses velocity each with two
> templates that generates email content.  There are close to 20 services
> like this and they work fine with velocity.  However I have two that are
> somewhat different, I've had one of these different ones for a long time
> w/o trouble but now that I have two 'different' ones I get the above error.
>
> These 'different' services use Quartz to schedule a job that uses
> Velocity.  The Quartz job will fire and it will create a new instance of
> the Job and those Job instances create new instances of VelocityEngine
> & VelocityContext.  I use the following configuration for Velocity in all
> the apps.
>
>
> Properties properties = new Properties();
> properties.put("resource.loader", "class");
> properties.put("class.resource.loader.class",
> "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
> properties.put("class.resource.loader.description", "Load resources from
> the CLASSPATH");
>
> properties.put("runtime.log.logsystem.class",
> "org.apache.velocity.runtime.log.Log4JLogChute");
> properties.put("runtime.log.logsystem.log4j.category", "velocity");
> properties.put("runtime.log.logsystem.log4j.logger", "velocity");
>
> velocityEngine = new VelocityEngine();
> velocityEngine.init(properties);
>
> Then when I use the template I have:
>
> VelocityContext velocityContext = new VelocityContext();
> velocityContext.put("updatedRates", updatedRates);
>
> StringWriter writer = new StringWriter();
> velocityEngine.mergeTemplate("Body-1_v2.vm", "utf-8", velocityContext,
> writer);
> String s = writer.toString();
>
> Where 'Body-1_v2.vm' is in the War's classpath, e.g.
> WEB-INF/classes/Body-1_v2.vm
>
> My wars are skinny in that all of their jars are loaded from the Ear's lib
> folder but each War has its custom code and resources in its
> WEB-INF/classes folder
>
> This does work sometimes, it seems that one of these Quartz fired apps
> will work but not both (one is a second version of the other).
>
> So it seems to be there is a bug in Velocity's resource loader in that it
> can't property resolve the classpath when velocity is loaded by a thread
> created by Quartz (which was loaded by the web app).
>
> How can I fix this?  How can I be more explicit in telling Velocity where
> the resources are regardless of what thread launched Velocity?
>
> -Dave
>
>
>
>

Reply via email to