You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Gradle多模块项目中Scala子模块依赖Kotlin子模块构建失败求助

解决Sub2依赖Sub1时的Spring Boot依赖版本缺失问题

看起来你遇到的问题核心在于Sub1作为Spring Boot应用模块的配置方式,导致其依赖无法正确传递给Scala模块Sub2,具体来说有两个关键点:

  1. Sub1使用了org.springframework.boot插件,这个插件默认会生成可执行的bootJar而非普通库jar,并且会修改依赖的传递性,使得下游模块(比如Sub2)无法获取到Spring Boot starter依赖的版本信息。
  2. Sub1的Spring Boot依赖版本由io.spring.dependency-management插件管理,但Sub2没有应用这个插件,也没有引入Spring Boot的BOM,导致Gradle无法解析spring-boot-starter-data-jpa的版本号,从而报错Could not find org.springframework.boot:spring-boot-starter-data-jpa:.

下面提供两种可行的解决方案,你可以根据项目需求选择:

方案一:将Sub1改为Spring Boot库模块(推荐)

如果Sub1只是作为提供核心Map的工具库,不需要作为独立的Spring Boot应用运行,那么应该移除org.springframework.boot插件,改用纯库模式配置:

修改sub1/build.gradle.kts

plugins {
    id("org.jetbrains.kotlin.plugin.spring")
    id("org.jetbrains.kotlin.plugin.jpa")
    id("io.spring.dependency-management") // 保留版本管理插件
    id("org.jlleitschuh.gradle.ktlint")
}

// 引入Spring Boot BOM来统一管理依赖版本
dependencyManagement {
    imports {
        // 确保根项目的gradle.properties中配置了springBootVersion属性,比如springBootVersion=2.7.15
        mavenBom("org.springframework.boot:spring-boot-dependencies:${project.properties["springBootVersion"]}")
    }
}

dependencies {
    // Kotlin基础依赖
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-noarg")
    
    // Spring Boot相关依赖(作为库使用)
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-autoconfigure") // 若需要自动配置能力
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("javax.persistence:javax.persistence-api")
    
    runtimeOnly("mysql:mysql-connector-java")
}

这样修改后,Sub1会生成普通的库jar,所有implementation依赖会正确传递给Sub2,同时依赖版本由Spring Boot BOM统一管理,Sub2不需要额外配置就能解析版本。

方案二:保留Sub1为Spring Boot应用,同时提供可依赖的库jar

如果Sub1需要作为独立Spring Boot应用运行,同时要被Sub2依赖,那么需要配置Sub1生成两个jar:一个可执行的bootJar,一个普通的库jar,并让后者作为对外依赖的artifact:

第一步:修改Sub1的配置

修改sub1/build.gradle.kts

plugins {
    id("org.jetbrains.kotlin.plugin.spring")
    id("org.jetbrains.kotlin.plugin.jpa")
    id("org.springframework.boot")
    id("io.spring.dependency-management")
    id("org.jlleitschuh.gradle.ktlint")
}

// 启用普通jar任务,并设置为主要依赖 artifact
tasks.jar {
    enabled = true
    archiveClassifier.set("") // 移除默认的classifier,让这个jar成为默认产物
}

// 给可执行jar添加classifier,避免和普通jar冲突
tasks.bootJar {
    archiveClassifier.set("boot")
}

dependencies {
    // 原有的依赖保持不变
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("org.jetbrains.kotlin:kotlin-noarg")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("javax.persistence:javax.persistence-api")
    runtimeOnly("mysql:mysql-connector-java")
}

第二步:修改Sub2的配置

Sub2需要引入Spring Boot的BOM来解析依赖版本,所以添加io.spring.dependency-management插件并配置BOM:

plugins {
    id("com.github.johnrengelman.shadow")
    id("application")
    id("scala")
    id("com.github.maiflai.scalatest")
    id("io.spring.dependency-management") // 添加版本管理插件
}

// 引入Spring Boot BOM
dependencyManagement {
    imports {
        mavenBom("org.springframework.boot:spring-boot-dependencies:${project.properties["springBootVersion"]}")
    }
}

dependencies {
    implementation(project(":sub1"))
    implementation("org.scala-lang:scala-library:2.12.11")
    testImplementation("org.scalatest:scalatest_2.12:3.2.3")
    testImplementation("org.scalatestplus:junit-4-13_2.12:3.2.3.0")
    testRuntimeOnly("com.vladsch.flexmark:flexmark-all:0.35.10")
}

// 其余配置保持不变
application {
    mainClass.set("my.application.path")
}

tasks.withType<ScalaCompile>().configureEach {
    scalaCompileOptions.additionalParameters = listOf("-feature")
}

tasks.withType<JavaCompile>().configureEach {
    options.encoding = "UTF-8"
}

最后,别忘了在根项目的gradle.properties中添加Spring Boot版本配置,比如:

springBootVersion=2.7.15
kotlinVersion=1.6.21

这样配置后,Sub2就能正确解析Sub1传递过来的Spring Boot依赖版本,构建也就不会报错了。

内容的提问来源于stack exchange,提问作者taegyun kim

火山引擎 最新活动