【问题标题】:Gradle not including FXML and imagesGradle 不包括 FXML 和图像
【发布时间】:2018-08-03 03:25:36
【问题描述】:

我一直在寻找在build.gradle 中包含 FXML 和图像的正确方法,以便将它们构建到 jar 中。我已经查看here 并尝试过,但它仍然无法正常工作。

抛出此错误:java.lang.NullPointerException: inputStream is null.

这里是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"
    }
}

这里是 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);

堆栈跟踪表明loader.load(getClass().getResourceAsStream("layoutForm.fxml")); 导致错误

这里是源树:

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

你可以看到layoutForm.fxmlIcon.png都在树中

这是 Out 树:

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

在输出树中,它们都不存在,我已经摆弄了几个小时试图解决这个问题。任何帮助将不胜感激。

另外,如果您需要更多 here 是 Github 存储库

【问题讨论】:

  • 您是否尝试过将 FXML 和图像文件放在 resources 文件下,而不是将它们放在源文件下?即遵循标准的 Maven 项目布局文件结构。
  • Maven 标准直接布局:maven.apache.org/guides/introduction/…
  • @Kerry OP 显然在使用 gradle,为什么要将它们发送到 maven 文档?
  • @lance-java 因为我认为 gradle 默认使用 Maven 文件结构?
  • 是的,因为 Maven 文档中提到的 src/main/filterssrc/assemblysrc/site 等不适用于 Gradle,可能会导致混淆。

标签: java gradle intellij-idea build continuous-integration


【解决方案1】:

您将 xml 文件放在名为 src/main/java 的文件夹中(提示:java dir 用于 java 文件)

资源(例如 xml、图像文件等)应放入 src/main/resources

这是 Maven 和 Gradle 都遵循的标准约定。如果您想更改默认设置,但首先我强烈建议您考虑遵循合理的约定。

另外,关于类加载器的说明

  • SomeClass.class.getResource("foo.xml") 将查找与类包相关的 xml
  • SomeClass.class.getResource("/foo.xml") 将查找相对于类路径根目录的 xml

所以在你的例子中

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

这是在类路径com/voidustries/poly/gui/layoutForm.fxml上寻找一个文件

因此,如果您想将资源留在原处,您需要将 src/main/java 添加到资源文件夹,而不是 src/main/java/com/voidustries/poly

【讨论】:

    【解决方案2】:

    只是为了让任何不满意的人补充我的三便士:

    在 src/main/resources (Windows src\main\resources) 下,您似乎必须使资源文件的“位置”匹配 用于运行 .class 文件的类路径。

    我已经通过在 JavaFX gradle 项目中使用 .fxml 文件得出结论(直到知识渊博的人另有说明)。

    Main(包含main())在一个名为“sample”的包中...所以.java文件的路径是...\EclipseWorkspace\TestFXexp\src\main\java\sample\ Main.java.

    这似乎意味着您的 .fxml 文件必须放在此处:...\EclipseWorkspace\TestFXexp\src\main\resources\ sample\config.fxml。

    gradle installdist 然后将正确打包 .jar 以进行部署。展开 .jar 您会发现 config.xml 已与 .class 文件一起放在目录 sample\ 下......并且 Main.class 文件能够找到并使用它。

    当我像这样放置 config.fxml 时:...\EclipseWorkspace\TestFXexp\src\main\resources\config.fxml ... 它不起作用:config.fxml 被放在 外面.jar文件和Main.class文件中的sample包找不到。

    【讨论】:

    • 我会说你的结论是正确的。但我不喜欢 Gradle 希望我们改变以前的做法。对于图像和其他真正的“资源”来说,这是有道理的,但 FXML 文件本质上只是简写的 .java 文件,它们进行实例化、将子项添加到容器并设置属性。我们经常同时处理 FXML 文件及其控制器,我不希望为了获得我需要的 FXML 而打开两个完全独立的“镜像”目录结构。更不用说移动重构需要我们将文件移动到两个文件夹中的麻烦了。
    • 另外,如果我知道我必须手动将数十或数百个 FXML 文件移动到这个单独的目录结构中,我不太可能从 NetBeans Ant JavaFX 项目切换到 Gradle 项目。 IMO 在这种情况下,覆盖 Gradle 的常规约定是有意义的,仅适用于 FXML 文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多