I have recently added a Gradle nature to our existing web project. The project itself is a layered java project
Common - DataAccess - Business - Web
\- Batch
Before we have used, we manually managed the dependencies of the project and added only the neccessary libraries to each project.
To support our project structure, I created a gradle multi-project:
root
+-- build.gradle
+-- settings.gradle
+-- Common
+-- build.gradle
+-- DataAccess
+-- build.gradle
+-- Business
+-- build.gradle
+-- Web
+-- build.gradle
+-- Batch
+-- build.gradle
The files look basically like this (shortened of course)
Common -> build.gradle
[...]
implementation 'javax.money:money-api:1.0.3'
implementation 'org.slf4j:slf4j-log4j12:1.7.5'
testImplementation 'org.springframework:spring-test:4.3.13.RELEASE'
[...]
DataAccess -> build.gradle
dependencies {
[...]
api project(':Common')
implementation 'javax.money:money-api:1.0.3'
implementation 'org.slf4j:slf4j-log4j12:1.7.5'
implementation 'org.hibernate:hibernate-core:5.2.14.Final'
implementation 'org.hibernate:hibernate-jcache:5.2.14.Final'
implementation 'org.springframework.data:spring-data-jpa:1.11.9.RELEASE'
testImplementation 'org.springframework:spring-test:4.3.13.RELEASE'
[...]
}
Business -> build.gradle
dependencies {
[...]
api project(':DataAccess')
implementation 'org.slf4j:slf4j-log4j12:1.7.5'
implementation 'com.google.guava:guava:25.1-jre'
implementation 'com.googlecode.java-ipv6:java-ipv6:0.16'
testImplementation 'org.springframework:spring-test:4.3.13.RELEASE'
[...]
}
And so on. No problem so far, the gradle build executes without any errors.
But after creating the eclipse project and classpath files with gradle, the Business project has all the libraries of its child project in the classpath. This isn't a big problem at first, but this allows the developers to use libraries unavailable to gradle. This could lead to build errors later on the build server.
Of course I just could add all the depencies using api instead of implementation, but there should be a contract which things to use on each layer, right? It doesn't make sense to have access to hibernate / mysql libraries in the business or even worse, the web layer.
Is there a way to prevent gradle from adding libraries of the subprojects to the eclipse classpath?
Update 2019-10-16
Tried to go another route. Instead of API, I used a custom configuration to import the subproject:
root projects build.gradle: Just went another route, but I haven't been able to solve the issue yet. To the roots build project, I added the following:
allprojects {
configurations {
warOnly
warOnly.transitive = false
compile.extendsFrom(warOnly)
}
eclipse
{
classpath {
minusConfigurations += [ configurations.runtimeClasspath, configurations.testRuntimeClasspath ]
}
}
}
And switched from
api project(':Common')
to
warOnly project(':subprojectname')
However, that also seem to remove all the dependencies from compileClasspath as well. Not a feasible solution.