File.getAbsolutePath incorrect on Ubuntu

2019-08-13 02:32发布

This is a follow-up question to this one (just as a brief description: I have been able to run a Java program by double-clicking on the .jar file on OS X and Windows, but not on Linux, as with the latter I get a file path problem).

Through trying out a few things using NetBeans under Ubuntu (12.04) I found that the problem seems to be located in what the program considers to be its working directory (which I concluded from the output of File.getAbsolutePath()). If I start my application in NetBeans, everything works (even under Ubuntu), and

System.out.println(new File(".").getAbsolutePath());

gives me /home/my_home/projects/VocabTrainer/., which is my project folder and thus correct. However, if I double-click on the .jar file, located in /home/my_home/projects/VocabTrainer/dist, the output I get under Ubuntu suddenly is merely /home/my_home/. This is problematic as I want to access a data file which is located in a sub-directory of my dist dir.

Does anyone know the cause of this behaviour, and how I can solve the problem?

PS: I don't know if this is required, but here's the output of java -version

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~12.04.1)
OpenJDK Server VM (build 20.0-b12, mixed mode)

2条回答
手持菜刀,她持情操
2楼-- · 2019-08-13 02:52

I think you're confusing the location of the JAR with the current working directory.

To determine the former, see How to get the path of a running JAR file?

查看更多
你好瞎i
3楼-- · 2019-08-13 03:07

The cause, not really, at the moment. But you may not want to handle it that way, due to the evident unpredictability. Something like this should get the file, assuming you use the qualified class name of something in the jar in the below getResource call.:

URL url = this.getClass().getClassLoader().getResource("thepackage/ofyourclass/JunkTest.class");  //get url of class file.  expected: ("jar:file:/somepath/dist/yourjar.jar!qualified/class/name.class")
File distDir = null;
if(url.getProtocol() == "jar") {
    String classPath = null;
    String jarPath = url.getPath();
    if(jarPath.matches(".*:.*")) jarPath = new URL(jarPath).getPath();
    classPath = jarPath.split("!")[0];
    distDir = new File(classPath).getParentFile(); //may need to replace / with \ on windows?
} else { //"file" or none
    distDir = new File(url.toURI()).getParentFile();
}    
//... do what you need to do with distDir to tack on your subdirectory and file name

EDIT: I should point out this is clearly hacky. You may be able to add the file's location to the classpath directly at startup (or include the file you're looking for in the jar). From this you could use this.getClass().getClassLoader().getResource() with the filename of what you're looking for directly, which would get you to something like:

URL url = this.getClass().getResource("yourfile");
File file = new File(url.toURI());
//... use file directly from here

FURTHER EDIT: ok, adapted to your missing protocol, and spread it out, so error messages will be more readable for you.

查看更多
登录 后发表回答