Pedo Souza
Pedo Souza

Reputation: 63

FileNotFoundException loading jar file even existing the file

I have a application who load a jar file inside lib folder of a root folder, when I put this root folder on C:\ or in C:\somefolder works fine, but when I put inside of "Program Files (x86)" returned FileNotFoundException even existing and running cmd on Admin mode.

    JarFile jf;
    Image img = null;
    compuservice = new FrmPrincipal();
    compuservice.setVisible(true);
    System.out.println("Path of MainClass: " + Main.class.getResource("Main.class").getPath());
    System.out.println("Path Icon over MainClass: " + Main.class.getResource("Icon.png").toString());
    System.out.println("Path Icon over compuservice: " + compuservice.getClass().getResource("Icon.png").toString());
    System.out.println("Path Main.class: " + Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    if(compuservice.getClass().getResource("Icon.png").toString().contains("jar")){
        jf = new JarFile(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
        Enumeration<JarEntry> entries = jf.entries();
        while(entries.hasMoreElements()){
            JarEntry entrie = (JarEntry)entries.nextElement();
            if(entrie.getName().contains("Icon.png")){
                img = ImageIO.read(ImageIO.createImageInputStream(jf.getInputStream(entrie)));
                break;
            }
        }
        if(img == null)
            img = ImageIO.read(compuservice.getClass().getResource("javax/swing/plaf/basic/icons/JavaCup16.png"));
        compuservice.setIconImage(img);         
    }

I get the System.out.println to debug the information and returning the right path.

Stacktrace with println from app:

Path of MainClass: file:/C:/Program%20Files%20(x86)/CompuForte/compuservice/CompuService-0.0.13.4.3-SNAPSHOT.jar!/com/compu/server/main/Main.class

Path Icon over MainClass: jar:file:/C:/Program%20Files%20(x86)/CompuForte/compuservice/CompuService-0.0.13.4.3-SNAPSHOT.jar!/com/compu/server/main/Icon.png

Path Icon over compuservice: jar:file:/C:/Program%20Files%20(x86)/CompuForte/compuservice/CompuService-0.0.13.4.3-SNAPSHOT.jar!/com/compu/server/main/Icon.png

Path Main.class: /C:/Program%20Files%20(x86)/CompuForte/compuservice/CompuService-0.0.13.4.3-SNAPSHOT.jar

Exception in thread "main" java.io.FileNotFoundException: C:\Program%20Files%20(x86)\CompuForte\compuservice\CompuService-0.0.13.4.3-SNAPSHOT.jar (O sistema não pode encontrar o caminho especificado)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(Unknown Source)
        at java.util.zip.ZipFile.<init>(Unknown Source)
        at java.util.jar.JarFile.<init>(Unknown Source)
        at java.util.jar.JarFile.<init>(Unknown Source)
        at com.compu.server.main.Main.InitInstance(Main.java:37)
        at com.compu.server.main.Main.<init>(Main.java:24)
        at com.compu.server.main.Main.main(Main.java:102)
2015-10-01 10:11:16.384:INFO::AWT-EventQueue-0: Logging initialized @521ms
C:\Program%20Files%20(x86)\CompuForte\compuservice\lib
0 [AWT-EventQueue-0] ERROR com.compu.ws.rest.app.AppWS  -
null

Upvotes: 0

Views: 1498

Answers (1)

Stephen C
Stephen C

Reputation: 718788

I can see what the problem is. Here is the path you are attempting your code is attempting to use:

C:\Program%20Files%20(x86)\CompuForte\compuservice\CompuService-0.0.13.4.3-SNAPSHOT.jar

Notice the %20? That is a "percent encoded" space character. It should be a real space character.

So where did the bogus percent encoding come from?

Here:

Main.class.getProtectionDomain().getCodeSource().getLocation().getPath()

The getLocation() call is returning a URL, and then you are calling getPath() to extract the path component of the URL. The problem is that that method doesn't "decode" the encoding.

One way to deal with that is to use URL.toURI() to get a URI object, and then call URI.getPath(). I think it would be better to use new File(url.toURI()) ... which will give an exception1 in the edge-case where the CodeSource for the class is not a file in the local filesystem.


1 - This is a GOOD THING. The alternative would be that you attempted to interpret that path of (for example) an "http://..." URL as a file path. Ooops!

Upvotes: 1

Related Questions