Gradle not including FXML and images

2019-05-30 05:13发布

I have been looking around for the proper way to include FXML and images in the build.gradle so that they are build into the jar. I have look here and tried it but it still does not work.

Throws this error: java.lang.NullPointerException: inputStream is null.

Here is the build.gradle (Github):

group 'com.voidustries'
version '1.0-SNAPSHOT'

sourceSets {
    main {
        resources {
            srcDirs = ["src/main/java/com/voidustries/poly"]
            includes = ["gui/layoutForm.fxml"]
        }
    }
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.1.0'
    }
}

apply plugin: 'java'
apply plugin: 'org.junit.platform.gradle.plugin'

repositories {
    mavenCentral()
}

dependencies {
    testCompile('org.junit.jupiter:junit-jupiter-api:5.1.0')
    testRuntime('org.junit.jupiter:junit-jupiter-engine:5.1.0')
}

task wrapper(type: Wrapper) {
    description = 'Generates gradlew[.bat] scripts'
    gradleVersion = '4.3.1'
}

test {
    testLogging {
        events "passed", "skipped", "failed"
    }
}

Here is GUI.java (Github):

FXMLLoader loader = new FXMLLoader();
FileInputStream fis = new FileInputStream(settings);
ResourceBundle resourceBundle = new PropertyResourceBundle(fis);
loader.setResources(resourceBundle);

Parent root = loader.load(getClass().getResourceAsStream("layoutForm.fxml"));
Platform.setImplicitExit(false);

The stacktrace says that loader.load(getClass().getResourceAsStream("layoutForm.fxml")); is causing the error

Here is the source Tree:

com
└───voidustries
    └───poly
        │   CustomFormatter.java
        │   Main.java
        │   PolyThreads.java
        │   SysTray.java
        │
        ├───gui
        │       Controller.java
        │       GUI.java
        │       Icon.png
        │       layoutForm.fxml
        │
        └───img
                Icon.png

you can see that layoutForm.fxml and Icon.png are both there in the tree

Here is the Out tree:

com
└───voidustries
    └───poly
        │   CustomFormatter.class
        │   Main.class
        │   PolyThreads.class
        │   SysTray.class
        │
        └───gui
                Controller.class
                GUI.class

In the out tree they are both absent and I have been fiddling for hours trying to fix this issue. Any help would be greatly appreciated.

Also if you need more here is the Github repository

2条回答
祖国的老花朵
2楼-- · 2019-05-30 05:40

Just to add my thre'penny bit for anyone not getting satisfaction:

Under src/main/resources (Windows src\main\resources) you seem to have to make the "location" of your resource file match the classpath used to run your .class files.

I have concluded this (until a more knowledgeable person says otherwise) from playing around with an .fxml file in a JavaFX gradle project.

The class Main (containing main()) is in a package called "sample"... so the path to the .java file is ...\EclipseWorkspace\TestFXexp\src\main\java\sample\Main.java.

This appears to mean that your .fxml file has to go here: ...\EclipseWorkspace\TestFXexp\src\main\resources\ sample\config.fxml.

gradle installdist will then correctly package up the .jar for deployment. Expanding the .jar you find that config.xml has been put under directory sample\ along with the .class files... and that the Main.class file is able to find it and use it.

When I put the config.fxml like this: ...\EclipseWorkspace\TestFXexp\src\main\resources\config.fxml ... it didn't work: the config.fxml is put then outside the sample package in the .jar file and the Main.class file can't find it.

查看更多
一夜七次
3楼-- · 2019-05-30 05:46

You are putting xml files in a folder called src/main/java (hint: java dir is for java files)

Resources (eg xml, image files etc) should go in src/main/resources

This is a standard convention followed by both Maven and Gradle. If you want to change the defaults you can, but first I strongly advise you consider following the sensible conventions.

Also, a note on classloaders

  • SomeClass.class.getResource("foo.xml") will look for the xml relative to the class package
  • SomeClass.class.getResource("/foo.xml") will look for the xml relative to the classpath root

So in your example

getClass().getResourceAsStream("layoutForm.fxml")

This is looking for a file on the classpath com/voidustries/poly/gui/layoutForm.fxml

So if you want to leave your resources where they are, you will want to add src/main/java to the resource folders, not src/main/java/com/voidustries/poly

查看更多
登录 后发表回答