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

升级JavaFX+Spring Boot应用至Java17时遇NoSuchMethodException问题

JavaFX 8升级到Java 17(Spring Boot 2.7.1)问题解决指引

核心问题分析

  • Java 9+的模块化系统(JPMS)禁止直接访问com.sun.javafx这类内部API,Utils.getResource属于未公开的内部方法,Java 17下无法调用,直接触发NoSuchMethodException。
  • Modena.css找不到是因为模块化环境下资源加载规则变更,加上Spring Boot的打包/运行机制影响了资源路径解析。

解决方案步骤

1. 替换内部API调用

找到代码中调用com.sun.javafx.scene.control.skin.Utils.getResource的逻辑,用JavaFX公开API替代:

// 原内部API调用(需删除)
// URL resource = Utils.getResource("modena.css");

// 方式1:直接使用JavaFX默认的Modena样式(推荐)
Scene scene = new Scene(root);
// JavaFX默认会自动应用Modena.css,无需手动添加

// 方式2:加载自定义样式文件
URL cssUrl = getClass().getResource("/path/to/your/custom-style.css");
if (cssUrl != null) {
    scene.getStylesheets().add(cssUrl.toExternalForm());
}

2. 调整POM配置兼容模块化

更新pom.xml,确保JavaFX依赖适配模块化,同时配置Spring Boot插件传递必要的JVM参数:

<dependencies>
    <!-- JavaFX模块化依赖 -->
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>17.0.6</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>17.0.6</version>
    </dependency>
    <!-- Spring Boot依赖保持2.7.1 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.7.1</version>
            <configuration>
                <jvmArguments>
                    --add-modules javafx.controls,javafx.fxml
                    <!-- 仅临时兼容未替换的内部API调用,建议后续彻底移除 -->
                    --add-exports javafx.controls/com.sun.javafx.scene.control.skin=ALL-UNNAMED
                </jvmArguments>
            </configuration>
        </plugin>
        <!-- JavaFX Maven插件,用于模块化环境下的打包与运行 -->
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.8</version>
            <configuration>
                <mainClass>你的主类全限定名(如com.example.demo.JavaFxApp)</mainClass>
                <modules>
                    <module>javafx.controls</module>
                    <module>javafx.fxml</module>
                </modules>
            </configuration>
        </plugin>
    </plugins>
</build>

3. 添加模块描述文件

在src/main/java目录下创建module-info.java,声明模块依赖与访问权限:

module your.module.name {
    // 声明依赖的模块
    requires javafx.controls;
    requires javafx.fxml;
    requires spring.boot;
    requires spring.boot.autoconfigure;

    // 允许Spring Boot扫描并访问你的模块类
    opens com.your.package to spring.boot, spring.boot.autoconfigure;
    // 若使用FXML,需打开FXML所在包给javafx.fxml模块访问
    opens com.your.package.fxml to javafx.fxml;

    // 导出主类所在包(按需配置)
    exports com.your.package;
}

将your.module.name和com.your.package替换为实际的模块名与包路径。

4. 修复资源加载

  • 若使用JavaFX默认的Modena样式,无需手动加载,JavaFX会自动应用。
  • 自定义样式文件需放在src/main/resources目录下,通过类加载器加载:
scene.getStylesheets().add(getClass().getResource("/custom-style.css").toExternalForm());
  • 禁止直接引用com.sun.javafx路径下的内部资源,这类路径在模块化环境下不对外暴露。

5. 运行测试

  • 使用JavaFX插件运行:mvn javafx:run
  • 或使用Spring Boot插件运行:mvn spring-boot:run

内容的提问来源于stack exchange,提问作者Conrad Bekondo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 22:27:22