developmentOnly 选错变体
Boot 4.0.8、4.1.1 的开发依赖配置缺少运行时属性,可能导致 Gradle 选错变体或歧义。补齐已有配置属性,同时保持开发依赖的打包排除规则。
Spring Boot 项目打包时,developmentOnly 或 testAndDevelopmentOnly 的依赖解析出现变体歧义,或者选到不合适的产物。若同一依赖在 runtimeClasspath 中能正常解析,先比较两个配置的属性,不要立即把开发依赖移到 implementation。
继承依赖不继承属性
核对的 Boot 4.0.8、4.1.1 Gradle 插件创建这两个配置时,没有复制 runtimeClasspath 的属性。Gradle 的 extendsFrom 继承依赖等信息,但不继承属性;缺少运行时用途、产物形式等需求后,变体选择可能没有足够信息。
Boot 打包逻辑会计算开发依赖与生产依赖的文件差集,因此问题可能出现在 bootJar 阶段,而不只是手工查询配置时。先从错误中确认真正失败的配置名、所请求的属性和生产者提供的变体。
如果失败发生在其他配置,或者依赖根本没有匹配当前 JVM 的变体,不能用这里的属性补齐掩盖真实不兼容。
补齐已有配置的需求
受影响项目可以按已提交的插件修复方向,让这两个配置采用项目实际的运行时属性。以下为 Groovy build.gradle 片段,放在 Java 和 Boot 插件已应用、所需运行时属性已设置、配置尚未开始解析的位置:
def runtime = configurations.named('runtimeClasspath')
['developmentOnly', 'testAndDevelopmentOnly'].each { configName ->
configurations.named(configName) {
canBeConsumed = false
attributes {
def source = runtime.get().attributes
source.keySet().each { key ->
attributeProvider(key, providers.provider {
source.getAttribute(key)
})
}
}
}
}
这里复制的是项目的属性,不硬编码一个 Java 版本或产物类型。键集合在配置这段逻辑时取得;项目稍后才新增自定义属性时,需要调整配置顺序,使新键也被包含。已经解析的配置不能再按这段方法修改。
canBeConsumed = false 对应普通开发依赖配置的用途。若项目另外把这两个名称作为对外发布的自定义配置,先理清这份额外约定,不能直接改变它的消费行为。
看产物是否仍按预期排除
重新检查失败配置选到的变体,再运行原打包入口,确认开发专用依赖仍按原设计排除,生产和测试所需依赖没有丢失。把依赖移进 implementation 虽可能避开一处解析,却会改变打包内容,不是等价修复。
这个修复已提交,列入 4.0.9 计划;截至 2026 年 10 月 14 日,该正式版本还未发布。后续采用包含修复的兼容插件时,可撤掉重复的本地补丁,并对照相同的变体与打包结果验收。


