Gradle leverages plugins
Usually, build.gradle file would have a bunch of plugins applied. These plugins provide specific functionalities. Many of the targets that you are running might have come from these plugins. Read up the documentation of these plugins so you can use them right. Examples of common plugins — java, java-library,jacoco,sonarqube etc.
Use standard gradle configurations
Gradle java-library plugin has standard configurations — implementation,testImplementation, compileOnly, testCompileOnly and so on. Gradle has specific support for these standard configurations which is not available for custom configurations.
Duplicate transitive jars handling
Using the standard configuration of
implementation instead of a custom configuration of
app_compile resulted in many duplicate jars not to be downloaded.
Conditional apply of plugins
It takes time to apply these gradle plugins. By default, have these plugins with
apply as false. Conditionally apply these plugins only when there is a need to run these. For instance, jacoco and sonarqube plugins need to be applied only when the build.gradle file is invoked from the gitlab CI pipeline, while it is not needed when invoked from a developer’s machine.
Isolating Gitlab CI
Checking for the presence of the system environment variable
System.getProperty("CI_PIPELINE_ID") to determine whether gradle was invoked from gitlab CI or local machine served as a helpful flag to control the execution flow of the gradle targets.
build.gradle has a way of growing in size as the project grows in size, and the number of jars increases. Helps to modularize into multiple smaller files — plugin specific files, specific file to capture configurations etc.
The dependency tree for the project can be extracted using grade tasks such as
./gradlew dependencies --configuration implementation
Similarly, to get dependencyInsight for a specific jar, this can be done as well.
gradle -q dependencyInsight --dependency commons-codec --configuration scm
For dependency resolution for the issue with duplicate jars, the usage of standard configurations like
testImplementation goes a long way. There were still a few jars that were duplicates. The reason these were present is that the group names were different even while the root of the jar name was the same. For e.g.
javax.inject jar was present with multiple version because one of the jars had group name as
javax.inject while another version of
javax.inject jar had group name as something else.
To resolve such one-off jars from duplicating, use
dependencyInsight to find where these transitive dependencies are coming from in the first place, and then use
dependencyConstraint to exclude the particular group/jar that you want to exclude.