Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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   //.... } 
like image 325
hqt Avatar asked Apr 13 '12 15:04

hqt


People also ask

Why is URI not hierarchical?

First Of All, The URI is not hierarichal Issue is because probably you are using "/" as file separator. You must remember that "/" is for Windows and from OS to OS it changes, It may be different in Linux. Hence Use File. seperator .

How do I add a resource file to a jar file?

1) click project -> properties -> Build Path -> Source -> Add Folder and select resources folder. 2) create your JAR! EDIT: you can make sure your JAR contains folder by inspecting it using 7zip. After following your EDIT tip, I learned that even though your resource file, e.g. someFile.


1 Answers

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.

like image 152
dash1e Avatar answered Sep 20 '22 17:09

dash1e