You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:50:16