Java Jar file: use resource errors: URI is not hierarchical

陌路散爱 提交于 2019-11-26 11:21:18

You cannot do this

File src = new File(resourceUrl.toURI()); //ERROR HERE

it is not a file! When you run from the ide you don't have any error, because you don't run a jar file. In the IDE classes and resources are extracted on the file system.

But you can open an InputStream in this way:

    InputStream in = Model.class.getClassLoader().getResourceAsStream("/data.sav");

Remove "/resource". Generally the IDEs separates on file system classes and resources. But when the jar is created they are put all together. So the folder level "/resource" is used only for classes and resources separation.

When you get a resource from classloader you have to specify the path that the resource has inside the jar, that is the real package hierarchy.

Mario

If for some reason you really need to create a java.io.File object to point to a resource inside of a Jar file, the answer is here: https://stackoverflow.com/a/27149287/155167

File f = new File(getClass().getResource("/MyResource").toExternalForm());

Here is a solution for Eclipse RCP / Plugin developers:

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();
}

It's very important to use FileLocator.toFileURL(fileURL) rather than resolve(fileURL) , cause 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. For instance, I guess Lars Vogel has an error in his article - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/

While I stumbled upon this problem myself I'd like to add another option (to the otherwise perfect explanation from @dash1e):

Export the plugin as a folder (not a jar) by adding:

Eclipse-BundleShape: dir

to your MANIFEST.MF.

At least when you export your RCP app with the export wizard (based on a *.product) file this gets respected and will produce a folder.

In addition to the general answers, you can get "URI is not hierarchical" from Unitils library attempting to load a dataset off a .jar file. It may happen when you keep datasets in one maven submodule, but actual tests in another.

There is even a bug UNI-197 filed.

I got a similiar issues before, and I used the code:

new File(new URI(url.toString().replace(" ","%20")).getSchemeSpecificPart());

instead of the code :

new File(new URI(url.toURI())

to solve the problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!