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 > > > >