未找到带有 Gradle 错误模块的 JavaFX

JavaFX with Gradle error module not found

我正在 IntelliJ 中使用 JavaFX 创建一个示例演示应用程序,但我需要使用一个名为 JavaFaker 库的库。我使用 Gradle 作为构建系统,但每次我尝试添加库时,无论是作为 build.gradle 文件中的实现,还是通过 IntelliJ 项目结构选项,module.java文件说错误:找不到模块。我已经尝试将它添加到模块中,但没有任何变化。

模块-info.java

module com.example.demo1 {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafaker;

    opens com.example.demo1 to javafx.fxml;
    exports com.example.demo1;
}

build.gradle

plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.10'
    id 'org.beryx.jlink' version '2.24.1'
}

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

repositories {
    mavenCentral()
}

ext {
    junitVersion = '5.8.2'
    javaFakerVersion = '1.0.2'
}

sourceCompatibility = '17'
targetCompatibility = '17'

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

application {
    mainModule = 'com.example.demo1'
    mainClass = 'com.example.demo1.HelloApplication'
}

javafx {
    version = '17.0.1'
    modules = ['javafx.controls', 'javafx.fxml']
}

dependencies {
    implementation("com.github.javafaker:javafaker:${javaFakerVersion}")
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}

test {
    useJUnitPlatform()
}

jlink {
    imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip") as RegularFile
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'app'
    }
}

jlinkZip {
    group = 'distribution'
}

错误信息

> Task :HelloApplication.main() FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafaker not found, required by com.example.demo1

我尝试了一段时间使它与 Gradle 一起工作,但无法做到。我不太了解 Gradle,但除非你了解,否则我不建议尝试。

使用 Maven

很容易让它与 Maven 一起工作。

  1. 创建一个new JavaFX project

    • 选择 Maven 作为构建系统而不是 Gradle。
  2. 添加 javafaker 依赖到你的 pom.xml.

    <dependency>
        <groupId>com.github.javafaker</groupId>
        <artifactId>javafaker</artifactId>
        <version>1.0.2</version>
    </dependency>
    
  3. 按 Maven 中的刷新图标 window 将 Maven 项目重新导入 IDE.

  4. 将 javafaker 模块的 requires 子句添加到您的 module-info.java

    requires javafaker;
    
  5. 添加代码以在您的应用中使用 javafaker。

我没有使用 javafaker 的代码,所以我无法验证最后一步是否有效,但请试一试。 . .

我遇到的一些问题 Gradle

查看 Gradle Documentation 部分“使用非模块的库”:

A third case are traditional libraries that provide no module information at all — for example commons-cli:commons-cli:1.4. Gradle puts such libraries on the classpath instead of the module path. The classpath is then treated as one module (the so called unnamed module) by Java.

这就是您使用的 javafaker 依赖项的情况。它没有 module-info.java,也没有在其清单文件中定义 属性 Automatic-Module-Name(这是本节中的其他两种情况)。其他两种情况都会导致 Gradle 将库放在模块路径上,但你的情况意味着它在 class 路径上。

当您想从您定义的命名模块访问代码时,这是一个问题,因为您创建了一个 module-info.java

你的模块只能找到它需要的模块的代码和资源(需要在模块路径上),所以你在module-info.java中加上requires javafaker,得到如下尝试 运行 通过 IDE:

java.lang.module.FindException: Module javafaker not found, required by com.example.demo1

所以你按照我链接的 Gradle 文档的建议从 module-info.java 中删除了 requires javafaker,当你尝试编译时你会得到以下内容:

Package 'com.github.javafaker' is declared in module 'javafaker', but module 'com.example.demo1' does not read it

所以你必须把库放在module-info才能使用它,但是你不能把库放在module-info因为Gradle放在class路径 -> catch-22.

有一些解决方法,例如提供 VM 参数以允许访问未命名的模块(即 class 路径),或者修改 Gradle 构建的模块路径处理 and/or IDE 不知何故(我不知道如何),但它们非常丑陋。

另一方面,对于这种情况,Maven 的行为不同于 Gradle,它将依赖库放在模块路径上,即使它没有 module-info.java 或 [=15] =] 定义。这意味着它(对我而言)更容易设置和使用。

关于模块命名的附带建议

这不是错误,但注意:虽然module names with numbers in them are now allowed due to a change in the module system specification, it is probably best not to put numbers in module names to prevent the module name and version info being confused.

我最近遇到了类似的问题。但是,将 static 添加到 requires 语句有帮助。也许这将解决您的问题,而无需切换到 maven。

因此您需要添加:requires static javafaker;