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

使用ControlsFX AutoCompletionBinding时出现IllegalAccessError的解决方法

解决JDK17下ControlsFX AutoCompletionBinding的IllegalAccessError模块化问题

问题描述

使用ControlsFX的TextFields.bindAutoCompletion()时触发IllegalAccessError,错误信息如下:

class org.controlsfx.control.textfield.AutoCompletionBinding (in module org.controlsfx.controls) cannot access class com.sun.javafx.event.EventHandlerManager (in module javafx.base) because module javafx.base does not export com.sun.javafx.event to module org.controlsfx.controls

业务场景代码(实时从数据库搜索学生姓名并绑定自动补全):

try {
    SearchSession searchSession = Search.session(JpaUtil.getEntityManager());
    SearchResult<Student> result = searchSession.search(Student.class)
            .where(f -> f.match()
                    .field("firstName")
                    .matching(search))
            .fetch(20);
    List<Student> list = result.hits();
    TextFields.bindAutoCompletion(searchField, list);
} catch (Exception ex) {
    ex.printStackTrace();
}

原因分析

JDK9+引入的模块化系统(JPMS)限制了模块间的内部包访问,com.sun.javafx.event是JavaFX的内部私有包,默认不会对外暴露。旧版本的ControlsFX在实现AutoCompletionBinding时直接调用了这个内部包的EventHandlerManager类,导致JDK17下触发访问权限错误。

解决方案

方案1:添加VM启动参数(快速临时修复)

在JVM启动参数中强制让javafx.base模块向org.controlsfx.controls模块开放内部包:

--add-exports javafx.base/com.sun.javafx.event=org.controlsfx.controls

IDE运行时直接在Run Configuration的VM Options中添加;打包后运行则在启动命令中追加该参数。

方案2:升级ControlsFX到兼容JDK17的版本

ControlsFX从11.1.2版本开始修复了JPMS模块化兼容问题,不再依赖JavaFX的内部私有API。直接升级依赖:

  • Maven:
<dependency>
    <groupId>org.controlsfx</groupId>
    <artifactId>controlsfx</artifactId>
    <version>11.1.4</version> <!-- 推荐使用最新稳定版 -->
</dependency>
  • Gradle:
implementation 'org.controlsfx:controlsfx:11.1.4'

方案3:切换为非模块化运行(如果项目未使用JPMS)

如果项目未显式声明module-info.java,可将项目从modulepath切换为classpath运行,绕过JPMS的权限检查:

  • IDE中:在Project Structure里将依赖从Module Libraries改为Global Libraries,或调整编译选项为使用classpath。
  • 构建工具:Maven/Gradle中移除模块化相关配置,确保编译和运行时使用classpath而非modulepath。

优化建议

针对实时搜索场景,建议使用AutoCompletionBinding的异步数据源版本,避免数据库查询阻塞UI线程:

TextFields.bindAutoCompletion(searchField, param -> {
    // 异步执行数据库搜索
    CompletableFuture<List<String>> future = CompletableFuture.supplyAsync(() -> {
        try (SearchSession searchSession = Search.session(JpaUtil.getEntityManager())) {
            SearchResult<Student> result = searchSession.search(Student.class)
                    .where(f -> f.match().field("firstName").matching(param.getUserText()))
                    .fetch(20);
            return result.hits().stream().map(Student::getFirstName).toList();
        } catch (Exception e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    });
    return future.thenApply(CompletionStage::toList);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:27:24