If I have a build structured like this:
build.gradle:
buildscript {
repositories {
jcenter()
}
}
subprojects {
apply plugin: 'java'
ext.libraries = [
log4j: [
'log4j:log4j:1.2.17'
],
]
repositories {
jcenter()
}
}
settings.gradle:
include 'project1'
include 'project2'
project1/build.gradle:
dependencies {
compile libraries.log4j
}
project2/build.gradle:
dependencies {
compile project(':project1')
}
project2/src/main/java/org/example/Test.java:
import org.apache.log4j.Logger;
public class Test {
public static void main(String[] args) {
org.apache.log4j.Logger.getLogger(Test.class).error("log something");
}
}
Basically, project2 depends on project1. project1 depends on log4j. project2 does not depend on log4j and thus should not be able to use it.
When I run this build, the build somehow works. log4j is added as a compile-time dependency for project2 even though I did not want it.
This has happened in our real project. Many modules have dependencies which they should not have and this appears to be the cause.
How do I stop Gradle doing that?
For contrast, notice how buildr does the right thing by default.
buildfile:
repositories.remote << 'http://jcenter.bintray.com'
LOG4J = 'log4j:log4j:jar:1.2.17'
define 'dependency_leak' do
define 'project1' do
compile.with LOG4J
end
define 'project2' do
compile.with project(:project1)
end
end
If I now run buildr, the build downloads log4j and then fails because project2 is trying to compile and can’t find log4j, which is exactly what you would expect to happen with this dependency tree.
I don’t know why this isn’t the default behaviour, but in any case, is there a way to get the sane behaviour?