javalinuxjargetresource

Java error getResource() after compilation into jar


Yesterday I finally finished my JavaFX application which perfectly ran in IDE, but when I tried to convert it to a .jar file and then run it... it didn't work. I found that my class can not import any .fxml file using getClass().getResource().
So I created a sample code which is trying to read text file CheckFile.txt.


Class path tree:

.
├── ClassFileTry.iml
├── out
│   ├── artifacts
│   │   └── ClassFileTry_jar
│   │       └── ClassFileTry.jar
│   └── production
│       └── ClassFileTry
│           ├── com
│           │   └── company
│           │       ├── CheckFile.txt
│           │       └── Main.class
│           └── META-INF
│               └── MANIFEST.MF
└── src
    ├── com
    │   └── company
    │       ├── CheckFile.txt
    │       └── Main.java
    └── META-INF
        └── MANIFEST.MF

Sample java code:

public static void GetResource() {
    String result = null;
    String url = (Main.class.getResource("CheckFile.txt")).getPath();
    System.out.println("URL = " + url);

    try {
        Scanner reader = new Scanner(new File(url));
        while (reader.hasNextLine()) {
            String data = reader.nextLine();
            result = data;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    System.out.println(result);
}

Output error:

$ java -jar ClassFileTry.jar
URL = file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt
java.io.FileNotFoundException: file:/home/tucna/Desktop/ClassFileTry/out/artifacts/ClassFileTry_jar/ClassFileTry.jar!/com/company/CheckFile.txt (No such file or directory.)
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:211)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:153)
    at java.base/java.util.Scanner.<init>(Scanner.java:639)
    at com.company.Main.GetResource(Main.java:49)
    at com.company.Main.main(Main.java:18)
null

I am using Linux and IntelliJ with java 15.0.2
So my questions are: What am I doing wrong and how to fix it? Why does getResourceAsStream() for reading files work and getResource() does not?

I'll be very grateful for any help! Thanks in advance!


Solution

  • java.io.File represents an actual file on disk. Your resource is not that; it's an entry in a jar file. new File(someUrl) is a non-starter. The go-to alternative is to never use file for thus stuff, instead, check the API you're using, it tends to have an alternative form that takes a URL or InputStream. So it is here, Scanner can also take an InputStream:

    try (InputStream in = Main.class.getResourceAsStream("/CheckFile.txt")) {
        Scanner s = new Scanner(in, StandardCharsets.UTF_8);
        // do you magic here.
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }