Gradle子项目单独构建无法引用buildSrc约定插件的问题求助
问题场景
基于预编译脚本类型创建了约定插件,从项目根目录执行./gradlew clean build时构建正常,但进入使用该插件的prj1子项目单独执行构建时,出现如下报错:
Plugin [id: 'java-convention'] was not found in any of the following sources:
- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)
项目结构如下:
buildSrc/ build.gradle src/main/groovy/java-convention.gradle prj1/ build.gradle build.gradle settings.gradle
相关文件内容:
- 根目录
build.gradle:
plugins { id 'java-convention' }
- 根目录
settings.gradle:
include('prj1')
buildSrc/build.gradle:
plugins { id 'groovy-gradle-plugin' }
buildSrc/src/main/groovy/java-convention.gradle:
plugins { id 'java' } java { sourceCompatibility = JavaVersion.VERSION_21 }
prj1/build.gradle:
plugins { id 'java-convention' } group = 'com.example' version = '0.0.1-SNAPSHOT'
尝试过在prj1/settings.gradle中添加includeBuild('../buildSrc'),但报错提示buildSrc是保留名称,无法在includeBuild()中引用。
问题原因
buildSrc是Gradle为根项目设计的特殊目录,只有在根项目上下文中执行构建时,Gradle才会自动构建buildSrc并将生成的插件Jar加入类路径。当直接进入子项目prj1单独运行Gradle命令时,Gradle会将当前目录视为项目根目录,无法识别上层的buildSrc,因此找不到自定义插件。
解决方案
方案1:始终从根目录执行构建(推荐)
不需要修改任何配置,直接在项目根目录执行针对prj1的构建命令即可:
./gradlew prj1:clean prj1:build
方案2:在子项目目录指定根项目上下文执行
如果必须在prj1目录下执行命令,可以通过--project-dir参数指定根目录路径:
./gradlew --project-dir ../ clean build
这样Gradle会以上层根目录为项目上下文,自动处理buildSrc的构建和插件加载。
方案3:将buildSrc转为复合构建(不推荐)
如果需要频繁在子项目目录执行命令,可以将buildSrc重命名为非保留名称(比如gradle-plugins),然后在根目录的settings.gradle中添加:
includeBuild('gradle-plugins')
这种方式会将插件项目转为复合构建的一部分,无论从哪个目录执行(只要能找到根settings.gradle)都能加载插件,但会增加项目复杂度,仅在必要时使用。
内容的提问来源于stack exchange,提问作者user2337270

