Gradle+OpenJFX项目如何实现JavaFX传递依赖,仅在GUI模块配置
问题根源
你遇到的编译错误本质是两个原因共同导致的:
- OpenJFX插件默认会把所有声明的JavaFX模块依赖添加到GUI模块的
implementation依赖配置下,Gradle里implementation范围的依赖不会传递给上层依赖模块,仅在当前模块的编译和运行时可用。 - 你GUI模块的对外公开API(比如代码里的
Game类)的签名、父类、实现的接口中用到了JavaFX的类(比如javafx.application.Application),boot模块调用这些API时,编译器需要加载对应的JavaFX类才能完成编译,但是boot模块又没有对应依赖,就会抛出类找不到的错误。
解决方案
你可以根据需求二选一:
方案1:封装GUI模块接口,彻底隐藏JavaFX实现(推荐,符合内部实现细节的要求)
如果要完全把JavaFX封闭在GUI模块内部、上层完全无感知,你需要修改GUI模块的对外接口,不要让任何JavaFX的类型出现在GUI模块的public/protected方法签名、返回值、父类定义、公开属性里。
示例修改逻辑:
// 原错误写法:直接对外暴露继承了JavaFX Application的类 public class Game extends Application { public static void execute(String[] args) { launch(args); } // 其他JavaFX逻辑 }
// 封装后写法:JavaFX类型完全隐藏在内部私有类中 public class Game { // 私有内部类继承Application,不会对外暴露JavaFX类型 private static class GameApp extends Application { @Override public void start(Stage stage) { // 原有启动逻辑 } } // 公开方法的参数、返回值都是基础类型,无任何JavaFX相关内容 public static void execute(String[] args) { Application.launch(GameApp.class, args); } }
改完之后GUI模块不需要修改原有Gradle配置,boot模块也完全不需要感知JavaFX的存在,编译即可正常通过。
方案2:将JavaFX配置为可传递依赖
如果你暂时不想调整代码,可以修改GUI模块的OpenJFX插件配置,指定JavaFX依赖使用api范围(api范围的依赖会自动传递给上层依赖模块),修改gui/build.gradle.kts的javafx配置块即可:
javafx { version = "17" modules("javafx.controls", "javafx.fxml") // 新增这行,指定JavaFX依赖添加到api配置下支持传递 configuration = "api" }
改完之后上层boot模块不需要做任何JavaFX相关配置,即可拿到传递的JavaFX依赖完成编译。
内容的提问来源于stack exchange,提问作者Julian Kirsch
相关产品推荐
相关产品推荐

