Gradle Spring依赖管理插件发布库时.module文件缺失依赖管理信息问题
我有一个Spring相关的类库,build.gradle配置如下:
plugins { id 'java-library' id 'maven-publish' id "io.spring.dependency-management" version "1.0.11.RELEASE" } dependencyManagement { imports { mavenBom 'org.springframework.boot:spring-boot-dependencies:2.7.0' } } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' } publishing { // Default maven publish settings }
发布后Gradle会生成.module文件,其他Gradle项目引用该库时会优先使用这个文件而不是pom。但问题是.module里没有写入dependencyManagement的信息,导致引用项目出现依赖解析错误:
Could not determine the dependencies of task ':shadowJar'. > Could not resolve all dependencies for configuration ':runtimeClasspath'. > Could not find org.springframework.boot:spring-boot-starter-data-mongodb:. Required by: project : > project :database > ru.spliterash:spcore-spring-database-mongo:1.0.0-SNAPSHOT:20220714.235637-1
不想通过禁用.module文件来解决,这里提供几个更合理的方案:
方案1:自定义Maven Publication,为.module文件添加Dependency Management信息
通过配置maven-publish插件的publication,手动在module描述符中加入BOM的依赖声明,这样其他项目就能通过.module文件获取到版本管理规则。修改publishing块如下:
publishing { publications { mavenJava(MavenPublication) { from components.java // 生成包含BOM依赖的module描述符 moduleDescriptor { dependencies { // 遍历dependencyManagement中导入的BOM,添加到module的依赖声明里 dependencyManagement.imports.each { bom -> def bomGav = "${bom.group}:${bom.name}:${bom.version}" dependency(bomGav) { scope("import") type("pom") } } } } } } }
这个配置会让生成的.module文件包含BOM的import依赖,其他项目引用时就能通过这个BOM解析spring-boot-starter-data-mongodb的版本。
方案2:升级Spring Dependency Management插件版本
你当前使用的是1.0.11.RELEASE版本,这个版本可能存在.module文件不包含dependencyManagement信息的bug。尝试升级到较新的版本(比如1.1.4或更高),新版本可能已经修复了这个问题:
plugins { // ...其他插件 id "io.spring.dependency-management" version "1.1.4" }
升级后重新发布,检查生成的.module文件是否已经包含了dependencyManagement的相关内容。
方案3:让发布的依赖包含完整版本号
另一种思路是,在发布时让Gradle把依赖的完整坐标(带版本)写入.module文件,而不是依赖consumer端的dependencyManagement。可以通过配置publication使用已解析的依赖:
publishing { publications { mavenJava(MavenPublication) { from components.java // 强制使用已解析的依赖版本,写入到module和pom中 versionMapping { usage('java-api') { fromResolutionOf('runtimeClasspath') } usage('java-runtime') { fromResolutionResult() } } } } }
这样配置后,发布的.module文件里的依赖会带上具体版本号,consumer项目无需依赖BOM就能解析。
验证方法
发布类库后,找到生成的.module文件,检查是否包含以下类似内容(以BOM为例):
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.7.0</version> <type>pom</type> <scope>import</scope> </dependency> <!-- 其他依赖 --> </dependencies>
如果有,说明配置生效,再在引用项目中测试依赖解析是否正常。
内容的提问来源于stack exchange,提问作者Spliterash

