Loading velocity template inside a jar file
Final code, developed using the ideas presented in both answers above:
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
final String templatePath = "templates/" + templateName + ".vm";
InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
if (input == null) {
throw new IOException("Template file doesn't exist");
}
InputStreamReader reader = new InputStreamReader(input);
VelocityContext context = new VelocityContext();
if (properties != null) {
stringfyNulls(properties);
for (Map.Entry<String, Object> property : properties.entrySet()) {
context.put(property.getKey(), property.getValue());
}
}
Template template = ve.getTemplate(templatePath, "UTF-8");
String outFileName = File.createTempFile("report", ".html").getAbsolutePath();
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName)));
if (!ve.evaluate(context, writer, templatePath, reader)) {
throw new Exception("Failed to convert the template into html.");
}
template.merge(context, writer);
writer.flush();
writer.close();
Unless JAR is exploded, you can't read the resource in JAR as file. Use an input stream.
See following code snippets,
InputStream input = classLoader.getResourceAsStream(fileName);
if (input == null) {
throw new ConfigurationException("Template file " +
fileName + " doesn't exist");
}
InputStreamReader reader = new InputStreamReader(input);
Writer writer = null;
try {
writer = new OutputStreamWriter(output);
// Merge template
if (!engine.evaluate(context, writer, fileName, reader))
......
If you want to use resources from classpath, you should use resource loader for classpath:
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());