I am developing an application for OSGi with velocity template engine. It works great for loading my templates by file loader but now I have to implement this templates in my jar and load it as resources.
How can i made it work?
My Code:
ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class",
ClasspathResourceLoader.class.getName());
ve.setProperty("classpath.resource.loader.path", "/velocitytemplates");
ve.init();
ve.getTemplate("foo.vm");
This will throw an exception like
Unable to find resource 'index.vm'
Caused by:
org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource 'index.vm'
Sadly Velocity is not that OSGi friendly. Therefore you cannot use the built in ClasspathResourceLoader and it is hard to add a custom developed ResourceLoader as well.
I suggest that you should get your template as a Reader in any of the ordinary ways and choose one of the following:
The first option can be used if you do not have to merge your templates very often so performance is not a key requirement.
Here is a sample for the second option where the created template object can be reused by calling the merge function on it (expecting that you already got a Reader to your vm file or resource):
RuntimeInstance runtimeInstance = new RuntimeInstance();
runtimeInstance.init();
SimpleNode simpleNode = runtimeInstance.parse(reader, "nameOfYourTemplateResource");
Template template = new Template();
simpleNode.init(new InternalContextAdapterImpl(new VelocityContext()), runtimeInstance);
template.setData(simpleNode);
template.merge(...);
...
To get a reader for the vm file in OSGi you should choose a class that is surely in the same bundle as your vm resource and call SameBundleClass.class.getResourceAsStream... You can transform your stream to writer with InputStreamReader than.
Please note that the example misses some try-catch-finally block.