12

I have 2 plugins A and B. In the MANIFEST.MF of the A I do have plugin B in a Require-Bundle section. But when I try to get B's resource from A like

ClassFromA.class.getClassLoader().getResource('resource_from_B') 

I am getting null. If I put B's resourсe (folder) to A's root everything works like a charm. Am I missing something?

NOTE: I read Lars Vogel's article

Bundle bundle = Platform.getBundle("de.vogella.example.readfile");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
    file = new File(FileLocator.resolve(fileURL).toURI());
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
}

^this solution works when I run my plugin from eclipse, but when I pack it to jar and try to install from the local update site I'm getting

java.lang.IllegalArgumentException: URI is not hierarchical  

P.S. I have also read several relative questions on the StackOverflow but wasn't able to find the answer:

SOLUTION: Many thanks to @greg-449. So the correct code is:

Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
   URL resolvedFileURL = FileLocator.toFileURL(fileURL);

   // We need to use the 3-arg constructor of URI in order to properly escape file system chars
   URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
   File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
    e1.printStackTrace();
} catch (IOException e1) {
    e1.printStackTrace();
} 

NOTE: also it's very important to use the 3-arg constructor of URI in order to properly escape file system chars.

potame
  • 7,597
  • 4
  • 26
  • 33
Ilya Buziuk
  • 1,839
  • 5
  • 27
  • 43

2 Answers2

8

Use

FileLocator.toFileURL(fileURL)

rather than FileLocator.resolve(fileURL) when you want to use the URL with File.

When the plugin is packed into a jar this will cause Eclipse to create an unpacked version in a temporary location so that the object can be accessed using File.

greg-449
  • 109,219
  • 232
  • 102
  • 145
0

Why not use Bundle.getResource? That seems to be the OSGi way to access resources.

Your first attempt might work if you use a ClassFromB.class.getClassLoader instead of A.

Iulian Dragos
  • 5,692
  • 23
  • 31