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!
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);
}