Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » How to access Velocity templates in a plugin(Don't know how to avoid "org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource" error)
How to access Velocity templates in a plugin [message #524591] Thu, 01 April 2010 14:31 Go to next message
Dave Derry is currently offline Dave DerryFriend
Messages: 4
Registered: October 2009
Junior Member
I'm creating a small RCP app to gain some understanding of the architecture and functionality. The application provides a way to easily generate a configuration file for parsing a specialized flat file used in one of our enterprise applications. After generating the configuration, a standalone application is executed against it to generate a java module consisting of the java entity classes and a driver class for parsing the file. This step uses Velocity for generating the necessary files.

I have modified the generation application to build an OSGi bundle, and have added a Command to the main menu for executing the generation class. It all works fine until it actually attempts to populate a template to create a file. Then I get the " org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource" error. I have tried everything I can think of; making sure that the templates are in a package that is Imported; placing the templates into a separate bundle which is listed as a Required-Bundle, etc. But I continue to get this error.

What am I doing wrong?

TIA,
Dave
Re: How to access Velocity templates in a plugin [message #524715 is a reply to message #524591] Thu, 01 April 2010 19:34 Go to previous messageGo to next message
Ralf Ebert is currently offline Ralf EbertFriend
Messages: 168
Registered: July 2009
Senior Member
Hi Dave,

> template to create a file. Then I get the "
> org.apache.velocity.exception.ResourceNotFoundException: Unable to find
> resource" error. I have tried everything I can think of; making sure
> that the templates are in a package that is Imported; placing the
> templates into a separate bundle which is listed as a Required-Bundle,
> etc. But I continue to get this error.

This depends on how you pass the template to Velocity. I'd recommend passing the template
as InputStream or URL, because this should work independent from the classloading. Passing
on filenames is almost guaranteed to fail because Velocity is not supposed to see
resources from bundles that depend on it.

Greetings,

Ralf


--
http://www.ralfebert.de/blog/
http://twitter.com/ralfebert/
Re: How to access Velocity templates in a plugin [message #524762 is a reply to message #524715] Fri, 02 April 2010 11:33 Go to previous messageGo to next message
Dave Derry is currently offline Dave DerryFriend
Messages: 4
Registered: October 2009
Junior Member
Thanks for the response Ralf,

> Passing on filenames is almost guaranteed to fail
> because Velocity is not supposed to see
> resources from bundles that depend on it.

That's the conclusion that I came to. I realized that the generator bundle was invoking the Velocity bundle, passing the template that was in the generator bundle (or a separate template bundle). Since, by my understanding, each bundle has it's own classloader, the Velocity bundle's classloader wouldn't be able to "see" the templates in a different bundle. So I tried adding an Import-Package (and even a Required-Bundle) element to the Velocity bundle's manifest.mf (which is of course *not* something that I would consider as a permanent solution), but I still got the same error.

Yes I am just passing the template file name to Velocity.mergeTemplate(...). This works fine when the standalone app is executed from the commandline. I want a jar that can be executed from the commandline, and also used as an OSGi bundle. I'll take a look at implementing your suggestion.

Thanks again,
Dave
Re: How to access Velocity templates in a plugin [message #524772 is a reply to message #524762] Fri, 02 April 2010 12:45 Go to previous messageGo to next message
Ralf Ebert is currently offline Ralf EbertFriend
Messages: 168
Registered: July 2009
Senior Member
Hi Dave,

> Yes I am just passing the template file name to
> Velocity.mergeTemplate(...). This works fine when the standalone app is
> executed from the commandline. I want a jar that can be executed from
> the commandline, and also used as an OSGi bundle. I'll take a look at
> implementing your suggestion.

hmm, Velocity seems to be a bit resistant to load resources propertly in an OSGI
environment. You can configure resource loaders [1] , but it's also done by String and
then Velocity cannot load the resource loader class. But there has to be a way, because
people are using Velocity in an OSGi environment [2]. I'm wondering why there is no
VelocityEngine#setResourceLoader or something...

Greetings,

Ralf


[1] http://velocity.apache.org/engine/devel/developer-guide.html #Configuring_Resource_Loaders
[2] http://issues.apache.org/jira/browse/VELOCITY-694

--
http://www.ralfebert.de/blog/
http://twitter.com/ralfebert/
Re: How to access Velocity templates in a plugin [message #524811 is a reply to message #524772] Fri, 02 April 2010 15:59 Go to previous messageGo to next message
Dave Derry is currently offline Dave DerryFriend
Messages: 4
Registered: October 2009
Junior Member
> hmm, Velocity seems to be a bit resistant to load resources propertly in an OSGI
> environment. You can configure resource loaders [1] , but it's also done by String and
> then Velocity cannot load the resource loader class. But there has to be a way, because
> people are using Velocity in an OSGi environment [2]. I'm wondering why there is no
> VelocityEngine#setResourceLoader or something...

Looks like I need to study more on classloading. I modified the generator to call Velocity.evaluate(...), passing an InputStreamReader derived from ClassLoader.getSystemResourceAsStream() on the template. Again this works fine when executing the jar from the commandline, but fails (with an NPE) when called from the plugin.

I guess I'll kick this over to the Velocity community, and see if anyone over there has an idea.

Thanks,
Dave
Re: How to access Velocity templates in a plugin [message #525024 is a reply to message #524591] Mon, 05 April 2010 12:56 Go to previous messageGo to next message
Charlie Kelly is currently offline Charlie KellyFriend
Messages: 276
Registered: July 2009
Senior Member
Hi Dave,

See the snippet below.
Remember to include the directory that contains your templates in your
build path (via MANIFEST.MF).

HTH

Charlie



private void initializeVelocity() throws Exception
{
try
{
Plugin sageGeneratorActivator = SageGeneratorActivator.getDefault();
if (null == sageGeneratorActivator)
throw new Exception ("generatorActivator is null");
Bundle uiGeneratorBundle = sageGeneratorActivator.getBundle();
//////////////////////////////////////////////////////////// ////
// retrieve "static" properties for initializing velocity engine
//////////////////////////////////////////////////////////// ////
String propertiesFileName = "properties/velocity.properties";
Path propertiesPath = new Path(propertiesFileName);
URL propertiesURL = FileLocator.find(uiGeneratorBundle,
propertiesPath, null);
if (null == propertiesURL)
throw new Exception ("URL is null for: " + propertiesFileName);
boolean substituteArgumentsFlag = false;
InputStream propertiesInputStream =
FileLocator.openStream(uiGeneratorBundle, propertiesPath,
substituteArgumentsFlag);
Properties velocityProperties = new Properties();
velocityProperties.load(propertiesInputStream);
//////////////////////////////////////////////////////////// ////
// find the location on local file system where Bundle is located
// add this to velocity properties
//////////////////////////////////////////////////////////// ////
String velocityPathKey = "file.resource.loader.path";
Path templatesPath = new Path ("templates");
URL templatesURL = FileLocator.find(uiGeneratorBundle,
templatesPath, null);
if (null == templatesURL)
throw new Exception ("templatesURL is null for: " + "templates", null);

URL tempURL = FileLocator.toFileURL(templatesURL);
String tempValue = tempURL.toExternalForm();
String velocityPathValue = null;
if (tempValue.startsWith("file:/"))
{
velocityPathValue = tempValue.substring(6);
}// if (tempValue.startsWith("file:/"))
else
velocityPathValue = tempValue;
//////////////////////////////////////////////////////////// ////
// use the properties to initialize velocity
//////////////////////////////////////////////////////////// ////
velocityProperties.put(velocityPathKey, velocityPathValue);
velocityEngine = new VelocityEngine();
velocityEngine.init(velocityProperties);

// tempTest();
}// try
catch (Exception e)
{
throw new Exception(e); // trap for debugging
}// catch (Exception e)
}// private void initializeVelocity() throws Exception
//////////////////////////////////////////////////////////// ////////////////


Dave Derry wrote:
> I'm creating a small RCP app to gain some understanding of the
> architecture and functionality. The application provides a way to easily
> generate a configuration file for parsing a specialized flat file used
> in one of our enterprise applications. After generating the
> configuration, a standalone application is executed against it to
> generate a java module consisting of the java entity classes and a
> driver class for parsing the file. This step uses Velocity for
> generating the necessary files.
>
> I have modified the generation application to build an OSGi bundle, and
> have added a Command to the main menu for executing the generation
> class. It all works fine until it actually attempts to populate a
> template to create a file. Then I get the "
> org.apache.velocity.exception.ResourceNotFoundException: Unable to find
> resource" error. I have tried everything I can think of; making sure
> that the templates are in a package that is Imported; placing the
> templates into a separate bundle which is listed as a Required-Bundle,
> etc. But I continue to get this error.
>
> What am I doing wrong?
>
> TIA,
> Dave
Re: How to access Velocity templates in a plugin [message #525025 is a reply to message #525024] Mon, 05 April 2010 13:01 Go to previous messageGo to next message
Charlie Kelly is currently offline Charlie KellyFriend
Messages: 276
Registered: July 2009
Senior Member
Hi Dave,

You might also need the following:

Charlie

private void initialize(String templateString) throws Exception
{
initializeVelocity();
velocityContext = new VelocityContext();
template = velocityEngine.getTemplate(templateString);
}// private void initialize(String templateString) throws Exception
//////////////////////////////////////////////////////////// ////////////////

exquisitus wrote:
> Hi Dave,
>
> See the snippet below.
> Remember to include the directory that contains your templates in your
> build path (via MANIFEST.MF).
>
> HTH
>
> Charlie
>
>
>
> private void initializeVelocity() throws Exception
> {
> try
> {
> Plugin sageGeneratorActivator =
> SageGeneratorActivator.getDefault();
> if (null == sageGeneratorActivator)
> throw new Exception ("generatorActivator is null");
> Bundle uiGeneratorBundle = sageGeneratorActivator.getBundle();
>
> //////////////////////////////////////////////////////////// ////
> // retrieve "static" properties for initializing
> velocity engine
>
> //////////////////////////////////////////////////////////// ////
> String propertiesFileName = "properties/velocity.properties";
> Path propertiesPath = new Path(propertiesFileName);
> URL propertiesURL = FileLocator.find(uiGeneratorBundle,
> propertiesPath, null);
> if (null == propertiesURL)
> throw new Exception ("URL is null for: " +
> propertiesFileName);
> boolean substituteArgumentsFlag = false;
> InputStream propertiesInputStream =
> FileLocator.openStream(uiGeneratorBundle,
> propertiesPath, substituteArgumentsFlag);
> Properties velocityProperties = new Properties();
> velocityProperties.load(propertiesInputStream);
>
> //////////////////////////////////////////////////////////// ////
> // find the location on local file system where Bundle
> is located
> // add this to velocity properties
>
> //////////////////////////////////////////////////////////// ////
> String velocityPathKey = "file.resource.loader.path";
> Path templatesPath = new Path ("templates");
> URL templatesURL = FileLocator.find(uiGeneratorBundle,
> templatesPath, null);
> if (null == templatesURL)
> throw new Exception ("templatesURL is null for: " +
> "templates", null);
>
> URL tempURL = FileLocator.toFileURL(templatesURL);
> String tempValue = tempURL.toExternalForm();
> String velocityPathValue = null;
> if (tempValue.startsWith("file:/"))
> {
> velocityPathValue = tempValue.substring(6);
> }// if (tempValue.startsWith("file:/"))
> else
> velocityPathValue = tempValue;
>
> //////////////////////////////////////////////////////////// ////
> // use the properties to initialize velocity
>
> //////////////////////////////////////////////////////////// ////
> velocityProperties.put(velocityPathKey, velocityPathValue);
> velocityEngine = new VelocityEngine();
> velocityEngine.init(velocityProperties);
>
> // tempTest();
> }// try
> catch (Exception e)
> {
> throw new Exception(e); // trap for debugging
> }// catch (Exception e)
> }// private void initializeVelocity() throws Exception
> //////////////////////////////////////////////////////////// ////////////////
>
>
>
> Dave Derry wrote:
>> I'm creating a small RCP app to gain some understanding of the
>> architecture and functionality. The application provides a way to
>> easily generate a configuration file for parsing a specialized flat
>> file used in one of our enterprise applications. After generating the
>> configuration, a standalone application is executed against it to
>> generate a java module consisting of the java entity classes and a
>> driver class for parsing the file. This step uses Velocity for
>> generating the necessary files.
>>
>> I have modified the generation application to build an OSGi bundle,
>> and have added a Command to the main menu for executing the generation
>> class. It all works fine until it actually attempts to populate a
>> template to create a file. Then I get the "
>> org.apache.velocity.exception.ResourceNotFoundException: Unable to
>> find resource" error. I have tried everything I can think of; making
>> sure that the templates are in a package that is Imported; placing the
>> templates into a separate bundle which is listed as a Required-Bundle,
>> etc. But I continue to get this error.
>>
>> What am I doing wrong?
>>
>> TIA,
>> Dave
Re: How to access Velocity templates in a plugin [message #533569 is a reply to message #525025] Fri, 14 May 2010 15:04 Go to previous message
Joost  is currently offline Joost Friend
Messages: 1
Registered: May 2010
Junior Member
Hi Dave,

I have a similar velocity issue.

Did you manage to solve the retrieval of the velocity templates via the snippet specified by Charlie ?

Regards,

Joost
Previous Topic:Inputs To Commands
Next Topic:creating p2 update site for RCP
Goto Forum:
  


Current Time: Thu Apr 25 19:31:07 GMT 2024

Powered by FUDForum. Page generated in 0.03411 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top