如何配置Gradle多模块项目实现Server与Game模块双向依赖?
项目结构
Parent ├── build.gradle ├── settings.gradle ├── Server │ ├── src │ │ ├── main │ │ │ └── Server.java │ │ └── test │ │ └── ServerTest.java │ └── build.gradle └── Game ├── src │ ├── main │ │ └── Game.java │ └── test │ └── GameTest.java └── build.gradle
问题需求
希望配置Gradle项目,让Server模块可调用Game模块,同时Game模块也可调用Server模块。
解决方案
嘿,这个问题其实涉及到Gradle里的循环依赖问题——默认情况下Gradle是不允许模块之间互相依赖的,因为这会打乱构建顺序,直接配置双向implementation依赖会直接报错。不过我们有两种可行的解决思路,我给你详细拆解:
方案1:提取公共代码到独立模块(最推荐)
这是最规范、最可持续的做法:把两个模块互相调用的代码抽离到一个新的Common模块,让Server和Game都依赖这个公共模块,从根源上避免循环依赖。
操作步骤:
- 在Parent项目下新建
Common模块,结构和Server/Game保持一致:Parent ├── ... └── Common ├── src │ ├── main │ │ └── [你的公共类/接口] │ └── test │ └── [公共类的测试代码] └── build.gradle - 修改根目录的
settings.gradle,添加新模块的引用:rootProject.name = 'Parent' include ':Server' include ':Game' include ':Common' // 新增这一行 - 配置Server模块的
build.gradle,添加对Common的依赖:dependencies { implementation project(':Common') // 保留你原来的其他依赖 } - 同样配置Game模块的
build.gradle:dependencies { implementation project(':Common') // 保留你原来的其他依赖 } - 把原来Server和Game中互相调用的代码迁移到Common模块里,之后两个模块只需要调用Common里的代码即可。
方案2:使用编译时/运行时分离依赖(仅临时应急,不推荐)
如果实在不想调整项目结构,可以用compileOnly和runtimeOnly来绕开循环依赖检查,但这种方式会让代码结构变得脆弱,容易出现运行时类找不到的问题,所以只适合临时场景。
配置方式:
- 在Server的
build.gradle中添加:dependencies { // 编译时依赖Game,让代码能通过编译 compileOnly project(':Game') // 其他原有依赖 } - 在Game的
build.gradle中添加:dependencies { // 编译时依赖Server,让代码能通过编译 compileOnly project(':Server') // 其他原有依赖 }
⚠️ 注意:这种方式下,你只能在编译时引用对方模块的代码,但运行时需要确保对方的类已经被加载,很容易触发ClassNotFoundException,所以强烈不推荐长期使用。
内容的提问来源于stack exchange,提问作者Suraj Kumar
相关产品推荐
相关产品推荐

