英文:
Gradle: Multi-module project, project does not get transitive dependencies when using "implementation" instead of "compile"
问题
这是项目A的build.gradle文件:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
implementation project(':B')
runtimeOnly project(':B')
}
这是项目B的build.gradle文件:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-simple:1.7.30'
implementation 'org.slf4j:slf4j-api:1.7.30'
}
当我执行
> gradle :A:jar
我得到编译错误,项目A中的slf4j导入找不到,但它是项目B的传递性依赖。如果我将项目B的build.gradle更改为:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-simple:1.7.30'
implementation 'org.slf4j:slf4j-api:1.7.30'
}
在Gradle 6.9中,一切都按预期工作,但我想升级到Gradle 7,“compile”已被弃用。有人有解决方案吗?
英文:
this is build.gradle file of project A:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
implementation project(':B')
runtimeOnly project(':B')
}
and this is the build gradle file of project B:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.slf4j:slf4j-simple:1.7.30'
implementation 'org.slf4j:slf4j-api:1.7.30'
}
When I execute
> gradle :A:jar
I get compilation errors that the imports of slf4j cannot be found in project A but it is a transitive dependency of project B. If I change the build.gradle of project B to:
plugins {
id 'java'
}
group = 'org.example'
repositories {
mavenCentral()
}
dependencies {
compile 'org.slf4j:slf4j-simple:1.7.30'
compile 'org.slf4j:slf4j-api:1.7.30'
}
everythings works as expected in Gradle 6.9 but I want to upgrade to Gradle 7 and "compile" is deprecated. Does someone has a solution?
答案1
得分: 1
Yes, that is exactly the point of an implementation dependency.
这确实是实现依赖项的目的。
It is needed for the implementation of the logic, but not for its API.
它用于逻辑的实现,但不用于其API。
Thus it does not leak into the compile classpath of downstream projects and by that makes compilation faster and increases chance for cache-hits if build cache is used.
因此,它不会泄漏到下游项目的编译类路径中,从而加快编译速度,并增加了如果使用构建缓存,则缓存命中的机会。
If you use slf4j
classes in the API of B (parameters, return types, super classes, ...), then apply the java-library
plugin (makes sense anyway if it is a library) and use the api
configuration instead.
如果您在B的API中使用slf4j
类(参数,返回类型,超类等),则应用java-library
插件(如果是库,这是有意义的),并使用api
配置代替。
If you just want to use slf4j
in A, then just also declare it as implementation
dependency there.
如果您只想在A中使用slf4j
,那么只需在那里将其声明为implementation
依赖项。
Read https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation for more information.
阅读https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation获取更多信息。
英文:
Yes, that is exactly the point of an implementation dependency.
It is needed for the implementation of the logic, but not for its API.
Thus it does not leak into the compile classpath of downstream projects and by that makes compilation faster and increases chance for cache-hits if build cache is used.
If you use slf4j
classes in the API of B (parameters, return types, super classes, ...), then apply the java-library
plugin (makes sense anyway if it is a library) and use the api
configuration instead.
If you just want to use slf4j
in A, then just also declare it as implementation
dependency there.
Read https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation for more information.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论