当前位置: 首页 > 知识库问答 >
问题:

JavaFX警告:不支持的JavaFX配置:类是从“未命名模块@…”加载的

滕学义
2023-03-14

我刚刚下载了JavaFX并进行了设置,我什么也没做。我运行了示例代码,这是弹出的警告,尽管一切都编译了。我正在使用IntelliJ。

这是在Main.java中:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

这是在sample.fxml:

<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<GridPane fx:controller="sample.Controller"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>

运行时,一切编译,窗口弹出,但我得到如标题所述的警告。

我以前从未使用过JavaFX,所以我不确定在哪里可以找到这个模块。

共有1个答案

谷梁涵忍
2023-03-14

TL;博士:

确保JavaFX被解析为命名模块。

>

  • 非模块化应用:

    java --module-path <path-to-fx> --add-modules <fx-modules> ...
    

    模块化应用:

    java --module-path <path> --module <main-module>/<main-class> [args...]
    

    其中<代码>

    使用包含JavaFX的JDK发行版(更多信息请参见下面的答案)。可能仍然需要使用< code> - add-modules。

    该警告与Java 9中引入的Java平台模块系统(JPMS)有关。如果您不熟悉模块,那么我推荐您阅读《理解Java 9模块》以获得简要概述。

    JPMS带来了模块路径,它现在与类路径一起存在。当类从类路径加载时,它们成为所谓的未命名模块的一部分。而模块路径上的类包含在模块中,因此被加载到命名模块中。命名模块可能是自动的,也可能不是自动的,这取决于它是否分别具有<code>模块信息</code>描述符。

    JavaFX仅支持作为命名模块加载。换句话说,JavaFX只支持从模块路径加载,而不支持从类路径加载。从版本9开始,当框架被模块化的时候,这一点已经被隐含地实现了。但是现在,从版本16开始,如果JavaFX检测到它是从类路径加载的(即在未命名的模块中),就会发出警告。见JDK-8256362。

    解决方案是确保JavaFX从模块路径加载并解析为命名模块。注意JavaFX由七个模块组成,可以从其留档中看出。

    如何确保 JavaFX 解析为命名模块可能取决于您的环境(例如,非模块化应用程序与模块化应用程序、外部 JavaFX SDK 等)。下面的示例都使用命令行来演示如何设置所需的参数。但是,如果您使用的是IDE(例如NetBeans,IntelliJ,Eclipse)和/或构建工具(例如Maven,Gradle),并且不确定在何处设置这些参数,请查看JavaFX 11入门。

    请注意,Gradle和Maven都有插件,可以更容易地使用JavaFX(即,它们为您处理所有配置)。

    如果您的代码是非模块化的,那么您就没有< code>module-info描述符。这意味着将JavaFX添加到模块路径是不够的;您还必须强制Java解析JavaFX模块。这可以通过< code> - add-modules参数来完成。

    例如:

    java --module-path <path-to-fx> --add-modules javafx.controls ...
    

    请注意,我只在 --add-modules 参数中包含 javafx.controls 模块。这是因为它需要javafx.base和javafx.graphics模块,这意味着它们将被隐式拉入。

    如果需要其他模块,则需要将它们包含在--add modules参数中,并用逗号分隔。

    此外,请注意,在这种情况下,代码和其他非模块依赖项可以放在类路径上。重要的部分是JavaFX是从模块路径加载的。

    如果您的代码是模块化的,那么您将拥有一个< code>module-info描述符。该描述符将具有必要的< code>requires指令。在这种情况下,您不再需要使用< code> - add-modules,但是您需要确保通过< code> - module将应用程序作为一个模块启动。

    例如:

    module app {
      // transitively requires javafx.base and javafx.graphics
      requires javafx.controls;
    
      // export javafx.application.Application implementation's package
      // to at least javafx.graphics
      exports com.example.app to javafx.graphics;
    }
    
    java --module-path <path> --module app/com.example.app.Main [args...]
    

    为此,您不仅需要将JavaFX放在模块路径上,还需要将自己的模块放在模块上。

    自Java11起,JavaFX不再包含在Oracle提供的JDK中。但是Oracle并不是基于OpenJDK的Java的唯一供应商。有供应商提供包含JavaFX的JDK发行版。其中至少有两个是:

    • BellSoft Libica JDK(确保选择“完整JDK”选项)。
    • Azul Zulu JDK(确保选择“JDK FX”包)。

    当JavaFX包含在JDK中时,它现在像所有其他Java模块一样成为运行时映像的一部分(例如Java.base)。这意味着它将自动作为命名模块加载,您不再需要手动将JavaFX放在模块路径上。但是,如果您的应用程序是非模块化的,那么您可能仍然需要使用--addmodules(不确定)。

    当您要部署JavaFX应用程序时,在运行时映像中包含JavaFX可能是最简单的方法。您可以使用< code > jlink /< code > jpackage 工具来完成此操作。这可以通过包含JavaFX的JDK或外部JavaFX SDK来完成。但是,如果您使用后者,那么在制作定制的运行时映像时一定要使用JMOD文件(或者使用来自Maven Central的JavaFX JARs,其中嵌入了所需的本机代码)。

    如果您的代码是非模块化的,那么您需要创建一个包含JavaFX(以及您的应用程序所需的所有其他非自动命名模块)的自定义运行时映像,然后配置< code>jpackage将您的代码(以及所有非模块化依赖项)放在类路径上。

    据我所知,如果从类路径加载JavaFX,则当前没有任何中断。这意味着另一种选择,至少目前是忽略警告。但是,我建议至少将 JavaFX 放在模块路径上,如果可以这样做而不会有太多麻烦的话。

  •  类似资料:
    • 我有多模块项目: api模块有my持久性作为一个依赖。我正在谈论的配置类应该从类路径中检测出来,这不是我忽略或错过的原因 在持久化模块中的包下配置类 ApiApplication类位于 需要帮忙吗?

    • 我是OSGi概念的新手,对于下面的错误,我非常感谢您的帮助。 当运行独立应用程序时没有问题,但是当同一个应用程序放在OSGI包中时,我们得到以下错误。 原因异常java.lang.运行时异常:无法实例化解析器org.apache.xerces.parsers.SAXParser:java.lang.类org.apache.xerces.parsers.SAXParser无法转换为类org.xml.

    • 搜索之后,我发现了两个有趣的答案: > 对 javaFX 的本机映像格式支持 使用javaFX控制gif图像 但是正如我所看到的,javaFX不支持APNG图像。如何使用任何外部库或编写一些代码来解决此问题。我需要一个解决方案... 谢谢你的帮助。

    • 项目/ SRC/ 主/ Java/ 资源/ baselayout.fxml 不是应该有用吗?我本来工作得很好,但突然就不是了。我不知道还能做什么。

    • 问题内容: 我搬到一台装有最新的Sun Java编译器的新机器上,并注意到现有Java 6代码中的一些警告。Eclipse IDE建议我用以下注释该作业: 例如: 当我使用较旧的编译器(JDK 1.6.0_20)返回机器时,我注意到该较旧的编译器现在警告禁止“原始类型”警告,声称不支持这种禁止,并建议使用@SuppressWarnings替换它。 (“未选中”)。同样,在某些地方,最新的编译器默认