简介:Gradle 8.0.2 是 Gradle 8.0 的第二个补丁版本,面向使用 Gradle 构建 Java、Scala、Kotlin 项目的开发者,尤其适合需要修复 8.0 系列已知问题的团队。该版本集中修复了元空间耗尽、无显式工具链的 Java/Scala 构建失败、自定义编译器支持被静默放弃、InstrumentingTransformer 生成类文件不一致导致远程构建缓存未命中、已解析配置扩展失效、配置缓存状态更新、插件管理规范状态显示异常、Scala 插件与工具链集成文档缺失、字符串 isBlank 报错等十余项问题,并补充了相关文档说明。压缩包共 11587 个文件,以 java 源码、html 文档、kt 脚本、jar 包为主,另含 png 图示、js/css 样式及少量 groovy、zip、pdf 等,整体约 159.92MB,目录结构完整,便于查阅源码与离线文档。已有 742 人学习下载,适合需要稳定构建环境或排查 8.0 升级问题的开发者参考。
1. 一个 200MB 的压缩包,卡住了整条构建链
上周帮同事配环境,Android 工程一跑./gradlew assembleDebug就卡在Downloading https://services.gradle.org/distributions/gradle-8.0.2-all.zip,进度条半小时不动。这不是网络玄学,是 Gradle Wrapper 默认从官方分发地址拉整包,而-all版本比-bin多出源码和文档,体积接近 200MB,弱网环境下失败率极高。gradle-8.0.2-all.zip就是官方发布的完整发行包,解压即用,包含bin、docs、src和lib,适合需要离线构建、想看 Gradle 内部实现、或者被 Wrapper 下载反复折磨的开发者。这篇笔记按「包是什么 → 怎么装 → 怎么让 Wrapper 认它 → 坑在哪」走一遍,新手能照着复现,熟手能直接抄参数。
2. 拆开 gradle-8.0.2-all.zip:目录结构与版本选型
2.1 all 和 bin 到底差在哪
很多人下载时随手点第一个链接,结果拿到的是-bin,后面想看源码发现src目录不存在。先把两个发行版的差异摆清楚,选型就不会反复。
| 对比项 | gradle-8.0.2-bin.zip | gradle-8.0.2-all.zip |
|---|---|---|
| 体积 | 约 100MB | 约 200MB |
包含bin/启动脚本 | 是 | 是 |
包含lib/依赖 jar | 是 | 是 |
包含docs/离线文档 | 否 | 是 |
包含src/源码 | 否 | 是 |
| 适用场景 | CI 缓存、纯构建 | 本地开发、源码调试、离线查阅 |
-all多出来的src是 Gradle 自身用 Groovy/Kotlin 写的源码,排查插件行为、读DefaultTask实现时直接翻本地文件比在线搜快得多。CI 环境如果只跑构建,-bin更省缓存空间;但本地开发机我一般直接上-all,省得后面为了看一段源码再下一次。
2.2 解压后的目录长什么样
拿到 zip 后先别急着配环境变量,解压看一眼结构,后面配GRADLE_HOME才不会指错层级。
# 解压到统一目录,注意解压后会自动生成 gradle-8.0.2 这一层 unzip gradle-8.0.2-all.zip -d /opt/gradle # 确认目录层级:GRADLE_HOME 应指向 gradle-8.0.2,而不是 /opt/gradle ls /opt/gradle/gradle-8.0.2 # 预期输出:bin docs init.d lib LICENSE NOTICE README这里有个高频翻车点:unzip -d /opt/gradle之后实际路径是/opt/gradle/gradle-8.0.2,如果环境变量写成/opt/gradle,执行gradle -v会报Could not find or load main class org.gradle.launcher.GradleMain。逻辑说明:GRADLE_HOME必须精确指向含bin/的那一层,bin/gradle脚本内部会基于自身位置反推lib,层级错一位就找不到主类。参数上-d指定的是父目录,不是最终目录,这一点和tar -C的行为一致,但很多人按tar的直觉写错。
2.3 版本号里的 8.0.2 意味着什么
Gradle 版本号是主版本.次版本.补丁,8.0.2 属于 8.0 系列的补丁版,修的是 8.0.0/8.0.1 的回归问题,API 层面与 8.0 兼容。选它而不是 8.1+ 的常见理由是:工程里 AGP(Android Gradle Plugin)版本锁死了兼容区间,AGP 8.0 要求 Gradle 8.0 及以上,但部分老插件在 8.1 的配置缓存上有行为变化。所以「补丁版 + 匹配 AGP」是稳妥组合,不要盲目追最新。判断方法很简单,看工程根目录gradle/wrapper/gradle-wrapper.properties里的distributionUrl,它写的就是这个工程期望的版本,下载对应包即可,别自己升。
3. 让 Wrapper 认本地包:三种落地方式与参数
3.1 方式一:手动解压 + 环境变量(最直接)
适合完全离线、或者就想全局用一个 Gradle 的场景。步骤不复杂,但每一步都有参数讲究。
# 1) 解压到固定位置 unzip gradle-8.0.2-all.zip -d /opt/gradle # 2) 写入环境变量(Linux/macOS,追加到 ~/.bashrc 或 ~/.zshrc) export GRADLE_HOME=/opt/gradle/gradle-8.0.2 export PATH=$GRADLE_HOME/bin:$PATH # 3) 生效并验证 source ~/.bashrc gradle -vgradle -v正常会输出 Gradle 版本、Kotlin 版本、JVM 版本和 OS 信息。逻辑说明:PATH里把$GRADLE_HOME/bin放前面,避免系统里已有的旧版gradle抢先命中;GRADLE_HOME本身不是 Gradle 强制读取的变量,但很多脚本和 IDE 会读它,配上有好处。参数上注意export只对当前 shell 及子进程生效,写进 rc 文件才能持久。Windows 下对应的是在「系统环境变量」里新建GRADLE_HOME,再把%GRADLE_HOME%\bin加进Path,改完必须重开终端,老终端不会刷新环境块。
提示:
gradle -v输出的 JVM 版本如果和工程要求不符,先查JAVA_HOME,Gradle 8.0.2 要求 JDK 8 及以上,跑 AGP 8.0 则实际需要 JDK 17,版本对不上会在配置阶段直接抛Unsupported class file major version。
3.2 方式二:改 distributionUrl 指向本地文件(推荐给团队)
手动配环境变量只解决「命令行能用」,./gradlew仍然会去官方地址下载。真正让 Wrapper 认本地包,是改gradle-wrapper.properties。
# gradle/wrapper/gradle-wrapper.properties # 原值类似: # distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip # 改为本地 file 协议,注意 Windows 下路径写法不同 distributionUrl=file\:/opt/gradle/gradle-8.0.2-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists逻辑说明:distributionUrl支持file:协议,Wrapper 会直接读本地 zip 并解压到~/.gradle/wrapper/dists下,不再走网络。参数上distributionBase和zipStoreBase保持默认GRADLE_USER_HOME即可,改它们会让缓存散落各处,团队协作时反而难排查。注意file:后面是冒号加斜杠,Windows 写成file\:/D\:/tools/gradle-8.0.2-all.zip,反斜杠要转义,这是 properties 文件的语法要求,不是笔误。团队里把这行改成内网共享路径,所有人./gradlew都走本地,比每人配一遍环境变量省事。
3.3 方式三:预置到 GRADLE_USER_HOME 缓存目录(CI 友好)
CI 环境不方便改工程文件,也不想每次解压,可以直接把包塞进 Wrapper 的缓存布局里。Wrapper 的缓存路径有固定规则:~/.gradle/wrapper/dists/gradle-8.0.2-all/<hash>/,<hash>是distributionUrl的 MD5 编码,不同 URL 算出的 hash 不同,所以这招要配合固定 URL 使用。
# 先让 Wrapper 跑一次(哪怕失败),生成 hash 目录 ./gradlew --version || true # 找到生成的 hash 目录 ls ~/.gradle/wrapper/dists/gradle-8.0.2-all/ # 输出类似:7x9k2m...(一串 32 位 hash) # 把本地 zip 放进去,并解压出 gradle-8.0.2 目录 HASH_DIR=$(ls -d ~/.gradle/wrapper/dists/gradle-8.0.2-all/*/ | head -1) cp gradle-8.0.2-all.zip "$HASH_DIR" unzip -q gradle-8.0.2-all.zip -d "$HASH_DIR" # 关键:创建一个 .ok 标记文件,Wrapper 见到它才认为下载完成 touch "$HASH_DIR/gradle-8.0.2-all.zip.ok"逻辑说明:Wrapper 判断「已下载」的依据不是 zip 存在,而是同目录下存在<zip名>.ok标记文件,缺了它照样重新下载,这是最容易漏的一步。参数上head -1防止有多个 hash 目录时取错,实际环境如果只有一个工程,直接写死路径更稳。CI 里把这套逻辑写进镜像构建阶段,后续构建全程离线,比每次配代理稳定得多。
4. 避坑与排查:五条血泪记录
4.1 现象:gradle -v报找不到主类
原因:GRADLE_HOME指到了解压的父目录,或者PATH里混进了旧版 Gradle 的bin。解决:echo $GRADLE_HOME确认末尾是gradle-8.0.2,which -a gradle看是否有多个命中,把旧的从PATH里摘掉。改完重开终端,别在当前 shell 里反复source试。
4.2 现象:Wrapper 一直卡在 Downloading,改成本地 file 后仍下载
原因:distributionUrl改了但没清缓存,Wrapper 发现缓存目录里已有半截下载或旧 hash,仍按旧逻辑走。解决:删掉~/.gradle/wrapper/dists/gradle-8.0.2-all/整个目录再跑,让它按新 URL 重新算 hash。这一步没有后悔药,缓存不清等于白改。
4.3 现象:解压后bin/gradle无执行权限
原因:从某些渠道拿到的 zip 在传输中丢了权限位,或者用图形工具解压时没保留。解决:chmod +x /opt/gradle/gradle-8.0.2/bin/gradle,顺手把bin下所有脚本都加上。判断方法:ls -l bin/gradle看有没有x,没有就是这个问题。
4.4 现象:构建报Unsupported class file major version 61
原因:JDK 版本和 Gradle/AGP 不匹配,61 对应 JDK 17,说明工程要求 17 但当前JAVA_HOME指向了更低版本,或者反过来 Gradle 8.0.2 跑在过新的 JDK 上。解决:java -version和gradle -v里的 JVM 对照,AGP 8.0 场景统一到 JDK 17,改JAVA_HOME后重开终端。
4.5 现象:团队里有人能跑有人不能,报 zip 损坏
原因:共享路径上的 zip 被不完整拷贝,或者file:路径里有空格没转义。解决:先unzip -t gradle-8.0.2-all.zip校验完整性,路径含空格时在 properties 里用%20编码。这类问题排查起来像黑匣子,最省事的做法是统一放一个无空格、无中文的路径。
5. 进阶:用校验和与 init 脚本把版本钉死
下载来源不可控时,光看文件名不够,得校验。官方每个发行版都提供.sha256文件,落地前对一遍,能挡掉大部分半截包和篡改包。
# 计算本地包的 sha256,与官方 .sha256 文件内容比对 sha256sum gradle-8.0.2-all.zip # 官方校验文件通常长这样(此处为格式示意,实际值以官方发布为准) # <64位十六进制> gradle-8.0.2-all.zip逻辑说明:sha256sum输出第一列是摘要,第二列是文件名,和官方文件逐字符比对即可。参数上没有花活,但要注意别用md5sum凑合,校验强度不够。校验通过再解压,能避免「解压到一半报 unexpected end of file」这种浪费时间的翻车。
另一个值得养成的习惯是用init.d脚本统一仓库和缓存配置。gradle-8.0.2-all.zip解压后自带init.d目录,往里放一个init.gradle,所有工程都会自动应用,不用每个项目改一遍。
// /opt/gradle/gradle-8.0.2/init.d/cache.gradle // 统一构建缓存目录,避免每个工程各存一份 gradle.projectsLoaded { rootProject { buildCache { local { directory = new File(gradle.gradleUserHomeDir, 'build-cache') } } } }逻辑说明:projectsLoaded在工程加载后触发,rootProject里配buildCache.local.directory,把缓存集中到GRADLE_USER_HOME/build-cache,多工程切换时命中率明显提升。参数上gradle.gradleUserHomeDir是 Gradle 内置属性,别硬编码绝对路径,换机器就失效。这类 init 脚本适合放团队统一镜像里,新人拉下来就带好配置。
我现在的习惯是:任何一次拿到发行包,先sha256sum对一遍,再unzip -t验完整性,最后才往GRADLE_HOME里放。这三步走完再配 Wrapper,基本不会再被「下载到一半」「解压损坏」「版本对不上」这三类问题反复消耗。希望帮到你。
本文还有配套的精品资源,点击获取