RHEL系统中TestFX与Monocle无头模式运行失败问题求助
问题:RHEL 9.4 上 TestFX 无头模式运行失败
环境信息:
- 系统:RHEL 9.4
- Java:1.8.0_431
- Monocle:1.8.0_20
- 应用:TestFX 程序(有头模式运行正常,需适配CI无头场景)
场景1:CLI执行Maven命令失败
执行命令:
mvn clean install -Dtestfx.headless=true -Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw -Dprism.txt=t2K -Dheadless.geometry=16000x12000-32 -Djavafx.platform=linux -Djava.awt.headless=true -X
错误日志:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.178 sec <<< FAILURE! com.example.TestFXExampleTest Time elapsed: 0.177 sec <<< ERROR! java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NoClassDefFoundError: com/sun/glass/ui/Robot at org.testfx.util.WaitForAsyncUtils.waitFor(WaitForAsyncUtils.java:301) at org.testfx.api.FxToolkit.registerPrimaryStage(FxToolkit.java:113)...
场景2:IntelliJ传参初始化失败
通过IntelliJ传递 -Dheadless=true 后,执行以下初始化代码:
@BeforeClass public static void setUpHeadlessMode() throws Exception { if (Boolean.getBoolean("headless")) { // System.setProperty("javafx.platform", "monocle"); System.setProperty("testfx.robot", "glass"); System.setProperty("testfx.headless", "true"); System.setProperty("glass.platform", "Monocle"); System.setProperty("monocle.platform", "Headless"); System.setProperty("prism.order", "sw"); System.setProperty("prism.text", "t2k"); System.setProperty("java.awt.headless", "true"); } registerPrimaryStage(); }
错误日志:
java.lang.NoSuchMethodException: com.sun.glass.ui.Screen.<init>(long, int, int, int, int, int, int, int, int, int, int, int, float) at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.getDeclaredConstructor(Class.java:2178) at com.sun.glass.ui.monocle.MonocleApplication$2.run(MonocleApplication.java:234) ...
现有POM依赖片段
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>11</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>11</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-graphics</artifactId> <version>11</version> </dependency>
补充说明
- 有头模式运行正常,排除基础POM配置问题
- Windows下依赖匹配版本的
glass.dll可正常运行无头模式,推测Linux需对应.so文件,但未找到 - 机器限制严格,无法随意安装软件或从GitHub获取资源
- 同类机器上无头测试均失败
解决方案
1. 修复版本兼容性冲突
当前Java 8 + Monocle 1.8.0_20 与 JavaFX 11 存在核心版本不兼容问题:
- JavaFX 11是脱离JDK独立发布的版本,其内部
com.sun.glass类结构与Java 8自带的JavaFX(及对应Monocle)完全不匹配,这是NoSuchMethodException的根本原因。 - 两种修复方向:
- 坚持Java 8:将JavaFX依赖替换为Java 8兼容版本(如Oracle JDK 8自带的JavaFX,或OpenJFX 8),同时使用与JDK小版本匹配的Monocle(1.8.0_XXX系列)。
- 升级到Java 11+:使用对应版本的OpenJFX配套Monocle实现,无需单独引入旧版Monocle。
2. 修正无头模式参数
针对Java 8 + 原生JavaFX场景,调整VM参数:
- 移除
-Djavafx.platform=linux,替换为-Djavafx.platform=monocle - 替换过大的分辨率参数,改用
-Dmonocle.headless.width=1600-Dmonocle.headless.height=1200 - 修正后的Maven命令示例:
mvn clean install -Dtestfx.headless=true -Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dmonocle.headless.width=1600 -Dmonocle.headless.height=1200 -Dprism.order=sw -Dprism.text=t2k -Djava.awt.headless=true
3. 确保原生库存在
RHEL系统中,Java 8自带的Monocle原生库(.so文件)通常位于JDK_HOME/jre/lib/amd64/glass/monocle目录:
- 检查是否安装了完整JDK(而非精简版JRE),部分精简包会移除JavaFX组件
- 若无法安装完整JDK,可从同版本的Oracle/OpenJDK包中提取
libglass_monocle.so,放置到项目src/main/resources或JVM的library.path目录下
4. 调整测试初始化时机
确保系统属性在JavaFX类加载前设置,将初始化逻辑移到静态代码块:
static { if (Boolean.getBoolean("headless")) { System.setProperty("testfx.robot", "glass"); System.setProperty("testfx.headless", "true"); System.setProperty("glass.platform", "Monocle"); System.setProperty("monocle.platform", "Headless"); System.setProperty("prism.order", "sw"); System.setProperty("prism.text", "t2k"); System.setProperty("java.awt.headless", "true"); System.setProperty("javafx.platform", "monocle"); } } @BeforeClass public static void setUp() throws Exception { registerPrimaryStage(); }
内容的提问来源于stack exchange,提问作者Vark Ster
相关产品推荐
相关产品推荐

