I just started using Java 16 and can't seem to figure out why I am unable to access resource files. I went through some troubleshooting to narrow down at least where I seem to be having a problem.
I'm using IntelliJ IDEA 2021.2 Build #IU-212.4746.92
I created a new project and I chose JavaFX with OpenJDK 16.
It then creates the project with three main files, an Application class, a Controller class, and a FXML file. Once I create the project, I go into the POM file and I chose version 16 of javaFX-controls and javafx-fxml and I tell it to get the latest version of the other libraries it adds automatically into the POM file.
I also copy two folders from a different project into the resources folder - all copy and pasting is done within IntelliJ.
When I run the application that it put there (called HellpApplication), it works fine. And that application uses class.getResource to grab the fxml file and again ... it works just fine. However, when I try to run this class:
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
public class FileResourcesUtils {
public static void main(String[] args) throws URISyntaxException {
FileResourcesUtils app = new FileResourcesUtils();
String fileName = "StyleSheets/AnchorPane.css";
System.out.println("getResourceAsStream : " + fileName);
InputStream is = app.getFileFromResourceAsStream(fileName);
printInputStream(is);
System.out.println("\ngetResource : " + fileName);
File file = app.getFileFromResource(fileName);
printFile(file);
}
private InputStream getFileFromResourceAsStream(String fileName) {
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(fileName);
if (inputStream == null) {
throw new IllegalArgumentException("file not found! " + fileName);
}
else return inputStream;
}
private File getFileFromResource(String fileName) throws URISyntaxException{
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(fileName);
if (resource == null) {
throw new IllegalArgumentException("file not found! " + fileName);
}
else return new File(resource.toURI());}
private static void printInputStream(InputStream is) {
try (InputStreamReader streamReader =
new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader)
)
{
String line;
while ((line = reader.readLine()) != null) System.out.println(line);
}
catch (IOException e) {e.printStackTrace();}
}
private static void printFile(File file) {
List<String> lines;
try {
lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
}
catch (IOException e) {e.printStackTrace();}
}
}
It throws this error:
getResourceAsStream : StyleSheets/AnchorPane.css
Exception in thread "main" java.lang.IllegalArgumentException: file not found! StyleSheets/AnchorPane.css
at com.simtechdata.test/com.simtechdata.test.FileResourcesUtils.getFileFromResourceAsStream(FileResourcesUtils.java:27)
at com.simtechdata.test/com.simtechdata.test.FileResourcesUtils.main(FileResourcesUtils.java:16)
Then, THE ONLY THING I HAVE TO DO ... is DELETE module-info.java, then that class runs perfectly! HOWEVER, without module-info.java there, I cannot run any FX code...
Here is module-info.java:
module com.simtechdata.test {
requires javafx.controls;
requires javafx.fxml;
opens com.simtechdata.test to javafx.fxml;
exports com.simtechdata.test;
}
Why did I use this class? Because I'm having the exact same problem trying to access resource files in my JavaFX application and this class was the easiest way for me to demonstrate the problem and show that it is specifically connected to the module-info file. When I run my own JavaFX code, it works just fine, until I try to access a resource file like a style sheet to throw onto a control.
What I would like to know is ... what sort of magic trick do I need to do in order to be able to access resource files from my JavaFX 16 application? What am I missing?
I'vr tried all of these different ways of getting to the resource file, but each one gives the same error:
String CSS_ANCHOR_PANE = this.getClass().getResource("StyleSheets/AnchorPane.css").toExternalForm();
String CSS_ANCHOR_PANE = ClassName.getClass().getResource("StyleSheets/AnchorPane.css").toExternalForm();
ClassLoader resource = ClassLoader.getSystemClassLoader();
String CSS_ANCHOR_PANE = resource.getResource("StyleSheets/AnchorPane.css").toExternalForm();
Class<?> resource = this.getClass();
String CSS_ANCHOR_PANE = resource.getResource("StyleSheets/AnchorPane.css").toExternalForm();
And here is a screenshot of the resource folder tree:
Any ideas?