I have deployed my app to jar file. When I need to copy data from one file of resource to outside of jar file, I do this code:
URL resourceUrl = getClass().getResource("/resource/data.sav");
File src = new File(resourceUrl.toURI()); //ERROR HERE
File dst = new File(CurrentPath()+"data.sav"); //CurrentPath: path of jar file don't include jar file name
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst);
// some excute code here
The error I have met is: URI is not hierarchical
. this error I don't meet when run in IDE.
If I change above code as some help on other post on StackOverFlow:
InputStream in = Model.class.getClassLoader().getResourceAsStream("/resource/data.sav");
File dst = new File(CurrentPath() + "data.sav");
FileOutputStream out = new FileOutputStream(dst);
//....
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) { //NULL POINTER EXCEPTION
//....
}
Here is a solution for Eclipse RCP / Plugin developers:
It's very important to use
FileLocator.toFileURL(fileURL)
rather thanresolve(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/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/155167You cannot do this
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: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.
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.
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:
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.