spring-boot - 当项目没有自己的类时,Gradle 'Implementation' 依赖项是运行时范围的

标签 spring-boot gradle dependency-management spring-boot-starter

我已经为自定义 Spring Boot Starter 构建了 Gradle 多项目。按照 Spring Boot Starter 约定,我的类全部位于“自动配置”项目中,并且我有一个单独的“启动”项目,该项目仅引入使用自动配置所需的依赖项。

多项目构建会生成 2 个不可运行的 jar,其中 1 个用于自动配置子项目,1 个用于启动子项目。我使用此启动器的新项目会拉入启动器 jar,但是当我使用来自传递依赖项的类时,我的项目在类路径上的任何位置都找不到它们。

当我深入研究入门 jar 时,我发现它定义的所有依赖项都是运行时范围的,这可以解释问题。我可以通过将启动器中的所有依赖项设置为“编译”而不是“实现”来“修复”问题,但我的理解是“编译”即将消失,并且“实现”依赖项应该在编译范围内反正。有人可以告诉我可能需要什么额外的配置才能将启动器依赖项定义为“实现”而不将它们在生成的 jar 中定义为“运行时”吗?

我的启动/自动配置多项目 gradle 文件:

plugins {
    id 'org.springframework.boot' version '2.1.4.RELEASE' apply false
    id 'io.spring.dependency-management' version '1.0.7.RELEASE' apply false
}

wrapper {
    gradleVersion = '5.2.1'
}

repositories {
    mavenLocal()
    // private repo info omitted
    mavenCentral()
    jcenter()
}

subprojects {
    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'maven-publish'
    apply plugin: 'java-library'

    group = 'com.mystarter'

    repositories {
        mavenLocal()
        // private repo info omitted
        mavenCentral()
        jcenter()
    }

    dependencies {
        annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor"
        annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
    }

    bootJar {
        enabled = false
    }

    jar {
        enabled = true
    }

    javadoc {
        failOnError = false
        options.addStringOption('Xdoclint:none', '-quiet')
    }

    task sourcesJar(type: Jar) {
        from sourceSets.main.allJava
        classifier = 'sources'
    }
    task javadocJar(type: Jar) {
        from javadoc
        classifier = 'javadoc'
    }

    publishing {
        publications {
            myProjStarterArtifacts(MavenPublication) {
                from components.java
                artifact sourcesJar
                artifact javadocJar
            }
        }
        repositories {
            // private repo info omitted
        }
    }

    tasks.build.finalizedBy tasks.publishToMavenLocal
}

我的入门子项目构建文件:

dependencies {
    compile project(':myproj-spring-boot-autoconfig')

    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.security:spring-security-cas'
    implementation 'org.springframework.security:spring-security-ldap'
}

如果我将上面的“实现”行更改为“编译”行,那么生成的 pom 文件将停止使这 4 个依赖项成为“运行时”作用域,而是将它们正确地限定为“编译”作用域。附带说明一下,“编译项目”行工作得很好,只是“实现”行在项目没有自己的类时似乎没有按照我预期的方式工作。

我的新项目对我的启动器的依赖:

dependencies {
    implementation('com.myproj:myproj-spring-boot-starter:1.0.0')
    // other dependencies
}

最佳答案

Gradle 项目中定义的实现依赖项仅可传递给该项目使用者的runtimeClasspath,这是设计使然。

如果您有一个没有代码但仅定义依赖项的项目,请考虑为其使用 java-platform 插件,它允许您指定约束和可选的依赖项。

否则,如果您希望项目在编译时向使用者公开其依赖项,则应使用 api 配置来声明它们,而不是使用 compile 来声明它们,后者确实已启用它的出路。

更多详情,请参阅 documentation .

关于spring-boot - 当项目没有自己的类时,Gradle 'Implementation' 依赖项是运行时范围的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56449729/

相关文章:

spring - Pivotal Cloud Foundry 中的 UI 应用程序

spring-boot - Spring boot 在服务中运行相同配置文件的多个实例

android - 签名库无法加载Gradle

java - Maven的依赖管理中的"Group pressure"

maven - 如何在第谷构建中使用包含第三方包的目录

java - Spring boot 2.0.4.RELEASE 默认情况下 fetch eager

amazon-web-services - 让 SQS 死信队列与 Spring Boot 和 JMS 一起使用

gradle - 在 Gradle 构建中定义 Maven 存储库后,如何将其替换为本地目录?

java - 使用 Gradle 将 Formatter 设置添加到 Eclipse 和 IntelliJ 项目

vim - 如何做一个 Go 项目工作区来使用依赖工具和 Go 工具?