JavaFX Maven项目运行报错:UnsupportedOperationException与Runtime缺失
解决Maven构建JavaFX项目的两个运行错误:DISPLAY无法打开与Runtime组件缺失
问题概述
我在开发一款UML编辑器,采用Maven构建JavaFX项目时遇到两个棘手问题:
- 执行
mvn clean javafx:run命令时,抛出UnsupportedOperationException: Unable to open DISPLAY错误 - 在VSCode中点击运行按钮,直接提示
Error: JavaFX runtime components are missing
已尝试修改FXML资源路径、在Linux虚拟机重新安装项目,但问题仍未解决。核心代码如下:
MainWindow.java
package com.classuml; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; // JavaFX Application Class public class MainWindow extends Application { @Override public void start(Stage primaryStage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("/com/classuml/mainwindow.fxml")); Parent root = loader.load(); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.show(); } // Optional: You can add methods to this class to show the window from other classes. }
mainwindow.fxml
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2015, 2019, Gluon and/or its affiliates. All rights reserved. Use is subject to license terms. This file is available and licensed under the following license: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Oracle Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> <?import javafx.scene.control.Label?> <?import javafx.scene.control.Menu?> <?import javafx.scene.control.MenuBar?> <?import javafx.scene.control.MenuItem?> <?import javafx.scene.control.ScrollBar?> <?import javafx.scene.control.SeparatorMenuItem?> <?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.VBox?> <?import javafx.scene.text.Font?> <VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.classuml.Controller"> <children> <MenuBar VBox.vgrow="NEVER"> <menus> <Menu mnemonicParsing="false" text="File"> <items> <MenuItem mnemonicParsing="false" text="New Diagram" /> <MenuItem mnemonicParsing="false" text="Open Diagram…" /> <Menu mnemonicParsing="false" text="Open Recent" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" text="Close" /> <MenuItem mnemonicParsing="false" text="Save" /> <MenuItem mnemonicParsing="false" text="Save As…" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" text="Preferences…" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" text="Quit" /> </items> </Menu> <Menu mnemonicParsing="false" text="Edit"> <items> <MenuItem mnemonicParsing="false" text="Undo" /> <MenuItem mnemonicParsing="false" text="Redo" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" text="Cut" /> <MenuItem mnemonicParsing="false" text="Copy" /> <MenuItem mnemonicParsing="false" text="Paste" /> <MenuItem mnemonicParsing="false" text="Delete" /> <SeparatorMenuItem mnemonicParsing="false" /> <MenuItem mnemonicParsing="false" text="Select All" /> <MenuItem mnemonicParsing="false" text="Unselect All" /> <SeparatorMenuItem mnemonicParsing="false" /> </items> </Menu> <Menu mnemonicParsing="false" text="Classes"> <items> <MenuItem mnemonicParsing="false" text="Add class" /> <MenuItem mnemonicParsing="false" text="Set relationship with..." /> <MenuItem mnemonicParsing="false" text="Delete class" /> </items> </Menu> <Menu mnemonicParsing="false" text="Attributes"> <items> <MenuItem mnemonicParsing="false" text="Delete Attribute" /> <MenuItem mnemonicParsing="false" text="Add Attribute" /> </items> </Menu> <Menu mnemonicParsing="false" text="Help"> <items> <MenuItem mnemonicParsing="false" text="Show help document" /> <MenuItem mnemonicParsing="false" text="About UML Reader" /> </items> </Menu> </menus> </MenuBar> <AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS"> <children> <Label alignment="CENTER" layoutX="275.0" layoutY="1.0" style=" " text="UML Reader" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false"> <font> <Font size="18.0" /> </font> </Label> <ScrollBar layoutX="633.0" orientation="VERTICAL" prefHeight="375.0" prefWidth="14.0" /> </children> </AnchorPane> </children> </VBox>
错误1:Unable to open DISPLAY(Linux环境)
原因
Linux下JavaFX依赖图形界面环境,出现这个错误通常是三种情况:
- 虚拟机未启用图形桌面环境,仅运行纯命令行
- 当前终端会话未关联DISPLAY环境变量
- 远程SSH连接时未开启X11转发
解决方案
- 检查虚拟机图形设置
- 如果是VMware/VirtualBox,开启虚拟机设置中的"图形加速"选项,启动时进入桌面环境(而非纯命令行模式)。
- 手动设置DISPLAY变量
在终端执行以下命令后,重新运行Maven命令:
这个值对应Linux默认桌面会话的DISPLAY标识,如果无效可以尝试export DISPLAY=:0export DISPLAY=:1。 - 远程SSH连接开启X11转发
连接服务器时添加-X参数:
同时确保服务器端安装了ssh -X your_username@your_vm_ipxauth工具,客户端SSH配置开启了X11转发。 - 完善Maven插件配置
确保pom.xml中的javafx-maven-plugin指定了正确的主类和JavaFX模块:<plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.classuml.MainWindow</mainClass> <modules> <module>javafx.controls</module> <module>javafx.fxml</module> </modules> </configuration> </plugin>
错误2:VSCode运行提示JavaFX runtime components are missing
原因
VSCode默认的Java运行配置不会自动引入JavaFX依赖,JVM找不到必需的运行时组件。
解决方案
- 修改launch.json配置
打开项目根目录下的.vscode/launch.json,添加vmArgs参数指定JavaFX模块路径和所需模块:
注意:{ "version": "0.2.0", "configurations": [ { "type": "java", "name": "Launch MainWindow", "request": "launch", "mainClass": "com.classuml.MainWindow", "vmArgs": "--module-path ${env:PATH_TO_FX} --add-modules javafx.controls,javafx.fxml" } ] }${env:PATH_TO_FX}是系统环境变量,需指向本地JavaFX SDK的lib目录。如果不想设置环境变量,直接替换成绝对路径即可,比如/opt/javafx-sdk-21/lib。 - 确保Maven依赖正确
在pom.xml中引入JavaFX依赖,并指定对应Linux系统的分类器:<dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>21</version> <classifier>linux</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>21</version> <classifier>linux</classifier> </dependency> </dependencies>
额外验证:FXML路径正确性
你的代码中/com/classuml/mainwindow.fxml的路径是正确的,只要确保文件放在src/main/resources/com/classuml/目录下即可,Maven会自动将该目录下的资源打包到classpath中。目录结构需符合以下规范:
src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── classuml/ │ │ └── MainWindow.java │ └── resources/ │ └── com/ │ └── classuml/ │ └── mainwindow.fxml
内容的提问来源于stack exchange,提问作者Kuhaku
相关产品推荐
相关产品推荐

