Kotlin Gradle DSL多模块子项目无法作为依赖被消费者使用
问题原因
- 你在
error-handling-lib-ktor模块使用api(project(":error-handling-common"))声明依赖,仅能保证当前模块在本地编译时能访问common模块的类,不会自动让maven-publish插件把common模块作为可传递依赖写入发布构件的POM元数据。缺少配置的情况下,生成的POM要么没有common模块的依赖声明,要么会把它错误标记为runtime作用域,下游拉取依赖时不会自动引入common,自然无法访问common中的类。 error-handling-common模块内的第三方依赖全部使用implementation声明,如果common的公共类、方法签名中用到了这些依赖(如ktor的类),就算common被传递到下游,这些依赖也不会暴露,下游运行时会抛出类找不到异常。- 你标注common模块需要编译为JS/JVM双目标,但当前common只应用了
kotlin("jvm")插件,属于纯JVM模块,这个配置不影响当前JVM场景发布,后续做多平台适配时再调整即可。
解决方法
- 给
error-handling-common模块添加id("maven-publish")插件,公共模块需要作为独立构件发布到仓库,不能仅作为本地项目依赖存在。 - 在
error-handling-lib-ktor模块中配置发布规则,正确映射依赖作用域,保证api声明的依赖被标记为可传递的编译期依赖,配置代码如下:
publishing { publications { register<MavenPublication>("mavenJava") { from(components["java"]) pom { withXml { val depsNode = asNode().appendNode("dependencies") // api依赖标记为compile作用域,支持向下游传递 configurations.api.get().allDependencies.forEach { dep -> val depNode = depsNode.appendNode("dependency") depNode.appendNode("groupId", dep.group) depNode.appendNode("artifactId", dep.name) depNode.appendNode("version", dep.version) depNode.appendNode("scope", "compile") } // implementation依赖标记为runtime作用域,不向下游传递 configurations.implementation.get().allDependencies.forEach { dep -> if (dep.group != null && dep.version != null) { val depNode = depsNode.appendNode("dependency") depNode.appendNode("groupId", dep.group) depNode.appendNode("artifactId", dep.name) depNode.appendNode("version", dep.version) depNode.appendNode("scope", "runtime") } } } } } } // 仓库地址保持原有artifactregistry配置即可 }
- 调整
error-handling-common模块的依赖规则:所有出现在公共API签名中的第三方依赖,从implementation改为api声明。比如当前引入的ktor相关依赖,如果在common的公共类中被引用,就用api声明,保证这些依赖能随common一起传递给下游,避免类缺失错误。 - 发布完成后先校验仓库中
error-handling-lib-ktor对应的POM文件,确认存在error-handling-common的依赖项且scope为compile,此时下游仅需引入error-handling-lib-ktor依赖,即可直接访问common模块的所有公共类。
内容的提问来源于stack exchange,提问作者Sniady
相关产品推荐
相关产品推荐

