Gradle compileOnly和runtimeOnly怎么选

阿敏小哥_1166

阿敏小哥_1166

2026-10-28

119人浏览

原创

compileOnly仅用于编译期需类但运行时由宿主提供(如注解、SDK接口),误用于new实例或直接调用会导致NoClassDefFoundError;其安全前提为所有引用均通过反射+兜底逻辑处理。

gradle compileonly和runtimeonly怎么选

compileOnly 什么时候用,又为什么容易崩溃

当你写的模块(比如一个 SDK 或工具库)在编译时需要某个类(比如 javax.annotation.Nullable 或 androidx.annotation.NonNull),但运行时完全不依赖它——或者更关键的是:**这个类由宿主 App 在运行时提供**,才该用 compileOnly。

常见误用是把 compileOnly 当成“轻量版 implementation”,比如给一个网络库加 compileOnly 'com.squareup.okhttp3:okhttp:4.12.0',结果一运行就抛 NoClassDefFoundError。因为 Gradle 根本没打包 OkHttp,而你的代码又直接 new 了 OkHttpClient,这属于编译可见、运行不可见的硬伤。

  • ✅ 正确场景:写一个注解处理器兼容库,依赖 com.google.auto.service:auto-service:1.1.1,但只在编译期生成代码,不参与运行
  • ✅ 正确场景:Android 库中引用 androidx.lifecycle:lifecycle-common:2.7.0 的注解,但生命周期逻辑由 App 自己引入实现
  • ❌ 错误场景:任何你代码里显式调用、new 实例、或反射加载的类,只要没被宿主 App 显式声明为 runtime 依赖,就不能靠 compileOnly

runtimeOnly 基本没人真用,除非你明确控制 classpath

runtimeOnly 表示:编译时看不到这个依赖,但会打进 APK/AAR/JAR 里,留给运行时加载。听起来像“隐藏依赖”,但实际落地极难——因为你无法在编译期引用它的任何类,连 import 都会报错。

这意味着你只能通过反射、SPI、或 ClassLoader.loadClass 动态加载它。而 Android 上 runtimeOnly 打包进 APK 后,ART 运行时默认能加载;但在 Java Web 或 Spring Boot 场景下,如果没手动把它加进 ClassLoader 或 spring.factories,照样找不到类。

  • ⚠️ 它不是“懒加载开关”,而是彻底切断编译期链接能力
  • ⚠️ 它和 apk(已弃用配置)行为一致,Gradle 官方文档里几乎不提使用案例
  • ? 极少数可行场景:插件化框架中,主壳工程预埋一个空接口,插件模块用 runtimeOnly 提供具体实现 JAR,再由壳动态加载

implementation 和 api 才是日常主力,compileOnly/runtimeOnly 是边界特例

绝大多数业务模块、App 模块、甚至普通 Library,都不该优先考虑 compileOnly 或 runtimeOnly。它们的存在意义是解决特定耦合问题,不是通用替代方案。

比如你写一个封装了 Gson 的 JSON 工具类,内部用了 Gson 和 TypeToken,那必须用 implementation 'com.google.code.gson:gson:2.10.1'——哪怕下游模块也想用 Gson,也应该自己声明,而不是靠你“泄露”过去。

  • 用 api 的唯一合理理由:你暴露的 public 方法签名里直接用了该依赖的类型(例如返回 Call,就必须 api 'com.squareup.retrofit2:retrofit:2.9.0')
  • compileOnly 的安全前提:你所有对该依赖的引用都包裹在 try/catch (ClassNotFoundException) 或 Class.forName(...).isPresent() 里,并有 fallback 行为
  • runtimeOnly 的安全前提:你从不 import、不 new、不写泛型约束、不参与编译期类型推导——只靠字符串类名 + 反射活下来

最容易被忽略的点:transitive 和 exclude 的组合影响

compileOnly 和 runtimeOnly 都默认关闭传递依赖(transitive = false)。但如果你手动写了 compileOnly('xxx') { transitive = true },就可能意外带入一堆编译期不需要、运行时又缺失的间接依赖,导致构建成功但运行失败。

反过来,runtimeOnly 如果依赖了一个带 native 库的包(比如 net.java.dev.jna:jna:5.13.0),它虽然打进 APK,但 Android 不支持 JNA 的 so 加载机制,照样会 UnsatisfiedLinkError。

所以选配置之前,先跑一遍 ./gradlew app:dependencies --configuration runtimeOnlyClasspath 或 compileOnlyClasspath,确认实际解析出的依赖树是否符合预期——这才是真正卡住问题的地方。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

gradle gradle依赖管理

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java Maven/Gradle 构建与依赖管理合集
Java Maven/Gradle 构建与依赖管理合集

系统讲解 Java 项目构建工具的使用与进阶配置,涵盖 Maven 的 POM 文件结构、生命周期(clean/compile/package/install/deploy)与插件机制、依赖范围(compile/provided/test/runtime)与传递依赖管理、多模块聚合与继承、私有 Nexus 仓库发布,以及 Gradle 的 Groovy / Kotlin DSL 语法、Task 自定义与增量构建、依赖版本目录(Versi

2026.05.09

389

25

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

20

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

0

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

0

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

120

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

60

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

60

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

60

25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Gradle 9 主版本升级指南
Gradle 9 主版本升级指南

共0课时 | 0人学习

Gradle 安全最佳实践
Gradle 安全最佳实践

共0课时 | 0人学习

Gradle 依赖校验手册
Gradle 依赖校验手册

共0课时 | 0人学习