I have some code that works just fine locally, but when I try to run it on my remote server, it throws a null pointer exception. It does so when attempting to get the template from Velocity. It fails the first time, and every time after.
The code in question is this bit:
URL location = Thread.currentThread().getContextClassLoader().getResource("velocity.properties");
String fullPath = location.getPath();
log.debug("Path: " + fullPath);
Velocity.init(fullPath);
Template tmplt = Velocity.getTemplate( "template.html" ); //This line throws the error
Logging shows the path to be correct, and I can verify that the file is there.
The properties file used to initialize velocity contains:
resource.loader = file
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html
file.resource.loader.cache = true
input.encoding=UTF-8
output.encoding=UTF-8
The stack trace for the error looks like this:
SEVERE: Servlet.service() for servlet Jersey REST Service threw exception
java.lang.NullPointerException
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
at org.apache.velocity.runtime.RuntimeSingleton.getTemplate(RuntimeSingleton.java:299)
at org.apache.velocity.app.Velocity.getTemplate(Velocity.java:358)
at ca.company.ipservice.models.MyClass.toHTML(MyClass.java:48)
I've Googled around and searched StackOverflow but I can't find any answer. Any ideas?
The property file.resource.loader.path
should point to a directory. Try to set it to the directory /var/lib/tomcat6/webapps/geoip/WEB-INF/templates
file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates
instead of
file.resource.loader.path=/var/lib/tomcat6/webapps/geoip/WEB-INF/templates/template.html
Also you seem to have a web application. In this case it is better to use the WebappResourceLoader
from the velocity tools
resource.loader = webapp
webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path = templates
webapp.resource.loader.cache = false
and set the servlet context property before initializing it
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setApplicationAttribute("javax.servlet.ServletContext", context);
where context
is the ServletContext
. The directory templates
should be located in your web root, thus in the same location as WEB-INF
.
EDIT
If you package your application into a war file and deploy it onto the app server which does not unpack it so that you have direct access to the filesystem then you might consider using the ClasspathResourceLoader
. For that you'll have to package your templates into an own jar file an put it into WEb-INF/lib
. The argument for getTemplate(...)
will have to follow the rule of retrieving ressources located in the classpath (see ClassLoader#getResourceAsStream).
resource.loader = classpath
classpath.resource.loader.description = Velocity Classpath Resource Loader
classpath.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
classpath.resource.loader.cache = false
Here you can find more informations about how to load templates (a.k.a. resources).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With