Gradle 'Implementation' 当项目没有自己的 类 时,依赖项是运行时范围的
Gradle 'Implementation' Dependencies Are Runtime-Scoped When Project Has No Classes Of Its Own
我有一个 Gradle 自定义 Spring 引导启动程序的多项目构建。按照 Spring Boot Starter 约定,我的 类 都在一个 'autoconfiguration' 项目中,我有一个单独的 'starter' 项目,它只引入使用自动配置所需的依赖项。
多项目构建生成 2 个不可运行的 jar,1 个用于自动配置子项目,1 个用于启动子项目。我使用这个启动器的新项目拉入了启动器 jar,但是当我去使用来自传递依赖项的 类 时,我的项目无法在类路径上的任何地方找到它们。
当我深入研究 starter jar 时,我发现它定义的所有依赖项都是 RUNTIME 范围的,这可以解释问题。我可以 'fix' 通过将启动器中的所有依赖项设置为 'compile' 而不是 'implementation' 来解决问题,但我的理解是 'compile' 即将过时,并且 'implementation' 无论如何,依赖项应该是编译范围的。有人可以告诉我可能需要什么额外的配置来将入门依赖项定义为 'implementation' 而它们在生成的 jar 中不被限定为 'runtime' 吗?
我的starter/autoconfigure多项目rootgradle文件:
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
}
我的 starter 子项目的 构建文件:
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'
}
如果我将上面的 'implementation' 行更改为 'compile' 行,那么生成的 pom 文件将停止使这 4 个依赖项成为 'runtime' 范围,而是正确地将它们范围限定为 'compile'。作为旁注,'compile project' 行工作得很好,只是 'implementation' 行似乎不像我在项目没有 类 时期望的那样工作它自己的。
我的新项目对我的初学者的依赖:
dependencies {
implementation('com.myproj:myproj-spring-boot-starter:1.0.0')
// other dependencies
}
implementation
在 Gradle 项目中定义的依赖项仅可传递给该项目的 runtimeClasspath
使用者,这是设计使然。
如果您有一个没有代码但只定义依赖项的项目,请考虑为其使用 java-platform
插件,它允许您指定约束和可选的依赖项。
否则,如果您希望项目在编译时向消费者公开其依赖项,则应使用 api
配置来声明它们,而不是 compile
,后者确实即将退出。
有关详细信息,请参阅 documentation。
我有一个 Gradle 自定义 Spring 引导启动程序的多项目构建。按照 Spring Boot Starter 约定,我的 类 都在一个 'autoconfiguration' 项目中,我有一个单独的 'starter' 项目,它只引入使用自动配置所需的依赖项。
多项目构建生成 2 个不可运行的 jar,1 个用于自动配置子项目,1 个用于启动子项目。我使用这个启动器的新项目拉入了启动器 jar,但是当我去使用来自传递依赖项的 类 时,我的项目无法在类路径上的任何地方找到它们。
当我深入研究 starter jar 时,我发现它定义的所有依赖项都是 RUNTIME 范围的,这可以解释问题。我可以 'fix' 通过将启动器中的所有依赖项设置为 'compile' 而不是 'implementation' 来解决问题,但我的理解是 'compile' 即将过时,并且 'implementation' 无论如何,依赖项应该是编译范围的。有人可以告诉我可能需要什么额外的配置来将入门依赖项定义为 'implementation' 而它们在生成的 jar 中不被限定为 'runtime' 吗?
我的starter/autoconfigure多项目rootgradle文件:
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
}
我的 starter 子项目的 构建文件:
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'
}
如果我将上面的 'implementation' 行更改为 'compile' 行,那么生成的 pom 文件将停止使这 4 个依赖项成为 'runtime' 范围,而是正确地将它们范围限定为 'compile'。作为旁注,'compile project' 行工作得很好,只是 'implementation' 行似乎不像我在项目没有 类 时期望的那样工作它自己的。
我的新项目对我的初学者的依赖:
dependencies {
implementation('com.myproj:myproj-spring-boot-starter:1.0.0')
// other dependencies
}
implementation
在 Gradle 项目中定义的依赖项仅可传递给该项目的 runtimeClasspath
使用者,这是设计使然。
如果您有一个没有代码但只定义依赖项的项目,请考虑为其使用 java-platform
插件,它允许您指定约束和可选的依赖项。
否则,如果您希望项目在编译时向消费者公开其依赖项,则应使用 api
配置来声明它们,而不是 compile
,后者确实即将退出。
有关详细信息,请参阅 documentation。