开发者

How can I use properties taken from a file in the code of an eclipse PDE fragment/plugin project?

开发者 https://www.devze.com 2023-01-10 09:03 出处:网络
I have created an eclipse plugin project and a corresponding fragment project which I use for junit tests.

I have created an eclipse plugin project and a corresponding fragment project which I use for junit tests.

In the fragment I specify the plugin project as the "Host plugin". Further 开发者_如何转开发I specify the following on the build.properties pane:

source.. = src/
output.. = bin/
bin.includes = META-INF/,\
               .,\
               my.properties

where my.properties is a file located at the root of the fragment project. I have then written a test where I try to load the my.properties file like this:

Properties properties = new Properties();
InputStream istream = this.getClass().getClassLoader()
    .getResourceAsStream("my.properties");

try {
  properties.load(istream);
} catch (IOException e) {
  e.printStackTrace();
}

but istream is null and the test fails with a NullPointerException when calling load in the try block.

I have tried to do the same thing in the host plugin and there it works fine. Any ideas about why I can't read resouces in my PDE fragment when using Junit?


Try using Bundle#getEntry. If your plug-in has an Activator, you get a BundleContext object when your plugin is started (use Bundle-ActivationPolicy: lazy in your manifest). You can get the Bundle object from the BundleContext:

public class Activator implements BundleActivator {
   private static Bundle bundle;

   public static Bundle getBundle() {
      return myBundle;
   }
   public void start(BundleContext context) throws Exception {
      bundle = context.getBundle();
   }
}

...
URL url = Activator.getBundle().getEntry("my.properties");
InputStream stream = url.openStream();
properties.load(stream);


One problem you MIGHT be having is that

InputStream istream = this.getClass().getClassLoader().
getResourceAsStream("my.properties");

behaves differently in two situations where "this" is located in a different package. Since you did not append "/" to the beginning, java will automatically start looking at the package root instead of the classpath root for the resource. If the code in your plug-in project and your fragment project exist in different packages, you have a problem.


Andrew Niefer has pointed the direction, but the solution is wrong. That is one that works:

1) Add super(); to the your Activator constructor.
2) Put this into the constructor of your plugin:

    Properties properties = new Properties();

    try {
        Bundle bundle=Activator.getDefault().getBundle();
        URL url = bundle.getEntry("plugin.properties");
        InputStream stream;
        stream = url.openStream();
        properties.load(stream);
    } catch (Exception e) {
        e.printStackTrace();
    }

And you have functioning "properties".


Explanations:

Doing (1) you will reach all that functionality:

public class Activator implements BundleActivator {
   private static Bundle bundle;

   public static Bundle getBundle() {
      return myBundle;
   }
   public void start(BundleContext context) throws Exception {
      bundle = context.getBundle();
   }
}

It is present already in the pre-parent class Plugin. And you simply can't put it into Activator, because getBundle() is final in Plugin.

Notice Activator.getDefault() in (2). Without it bundle is unreachable, it is not static. And if you simply create a new instance of activator, bundle of it will be null.


There is one more way to take a bundle:

Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);

Only check that Activator.PLUGIN_ID is set to the correct string - as is in the ID field of the Overview page of the plugin. BTW, you should check this Activator.PLUGIN_ID after every change of the plugin ID anyway.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号