现在AI这么强,很难有值得去写的博客了,这篇技术含量不高,但是排查这个问题花了今天一天,所以还是写一下吧,就当写日记一样。
背景
有个多年前做着玩的项目,太久没维护了,正好这两天把target版本升到36,gradle从7升级到8,很顺利,但是在服务器打包总是不能正常编译。为什么非要在服务器打包,这个说来话长,这里略过。打包脚本是这样的:
cd ~/project
rm -rf browser
# git clone git@github.com:【马赛克】/browser.git
git clone /home/git/browser.git
cp -r browser_mk/* browser/
export JAVA_HOME=/home/【马赛克】/android-studio/jbr
cd browser
./gradlew init clean bundleRelease --info --stacktrace
/home/【马赛克】/android-studio/jbr/bin/java -jar ~/Downloads/bundletool-all-1.14.0.jar build-apks --bundle='/home/【马赛克】/project/browser/app/build/outputs/bundle/release/app-release.aab' --output=~/project/app.apks
这套脚本用了挺久了,就是没想到这里有问题。
流水账
先是遇到报错:
// 【此处忽略】
Starting Build
Settings evaluated using settings file.
Projects loaded. Root project using build file '/home/【马赛克】/project/browser/build.gradle'.
Included projects: [root project 'browser']
> Configure project :
Evaluating root project 'browser' using build file '/home/【马赛克】/project/browser/build.gradle'.
Resource missing. [HTTP HEAD: https://repo.maven.apache.org/maven2/com/android/application/com.android.application.gradle.plugin/8.13.2/com.android.application.gradle.plugin-8.13.2.pom]
Resolved plugin [id: 'com.android.application', version: '8.13.2', apply: false]
FAILURE: Build failed with an exception.
* Where:
Build file '/home/【马赛克】/project/browser/build.gradle' line: 16
* What went wrong:
Plugin [id: 'com.android.application', version: '8.13.2', apply: false] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Included Builds (No included builds contain this plugin)
- Plugin Repositories (could not resolve plugin artifact 'com.android.application:com.android.application.gradle.plugin:8.13.2')
Searched in the following repositories:
Gradle Central Plugin Repository
* Try:
> Run with --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
* Exception is:
org.gradle.api.plugins.UnknownPluginException: Plugin [id: 'com.android.application', version: '8.13.2', apply: false] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Included Builds (No included builds contain this plugin)
- Plugin Repositories (could not resolve plugin artifact 'com.android.application:com.android.application.gradle.plugin:8.13.2')
Searched in the following repositories:
Gradle Central Plugin Repository
at org.gradle.plugin.use.resolve.internal.PluginResolutionResult.getFound(PluginResolutionResult.java:112)
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.resolvePluginRequest(DefaultPluginRequestApplicator.java:197)
at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:101)
at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:123)
at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:68)
【剩余内容忽略】
上面报错主要在于com.android.application:com.android.application.gradle.plugin:8.13.2这个没找到。
step 1
最开始配置的版本是8.13.0,服务器打包提示找不到,我先是顺手把版本号改一下看看。
step 2
然后观察到日志有一个repo.maven.apache.org的pom文件下载链接,浏览器打开,是404,但为什么gradle只尝试去这个域名找呢,我明明是配置了其他仓库的:
pluginManagement {
repositories {
google()
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "browser"
include ':app'
Google了一下报错,几个stackoverflow、gradle讨论都在说是网络不通畅,配置了代理等网络问题。在服务器终端试了一下curl https://dl.google.com/dl/android/maven2/com/android/application/com.android.application.gradle.plugin/8.13.2/com.android.application.gradle.plugin-8.13.2.pom能正常输出结果,google仓库是绝对存在这个版本,并且网络环境正常的。
step 3
Google的AI说让我执行gradlew build --refresh-dependencies,这个命令的执行消耗了一些时间,最终还是没有效果。
step 4
可能是比较自信,平时遇到玄学问题一般都是先怀疑是不是MIUI、OriginUI等等它们的问题,往往还真是平台的bug,所以这次依然是怀疑gradle是不是有什么bug?然后直接升级gradle版本8.13升到8.14.4。
这又涉及到服务器下载gradle好慢,把all换成bin。
下载好了,依然不行,难道是服务器网络环境什么时候也出了问题,并且curl能访问不代表gradle能访问?
step 5
于是配置阿里云镜像再次尝试。有人确实这样解决了这个问题。但我这里依然不行。
step 6
服务器环境各种清理,包括清理~/.gradle/目录,重新下载最新版AndroidStudio,用AS目录里的jbr路径作为JAVA_HOME等。
依然不行。
step 7
这时候google搜到一篇文章,一位网友遇到和我一样的报错,有人回复说"为什么我的项目settings.gradle里面有includeGroupByRegex而你的没有",于是我照着他的,把google()换成了:
google{
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
看起来很对,因为com.android.application确实能被刚添加的内容匹配到,看起来好像关联很大。但还是没效果.
step 8
然后GLM5又给了我几段,让这个com.android开头的插件不要走mavenCentral,mavenCentral换成了:
mavenCentral {
content {
excludeGroupByRegex("com\\.android.*") // 不去这里找 Android 相关
excludeGroupByRegex("androidx.*")
}
}
和AI讨论几个来回还是不行
step 9
我想着干脆让AI分析下gradle源码,看看为什么都改成这样了,报错看来依然会去mavenCentral找相应的插件,我到底哪里疏忽了。
GLM5陷入循环了,不断地重复,总是又想到了一个之前想到过的"关键问题":
让我再想想其他可能的原因...
实际上,让我再仔细看看错误信息。错误信息显示的是从 Maven Central 获取插件,而不是从 Google 仓库。
这意味着 Google 仓库可能被跳过了。
让我再检查一下为什么 Google 仓库被跳过了...
啊!我想到了一个关键问题!
...
step 10
我又在想,难道服务器这边改到了什么,导致忽略了settings.gradle文件吗?于是里面故意加一行错误的代码includeGroupByRegex(null),这样,本地运行确实会报错,提示参数不能是null,而服务器那边还是和之前一样的错误。会是有缓存吗?我确保杀掉了所有gradle相关的进程,再次运行,报错内容仍然和以前一样,看来是gradle根本没有读到settings.gradle文件。
AI给了./gradlew properties命令,说可以看到项目到底在把哪个文件当作settings.gradle去用。然而,执行了这个命令之后,服务器却和我本地一样报出"参数不能是null"的错误了。
step 11
另一边,我继续Google,在Google Issue上看到一个情况和我类似的网友发帖,他说他那边网络不好,不得不配置阿里云镜像,也是一个电脑正常,另一个电脑无法打包,情况和我类似,但Google工作人员的回复是劝他去找Gradle官方,因为这不像是AGP的问题。
我在想,AS对gradle版本有限制,会不会是打包命令(比如调用gradlew传入的参数)有什么变化呢。这才想着把打包脚本里的参数复制到本地,终于本地也出现了报错,这回确认了是打包命令的问题,而"不同电脑"是个干扰。
它说,init任务会导致settings.gradle被忽略。(我对它轻易给出的结论保持怀疑,但现在问题已解决,暂时不该去钻牛角尖了)。
就这样,误打误撞地解决了,是init任务的原因,直接删了它就完事。
总结
这个打包命令是2022年底在前前公司学到的,一直用着,没细看,没去思考里面的init在做什么。很难想到问题出自这里。估计前前同事们也踩到这个坑了。
如果遇到上文的报错,检查一下打包命令是不是有一个init任务。