Velocity can't find resource

0 votes
asked Aug 9, 2010 by anamuser

Something is wrong and it is very frustrating. I read on velocity's homepage that when I run a webapp then some properties should be set. And I've done that but no matter what I do I keep getting the same error.
This is where I set the props and use velocity

public class ConfirmationMailGenerator implements MailGenerator {

    private BasicUser user;
    private String htmlTemplate = "HTMLConfirmationMailTemplate.vsl";
    private String plainTemplate = "PlainConfirmationMailTemplate.vsl";

    public ConfirmationMailGenerator(BasicUser user) {
        this.user = user;
    }

    public StringWriter generateHTML() throws Exception {
        Properties props = new Properties();
        props.setProperty("resource.loader", "wepapp");
        props.setProperty("webapp.resource.loader.class", "org.apache.velocity.tools.view.WebappResourceLoader");
        props.setProperty("webapp.resource.loader.path", "/WEB-INF/mailtemplates/");
        VelocityEngine engine = new VelocityEngine(props);
        VelocityContext context = new VelocityContext();

        engine.init();

        Map map = createDataModel();
        context.put("user", map);

        Template template = engine.getTemplate(htmlTemplate);
        StringWriter writer = new StringWriter();
        template.merge(context, writer);

        return writer;
    }
...
}

The files is of course saved in /WEB-INF/mailtemplates/.
If I use this I get this error:

SEVERE: ResourceManager : unable to find resource 'HTMLConfirmationMailTemplate.vsl' in any resource loader.
SEVERE: The log message is null.

Thank you for your time:)

5 Answers

0 votes
answered Aug 9, 2010 by duffymo

Velocity is probably using the class loader to find those files. I'd recommend putting them in WEB-INF/classes, which is in the CLASSPATH by default.

0 votes
answered Aug 14, 2010 by will-glass

You are using the Webapp resourceloader, which is intended for pages served by the Velocity Tools servlet. (It requires some special initialization to find the root of the servlet context).

I recommend you use the ClasspathResourceLoader, then put the files into WEB-INF/classes, or elsewhere in your classpath. This is really the most straight forward approach.

resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

More info is here:

https://velocity.apache.org/engine/1.7/apidocs/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.html

0 votes
answered Aug 17, 2013 by javier-mr

Will Glass answer is correct, but the configuration should be:

resource.loader = class
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

Note the class at the beginning of the second line. See the links provided by him for more details!.

Note: Making an answer instead of a comment due to privileges.

0 votes
answered Aug 17, 2013 by cataclysm

I am fine it as follow,

In velocity.properties file

resource.loader=class, file
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path=vm_template
runtime.log.logsystem.class=org.apache.velocity.runtime.log.SimpleLog4JLogSystem
runtime.log.logsystem.log4j.category=velocity
input.encoding=UTF-8
output.encoding=UTF-8

And at my java class

import java.io.StringWriter;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.LoopTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.apache.velocity.tools.generic.SortTool;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class VelocitySupport implements InitializingBean {
private static Logger log = Logger.getLogger(VelocitySupport.class);

@Autowired private Properties properties;

public final void afterPropertiesSet() throws Exception {
    location = location.replace("classpath:", "");
    Resource res = new ClassPathResource(location);

    Properties prop = new Properties();
    prop.load(res.getInputStream());

    String staticDir = System.getProperty("staticDir");
    String tempPath = prop.getProperty("file.resource.loader.path");
    tempPath = staticDir + "/" + tempPath;

    prop.setProperty("file.resource.loader.path", tempPath);
    Velocity.init(prop);
}

public static String merge(final String template, final VelocityContext vc) throws Exception {
    try {
        vc.put("date", new DateTool());
        vc.put("escape", new EscapeTool());
        vc.put("math", new MathTool());
        vc.put("number", new NumberTool());
        vc.put("iterate", new LoopTool());
        vc.put("sort", new SortTool());

        Template temp = Velocity.getTemplate(template);

        StringWriter sw = new StringWriter();
        temp.merge(vc, sw);
        sw.flush();

        return sw.toString();
    }
    catch (ResourceNotFoundException e) {
        log.error("", e);
        throw e;
    }
    catch (ParseErrorException e) {
        log.error("", e);
        throw e;
    }
}

private String location;

public final void setLocation(final String location) {
    this.location = location;
}
}

And insert VM arguments of project as follow..

-DstaticDir= "your directory for template path"

That may be helpful for you...

0 votes
answered Aug 15, 2015 by arpit-agarwal

For resolving this error --WEB-INF/classes and all the JARs in WEB-INF/lib are in the CLASSPATH. Try moving your folder with the .vm files under WEB-INF/classes --dont put the abolute path eg. if abc.vm file is in /public_html/WEB-INF folder then put path = "/public_html/WEB-INF/abc.vm" for velocity template path.

Welcome to Q&A, where you can ask questions and receive answers from other members of the community.
Website Online Counter

...