不支持的 JavaFX 配置:类 是从 'unnamed module @...' 加载的

Unsupported JavaFX configuration: classes were loaded from 'unnamed module @...'

即使不完全相同,也似乎非常相似。在那个问题中,Slaw 的第二个建议涉及修复 module-info 以进行正确的模块管理似乎是合适的。但这到底是什么意思?或者更确切地说,javafx 抱怨我的模块有问题还是它正在谈论的其他模块?

这是我的模块-info.java

module myprogram.main {
    requires javafx.controls;
    requires javafx.fxml;
    requires janino;
    requires commons.compiler;
    requires org.fxmisc.richtext;
    requires wellbehavedfx;
    requires zt.process.killer;
    requires zt.exec;
    exports com.bla.myprogram;
    opens com.bla.myprogram to javafx.fxml;
}

jdk: jdk16.0.1+9

java -jar .\MyProgram.jar

@Override
    public void start(Stage primaryStage) throws Exception {
        System.out.println("enter start");
        ...

 public static void main(String[] args) {
        System.out.println("enter main");
        launch();
    }
enter main
Aug 04, 2021 1:22:52 PM com.sun.javafx.application.PlatformImpl startup
WARNING: Unsupported JavaFX configuration: classes were loaded from 'unnamed module @6203f37a'
enter start

(这是我的 gradle.build 如果它有任何意义的话)

plugins {
    id 'java-library'
    id 'application'
    id 'org.openjfx.javafxplugin' version "0.0.10"
}

group 'com.bla.myprogram'
version '0.3'

def currentOS = org.gradle.internal.os.OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
    platform = 'win'
} else if (currentOS.isLinux()) {
    platform = 'linux'
} else if (currentOS.isMacOsX()) {
    platform = 'mac'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
    implementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25'
    implementation "org.openjfx:javafx-base:11:${platform}"
    implementation "org.openjfx:javafx-graphics:11:${platform}"
    implementation "org.openjfx:javafx-controls:11:${platform}"
    implementation "org.openjfx:javafx-fxml:11:${platform}"
    implementation group: 'org.codehaus.janino', name: 'janino', version: '3.0.7'
    implementation group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.10.6'
    implementation group: 'org.fxmisc.wellbehaved', name: 'wellbehavedfx', version: '0.3.3'
    implementation group: 'org.zeroturnaround', name: 'zt-process-killer', version: '1.10'
    implementation group: 'org.zeroturnaround', name: 'zt-exec', version: '1.12'
}

test {
    useJUnitPlatform()
}

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

mainClassName = 'com.bla.myprogram.Main'

jar {
    manifest {
        attributes "Main-Class": 'com.bla.myprogram.Main'
    }

    from { (configurations.runtimeClasspath).collect { it.isDirectory() ? it : zipTree(it) } } {
        exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA'
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }
}

task createProperties(dependsOn: processResources) {
    doLast {
        new File("$buildDir/resources/main/version.properties").withWriter { w ->
            Properties p = new Properties()
            p['version'] = project.version.toString()
            p['name'] = rootProject.name.toString()
            p.store w, null
        }
    }
}

classes {
    dependsOn createProperties
}

我认为这可能是答案:

Shading multiple modules into the same jar is not possible, because a jar can only contain 1 module. So, I suppose the shade plugin resolves that problem by removing the module-info files of the dependencies it's using, which means the JavaFX code will not be loaded as a module, and you get a warning like this. I think the only way to get rid of the warning is to not use shading, but keep the JavaFX modules as separate jar files, that you then put on the module path when running the application.

所以显而易见的选择就是忽略警告。 Javafx 警告似乎很少指示任何有用的信息。但是,如果您将您的应用程序分发给其他用户,并不总是选择将视线移开。

另一个(天真的)选项是在启动时重定向错误流。这有点天真,因为可能会遗漏一些其他错误..

public void start(Stage primaryStage) throws Exception {
        System.setErr(oldErr); // reference to default System.err
        ...
public static void main(String[] args) {
        System.setErr(new PrintStream(new NullOutputStream())); 
        launch();
}

另一种选择是使用 jpackage 之类的东西而不是制作 jar。无论如何,这可能不是一个坏主意,因为每个 OS.

的 javafx 库都是不同的