我有一个用于自定义Spring Boot Starter的Gradle多项目构建。遵循Spring Boot Starter约定,我的类都在“自动配置”项目中,并且我有一个单独的“入门”项目,仅引入使用自动配置所需的依赖项。

多项目构建产生2个不可运行的jar,其中1个用于自动配置子项目,一个用于启动子项目。我正在使用该启动程序的新项目插入了启动程序jar,但是当我使用来自传递依赖项的类时,我的项目在类路径的任何位置都找不到它们。

当我进入入门jar时,我发现它定义的所有依赖项都在RUNTIME范围内,这可以解释问题。我可以通过将启动器中的所有依赖项都设置为“编译”而不是“实现”来“解决”问题,但是据我了解,“编译”即将退出,并且“实现”依赖项应在编译范围内进行无论如何。有人可以告诉我,将启动程序依赖项定义为“实现”时,可能需要哪些附加配置,而在生成的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项目中定义的implementation依赖关系仅对于该项目的使用者的runtimeClasspath具有传递性,即是设计使然。

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

否则,如果希望项目在编译时将其依赖项暴露给使用者,则应使用api配置声明它们,而不是确实要退出的compile

有关更多详细信息,请参见documentation

08-05 09:10
查看更多