SETUP:
I'm using the Modular with Gradle option from the official OpenJFX documentation.
File Structure:
As suggested in here, I tried using this for all of my resources:
URL cssURL = getClass().getResource("/org/jamesd/examples/css/style.css");
scene.getStylesheets().add(cssURL.toExternalForm());
So, in my case, in order to load my main .fxml
file (and all resources), it would be:
URL urlFXML = getClass().getResource("/fxml/file.fxml");
Parent root = FXMLLoader.load(urlFXML);
PROBLEM:
When I click on Run -> Run Main.java (with the code set up as above), I get the infamous java.lang.NullPointerException: Location is required.
, but when I build the application using jlink
, it works - as it should!
As suggested in this topic, I used the jimage list modules
command and it gave me the following structure:
Module: [module]
META-INF/MANIFEST.MF
[com]/[company]/[package]/Main.class
[com]/[company]/[package]/controllers/[Controller].class
fxml/file.fxml
img/logo.png
module-info.class
style/style.css
In order for me to be able to run the application without building it everytime, I have to set my resource URL
s like so:
URL urlFXML = new File("src/main/resources/fxml/file.fxml").toURI().toURL();
Parent root = FXMLLoader.load(urlFXML);
If I do that, though, after building my application with jlink
, I get this error:
java.io.FileNotFoundException: /home/[user]/Documents/Projects/[folder]/[folder]/[folder]/[projectname]/build/image/bin/src/main/resources/fxml/file.fxml (No such file or directory)
Which makes sense, as you can see from the jimage list modules
command from above.
I can't figure out what's messing with me, the IDE, Gradle, jlink
or my incompetence.
I also made sure that I've covered the "Troubleshooting" section (from the second link) as well:
- I'm using valid names for my resources.
- Since I'm using
getClass().getResource()
, I'm using/
in myURL
. - In this last point, which is:
Remember that absolute paths are defined relative to the classpath. Typically the root of the classpath is the union of all source and resource folders in your IDE.
I'm not sure which of these the author means:
- The
src
folder as seen in the image above (since he mentions IDE). - The
src/main
folder since that's where all the "source" code is (i.e.java
folder with the package and.java
files). - The "main" folder which contains all of folders and resources once the application is built (as seen by the
jimage list modules
command). - Or the directory of files that I get after running this code (ran by Run -> Main.java in the IDE, not after building the application):
File file = new File(".");
System.out.print("Files: \n");
for(String fileNames : file.list()) System.out.println(fileNames);
Which returns:
Files:
gradle
settings.gradle
.idea
src
build
build.gradle
gradlew.bat
gradlew
.gradle
I also tried adding the following code to my build.gradle
file, but it didn't seem to do anything:
sourceSets {
main {
resources {
srcDirs = ["src/main/resources"]
includes = ["**/*.fxml"]
}
}
}
Question:
Is there a way to set up the resource URL
s which works for both when I run the application and build it while maintaining my current file structure?
Source/Demo (GitHub won't let me upload it - too big when compressed or too many files/folders - sorry for the inconvenience).
I've included a built jlink
image, which only needs to be run. If you want to test it using absolute paths, uncomment the URL
s in Main.java
.
Edit 1:
Directory tree of the build
folder:
.
├── classes
│ └── java
│ └── main
│ ├── com
│ │ └── company
│ │ └── app
│ │ ├── controllers
│ │ │ └── TestingController.class
│ │ └── Main.class
│ └── module-info.class
├── generated
│ └── sources
│ ├── annotationProcessor
│ │ └── java
│ │ └── main
│ └── headers
│ └── java
│ └── main
├── image
│ ├── bin
│ │ ├── app
│ │ ├── app.bat
│ │ ├── java
│ │ ├── jrunscript
│ │ └── keytool
│ ├── conf
│ │ ├── net.properties
│ │ ├── sdp
│ │ │ └── sdp.conf.template
│ │ ├── security
│ │ │ ├── java.policy
│ │ │ ├── java.security
│ │ │ └── policy
│ │ │ ├── limited
│ │ │ │ ├── default_local.policy
│ │ │ │ ├── default_US_export.policy
│ │ │ │ └── exempt_local.policy
│ │ │ ├── README.txt
│ │ │ └── unlimited
│ │ │ ├── default_local.policy
│ │ │ └── default_US_export.policy
│ │ └── sound.properties
│ ├── include
│ │ ├── classfile_constants.h
│ │ ├── jawt.h
│ │ ├── jni.h
│ │ ├── jvmticmlr.h
│ │ ├── jvmti.h
│ │ └── linux
│ │ ├── jawt_md.h
│ │ └── jni_md.h
│ ├── legal
│ │ ├── java.base
│ │ │ ├── ADDITIONAL_LICENSE_INFO
│ │ │ ├── aes.md
│ │ │ ├── asm.md
│ │ │ ├── ASSEMBLY_EXCEPTION
│ │ │ ├── cldr.md
│ │ │ ├── c-libutl.md
│ │ │ ├── icu.md
│ │ │ ├── LICENSE
│ │ │ ├── public_suffix.md
│ │ │ └── unicode.md
│ │ ├── java.datatransfer
│ │ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ │ └── LICENSE -> ../java.base/LICENSE
│ │ ├── java.desktop
│ │ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ │ ├── colorimaging.md
│ │ │ ├── giflib.md
│ │ │ ├── harfbuzz.md
│ │ │ ├── jpeg.md
│ │ │ ├── lcms.md
│ │ │ ├── libpng.md
│ │ │ ├── LICENSE -> ../java.base/LICENSE
│ │ │ ├── mesa3d.md
│ │ │ └── xwd.md
│ │ ├── java.prefs
│ │ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ │ └── LICENSE -> ../java.base/LICENSE
│ │ ├── java.scripting
│ │ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ │ └── LICENSE -> ../java.base/LICENSE
│ │ ├── java.xml
│ │ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ │ ├── bcel.md
│ │ │ ├── dom.md
│ │ │ ├── jcup.md
│ │ │ ├── LICENSE -> ../java.base/LICENSE
│ │ │ ├── xalan.md
│ │ │ └── xerces.md
│ │ └── jdk.unsupported
│ │ ├── ADDITIONAL_LICENSE_INFO -> ../java.base/ADDITIONAL_LICENSE_INFO
│ │ ├── ASSEMBLY_EXCEPTION -> ../java.base/ASSEMBLY_EXCEPTION
│ │ └── LICENSE -> ../java.base/LICENSE
│ ├── lib
│ │ ├── classlist
│ │ ├── jexec
│ │ ├── jrt-fs.jar
│ │ ├── jspawnhelper
│ │ ├── jvm.cfg
│ │ ├── libawt_headless.so
│ │ ├── libawt.so
│ │ ├── libawt_xawt.so
│ │ ├── libfontmanager.so
│ │ ├── libjavajpeg.so
│ │ ├── libjava.so
│ │ ├── libjawt.so
│ │ ├── libjimage.so
│ │ ├── libjli.so
│ │ ├── libjsig.so
│ │ ├── libjsound.so
│ │ ├── liblcms.so
│ │ ├── libmlib_image.so
│ │ ├── libnet.so
│ │ ├── libnio.so
│ │ ├── libprefs.so
│ │ ├── libsplashscreen.so
│ │ ├── libverify.so
│ │ ├── libzip.so
│ │ ├── modules
│ │ ├── psfontj2d.properties
│ │ ├── psfont.properties.ja
│ │ ├── security
│ │ │ ├── blacklisted.certs
│ │ │ ├── cacerts
│ │ │ ├── default.policy
│ │ │ └── public_suffix_list.dat
│ │ ├── server
│ │ │ ├── libjsig.so
│ │ │ └── libjvm.so
│ │ └── tzdb.dat
│ └── release
├── jlinkbase
│ ├── delegating
│ ├── jlinkjars
│ │ ├── javafx-base-11.0.2-linux.jar
│ │ ├── javafx-controls-11.0.2-linux.jar
│ │ ├── javafx-fxml-11.0.2-linux.jar
│ │ ├── javafx-graphics-11.0.2-linux.jar
│ │ ├── testing-1.0.jar
│ │ └── testing.merged.module-1.0.jar
│ ├── mergedjars
│ ├── nonmodjars
│ ├── tmpmerged
│ │ └── testing.merged.module-1.0.jar
│ └── tmpmodinfo
│ └── module-info.class
├── libs
│ └── testing-1.0.jar
├── resources
│ └── main
│ ├── fxml
│ │ └── file.fxml
│ ├── img
│ │ └── logo.png
│ ├── lang
│ ├── lib
│ ├── META-INF
│ │ └── MANIFEST.MF
│ └── style
│ └── style.css
└── tmp
├── compileJava
│ └── source-classes-mapping.txt
└── jar
└── MANIFEST.MF