Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » Accessing classpath resources from a plugin
Accessing classpath resources from a plugin [message #443740] Fri, 03 February 2006 14:43 Go to next message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
Hi all,

I'm trying to read a file off the classpath from a plugin, and haven't been
able to get it working. In my plugin I have 2 class folders, resources and
local-resources. Resources contains config files of record, while
local-resources is ahead of resources on the classpath and contains copies
of the configs with local values (it is not checked into source control).

What I use in a non-plugin project to read these files:

InputStream is =
Connector.class.getResourceAsStream("/connector.properties");
props.load(is);

does not work (InputStream is null). I found this solution among the
archives:

InputStream is =
Platform.getBundle("myplugin").getEntry("connector.properties ").openStream();
props.load(is);

but I don't want to have to specify the location of the file.

Any help appreciated,

Todd
Re: Accessing classpath resources from a plugin [message #443773 is a reply to message #443740] Fri, 03 February 2006 19:27 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

If you want to see a resource from getClass().getResourceAsStream(*),
your resource has to be in a plugin somewhere (or you have to take a
chance with some other way).

For example, you could have your plugin manifest contain:
Bundle-ClassPath: external:/opt/local/rcp_app/config, .

That will put the /opt/local/rcp_app/config directory in front of your
plugin entries.

In theory, the "external:" modifier also takes environment variables,
but I've never tested that.

Later,
PW


Re: Accessing classpath resources from a plugin [message #443775 is a reply to message #443740] Fri, 03 February 2006 19:42 Go to previous messageGo to next message
Alex Blewitt is currently offline Alex BlewittFriend
Messages: 946
Registered: July 2009
Senior Member
To be honest, I don't think I understand the question. But I'd check that (a) your properties files are where you'd expect them to be when you export the plugin (check that they're being bundled with the build.properties in the bin.includes section), and that they're on the classpath for when you're testing in the PDE. Of course, it may be that you have set up the directory so that /resources/ is also on the path, and so what you're really looking for is /resources/connector.properties.

If you want to just have two copies, one of which overrides the other, make sure that /local-resources/ and /resources/ are on the project's build path (so that the resources get copied over) and make sure that the one you want to override is first. That way, when a build happens, it'll go through the source files in order and overwrite what's there.

You should be able to access it using your getResourceAsStream() method (in fact, that's the preferred way since it will work with both OSGI and non-OSGI Jar files). It's probably just a case of getting the path right, and without knowing how you've got your directory structure (and .classpath, build.properties etc. setup) then it's not easy to see how it would work.

By the way, another way of doing overrides is to load 2 files. You can even load one over another, if I remember correctly:

props.load(is1);
props.load(is2);

so if you had two files, say, connector-local.properties and connector.properties, then if the connector-local is present, it overwrites the values loaded in connector.properties. Of course, that may not be applicable to your current situation, but it may be a thought for the future.

Alex.
Re: Accessing classpath resources from a plugin [message #443778 is a reply to message #443773] Fri, 03 February 2006 21:23 Go to previous messageGo to next message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
Thanks Paul,

The trick though, is that I want to use a relative path (root of the
classpath) to get the resource. Adding "resources" to the Bundle-ClassPath:

Bundle-ClassPath: lib/commons-httpclient-3.0.jar,
lib/commons-logging.jar,
lib/commons-codec-1.3.jar,
lib/htmlparser.jar,
local-resources/,
resources/

still can't find the resource. Maybe I should mention that this is a
"subordinate" plug-in that gets called from the main application plug-in.

Incidentally, is there a way to have the plug-in project classpath
automatically updated when plugin.xml or its constituents are saved?

Todd


"Paul Webster" <pwebster@ca.ibm.com> wrote in message
news:ds0ass$8i0$1@utils.eclipse.org...
> If you want to see a resource from getClass().getResourceAsStream(*), your
> resource has to be in a plugin somewhere (or you have to take a chance
> with some other way).
>
> For example, you could have your plugin manifest contain:
> Bundle-ClassPath: external:/opt/local/rcp_app/config, .
>
> That will put the /opt/local/rcp_app/config directory in front of your
> plugin entries.
>
> In theory, the "external:" modifier also takes environment variables, but
> I've never tested that.
>
> Later,
> PW
Re: Accessing classpath resources from a plugin [message #443779 is a reply to message #443775] Fri, 03 February 2006 21:59 Go to previous messageGo to next message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
Hi Alex,

I have both folders in the build.properties, and both are added to the
runtime classpath (and updated to the Java Build Path). I might should have
mentioned that class in the resource-fetching plug-in is called from another
plug-in through an extension point.

In other words, could it be that I'm just getting the class and not the full
plug-in classpath from:
Object obj = configs[i].createExecutableExtension("class");
?

Running from main(), the (correct) resource files get read.

Todd


"Alex Blewitt" <alex_blewitt@yahoo.com> wrote in message
news:26932432.1138995797009.JavaMail.root@cp1.javalobby.org...
> To be honest, I don't think I understand the question. But I'd check that
> (a) your properties files are where you'd expect them to be when you
> export the plugin (check that they're being bundled with the
> build.properties in the bin.includes section), and that they're on the
> classpath for when you're testing in the PDE. Of course, it may be that
> you have set up the directory so that /resources/ is also on the path, and
> so what you're really looking for is /resources/connector.properties.
>
> If you want to just have two copies, one of which overrides the other,
> make sure that /local-resources/ and /resources/ are on the project's
> build path (so that the resources get copied over) and make sure that the
> one you want to override is first. That way, when a build happens, it'll
> go through the source files in order and overwrite what's there.
>
> You should be able to access it using your getResourceAsStream() method
> (in fact, that's the preferred way since it will work with both OSGI and
> non-OSGI Jar files). It's probably just a case of getting the path right,
> and without knowing how you've got your directory structure (and
> .classpath, build.properties etc. setup) then it's not easy to see how it
> would work.
>
> By the way, another way of doing overrides is to load 2 files. You can
> even load one over another, if I remember correctly:
>
> props.load(is1);
> props.load(is2);
>
> so if you had two files, say, connector-local.properties and
> connector.properties, then if the connector-local is present, it
> overwrites the values loaded in connector.properties. Of course, that may
> not be applicable to your current situation, but it may be a thought for
> the future.
>
> Alex.
Re: Accessing classpath resources from a plugin [message #443781 is a reply to message #443779] Fri, 03 February 2006 22:25 Go to previous messageGo to next message
Alex Blewitt is currently offline Alex BlewittFriend
Messages: 946
Registered: July 2009
Senior Member
The resource must be in the same plugin as the class that you're doing the class.getResourceAsStream().

This doesn't work:
pluginA/classA
pluginB/resourceB

this does:
pluginA/classA
pluginA/resourceA

The reason why it's different is that each Eclipse plugin gets its own classloader, so class A can only see resources in plugin A, regardless of who called what or where, even if there are plugin dependencies set up. (that's how icons get loaded, and don't have problems with generic names like 'icon_32x32.gif')

If you're trying to use a class to get a resource from the wrong plugin, that might cause the issue. I'm not sure given the extensions how that happens either, but it might be that if you're installing an extension then those classes get cached by the workspace's class loader or something fun like that.

Running the jars from the main method will work becaues you only have one classloader for the entire lot, so there's no distinction between pluginA and pluginB, so each can see each others tools.

You could try the buddy classloading policy to force both plugins to be in the same classloader, but I suspect that fixing the problem would be better.

Alex.
Re: Accessing classpath resources from a plugin [message #443834 is a reply to message #443781] Sat, 04 February 2006 14:25 Go to previous messageGo to next message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
The resources I'm trying to access live in the same plug-in that contains
the code for class.getResourceAsStream(), though that code is invoked
through an interface from another plug-in.

As a sanity check, I mocked up my situation with barebones sample plug-ins:

Core Plug-in
IHowdy.java
public String sayHowdy();

plugin.xml - extension point "howdy" requiring a class


Contrib Plug-in
Howdy implements IHowdy {
Properties props = new Properties();
try {
InputStream is =
Class.class.getResourceAsStream("/howdy.properties");
props.load(is);
}
return props.get("howdy");

/resources
howdy.properties
/local-resources
howdy.properties

plugin.xml - extends "howdy"
MANIFEST.MF -
Bundle-ClassPath: local-resources/,
resources/

No luck. Not even when I copy resources/local-resources to Core.

I mentioned this thread to a colleague and he suggested that I'm violating
plug-in framework conventions, that plug-ins are a very contained
environment and so are designed not to load resources off the classpath.
Don't know if he's right, but I'm willing to accept it at this point.

If you're interested in seeing what the above plug-ins are doing, I put the
code up on a CVS server:

anonymous@cvs.sourceforge.net:/cvsroot/zclipse (Core and Contrib projects)

Thanks for the help,

Todd
Re: Accessing classpath resources from a plugin [message #443846 is a reply to message #443834] Sat, 04 February 2006 21:50 Go to previous messageGo to next message
Alex Blewitt is currently offline Alex BlewittFriend
Messages: 946
Registered: July 2009
Senior Member
Unless your properties file happens to be in rt.jar, that isn't going to work:

Class.class.getResourceAsStream("/howdy.properties");

You should do 'howdy.class.getResourceAsStream()'

Or, if you are sure that the class you're running in comes from the same plugin, you can do 'this.class.getResourceAsStream()'

Of course, that could just be a typo.

> plug-ins are a very contained environment and so are designed not to load resources off the classpath.

That's rubbish. Every plugin loads resources off their classpath. All the icons and text menu items come from resources that are loaded off the classpath; and many of the non-UI plugins also have resources (error messages for the compiler).

I'm suprised that your Bundle-ClassPath doesn't contain any references to any obvious class directories, unless you've got those in one called 'resources' as well.

Perhaps if you publish your mockup here (i.e. there's no company specific code etc.; it is a public website, after all) then I can take a look and investigate the details of what you're trying to do, rather than the excerpts in there. Failing that, drop me a contact on EZ or via my gmail address (dot between first and last name).

Alex.
Re: Accessing classpath resources from a plugin [message #443878 is a reply to message #443834] Mon, 06 February 2006 13:00 Go to previous messageGo to next message
Ricky is currently offline RickyFriend
Messages: 204
Registered: July 2009
Senior Member
> Contrib Plug-in
> Howdy implements IHowdy {
> Properties props = new Properties();
> try {
> InputStream is =
> Class.class.getResourceAsStream("/howdy.properties");
> props.load(is);
> }
> return props.get("howdy");

I do not understand the Class.class.getResourceAsStream statement. Doesnt
this mean that the classloader of the Class class is used? Which must be
some kind of system classloader or the first eclipse loader or so. Maybe
try Howdy.class.getResourceAsStream or
ContribPlugin.class.getResourceAsStream.

Ricky
Re: Accessing classpath resources from a plugin [message #443885 is a reply to message #443878] Mon, 06 February 2006 16:13 Go to previous messageGo to next message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
Your suggestion works a treat. Changing from

Class.class.getResourceAsStream

to

ContribPlugin.class.getResourceAsStream

loads the resource in the correct order (local-resources/howdy.properties if
it exists, if not, checks resources/).

Thanks,

Todd


"Ricky" <ImmortalRick@gmx.de> wrote in message
news:op.s4jyfj2faudqvk@localhost.localdomain...
>> Contrib Plug-in
>> Howdy implements IHowdy {
>> Properties props = new Properties();
>> try {
>> InputStream is =
>> Class.class.getResourceAsStream("/howdy.properties");
>> props.load(is);
>> }
>> return props.get("howdy");
>
> I do not understand the Class.class.getResourceAsStream statement. Doesnt
> this mean that the classloader of the Class class is used? Which must be
> some kind of system classloader or the first eclipse loader or so. Maybe
> try Howdy.class.getResourceAsStream or
> ContribPlugin.class.getResourceAsStream.
>
> Ricky
Re: Accessing classpath resources from a plugin [message #443886 is a reply to message #443846] Mon, 06 February 2006 16:26 Go to previous message
Todd Chambery is currently offline Todd ChamberyFriend
Messages: 13
Registered: July 2009
Junior Member
You are correct. I'm not sure what I was confusing all this time, but if
the folders are on the Runtime classpath in the correct order and the
resource is loaded by the enclosing class/plugin:

InputStream is = MyHowdy.class.getResourceAsStream("/howdy.properties");

the resource is loaded correctly.

thanks for the help,

Todd

"Alex Blewitt" <alex_blewitt@yahoo.com> wrote in message
news:28866337.1139089838989.JavaMail.root@cp1.javalobby.org...
> Unless your properties file happens to be in rt.jar, that isn't going to
> work:
>
> Class.class.getResourceAsStream("/howdy.properties");
>
> You should do 'howdy.class.getResourceAsStream()'
>
> Or, if you are sure that the class you're running in comes from the same
> plugin, you can do 'this.class.getResourceAsStream()'
>
> Of course, that could just be a typo.
>
>> plug-ins are a very contained environment and so are designed not to
>> load resources off the classpath.
>
> That's rubbish. Every plugin loads resources off their classpath. All the
> icons and text menu items come from resources that are loaded off the
> classpath; and many of the non-UI plugins also have resources (error
> messages for the compiler).
>
> I'm suprised that your Bundle-ClassPath doesn't contain any references to
> any obvious class directories, unless you've got those in one called
> 'resources' as well.
>
> Perhaps if you publish your mockup here (i.e. there's no company specific
> code etc.; it is a public website, after all) then I can take a look and
> investigate the details of what you're trying to do, rather than the
> excerpts in there. Failing that, drop me a contact on EZ or via my gmail
> address (dot between first and last name).
>
> Alex.
Previous Topic:problem while migrating RCP app to 3.2
Next Topic:Export problem, plugins contains same contents
Goto Forum:
  


Current Time: Fri Jan 03 08:48:46 GMT 2025

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

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

Back to the top