Enterprise Java

Gradle Configuration

In this post, we feature a comprehensive article about Gradle Configuration.

1. Technology

Gradle is an open-source build tool for automatic task management. It builds upon the concept of Apache Ant, Apache Maven. Gradle is developed using the Groovy language. Gradle is developed using Groovy-based Domain Specific Language (DSL). The Gradle build contains the tasks in Groovy language, as Apache Maven, and Apache Ant build file is of the XML format.

Gradle uses a Directed Acyclic Graph (DAG) to determine the order to execute the tasks. Gradle was designed for multi-project builds, which means one project will have many child projects, which can grow to a high number. The Unique feature in Gradle is that it supports the incremental builds by intelligently determining which parts of the build tree is modified and which are not. If some parts of the tree are not modified then it will be skipped by showing up-to-date, others will be re-executed, which will decrease the build time of the projects.

2. Java Project Structure

Similar to Maven directory structure, Gradle is project structure will also contain src/main/java and src/main/resources for Java Classes and class-path resources, src/test/java and src/test/resources will contain the test classes and test resources accordingly.

3. Gradle Configuration

Gradle is the fundamental concept for specifying the dependencies. Using the Configuration we used to specify the dependencies which may in the local cache or Maven Central Repository or any repository configured in the Gradle build file.

Gradle is also supported in executing the Maven build file(pom.xml) file and ant build file (build.xml) file, by importing it into Gradle build file(build.gradle).

By default Gradle supports below configurations:

3.1. implementation

The implementation configuration should be considered the default. We use it to declare dependencies that we don’t want to expose to our consumers’ compile time. This configuration is introduced as the replacement of the deprecated compile configuration to avoid polluting the consumer`s compile-time, with the dependencies we actually don’t want to expose.

a) Gradle adds the dependency to the compile classpath and packages the dependency to the build output. However, when your module configures an implementation dependency, it’s letting Gradle know that you do not want the module to leak the dependency on other modules at compile time. That is, the dependency is available to other modules only at runtime.

b) Using this dependency configuration instead of API or compile (deprecated) can result in significant build time improvements because it reduces the number of modules that the build system needs to recompile. For example, if an implementation dependency changes its API, Gradle recompiles only that dependency and the modules that directly depend on it. Most apps and test modules should use this configuration.

3.2. API

We use the API configuration do declare dependencies that are part of our API, i.e. for dependencies that we explicitly want to expose to our consumers. This is the only standard configuration that exposes dependencies to the consumers’ compile time.

a) Gradle adds the dependency to the compile classpath and builds output. When a module includes an API dependency, it’s letting Gradle know that the module wants to transitively export that dependency to other modules, so that it’s available to them at both runtime and compile time.

b) This configuration behaves just like compile, but you should use it with caution and only with dependencies that you need to transitively export to other upstream consumers. That’s because, if an API dependency changes its external API, Gradle recompiles all modules that have access to that dependency at compile time. So, having a large number of API dependencies can significantly increase build time. Unless you want to expose a dependency’s API to a separate module, library modules should instead use implementation dependencies.

3.3. compileOnly

The compileOnly configuration allows declaring dependencies that should be available only at compile, not at the runtime. For example Project, Lombok is the library, which modifies the bytecode at compile-time, and adds more methods to class by using the annotations. Once updated bytecode is generated it is not needed to present in class-path, for these types of libraries will use this configuration.

3.4. runtime Only

Gradle adds the dependency to the build output only, for use during runtime. That is, it is not added to the compile classpath. For example Database Driver, we used to specify the driver class-name in configuration, but is not needed to present at the compile-time, it is only useful at the runtime.

3.5. annotation processor

To add a dependency on a library that is an annotation processor, you must add it to the annotation processor classpath using the annotation processor configuration. That’s because using this configuration improves build performance by separating the compile classpath from the annotation processor classpath. If Gradle finds annotation processors on the compile classpath, it deactivates compile avoidance, which negatively impacts build time (Gradle 5.0 and higher ignore annotation processors found on the compile classpath).

3.6. test implementation

Similar to implementation configuration, test implementation configuration is used to specify the dependencies which are available during the compile and runtime of tests. For Example, Junit and Mocking libraries are only needed while compiling or executing the tests.

3.7. testCompileOnly

Similar to compile Only the dependencies are only available at test class compilation but not at the runtime of the tests.

3.8. testRuntimeOnly

Similar to runtimeOnly, these dependencies are available at executing the tests, but not at the compilation of tests.

All the above are the configurations provided by the Gradle by default, by we can use custom configurations, specify these custom configurations in custom tasks. Gradle also supports the inheritance in the configuration. We can use extends from the property on the configuration to specify the base configuration.

configurations {
  testCompileOnly.extendsFrom compileOnly

Where all complete configuration dependencies will be copied to testCompileOnly Configuration, which will remove the duplicate specifications in the Gradle build file.

4. Gradle Configuration – Conclusion

In the current blog, we learned about the Gradle build tool and added advantages of Gradle over Maven, Ant build tools. We leaned the Gradle configuration in detail, where how to specify the dependencies at each configuration level.

In this article, I’ll depict everything you ever engineer need to mindful of Java Web application utilizing Gradle. I’ve finished numerous enormous Java ventures that would’ve been conceivable Gradle. It offers rapidly oversee and transportability. Utilizing Gradle to simple arrange amazing in your undertakings.

Vipul Patel

Vipul Patel is a Senior Java Technical Lead working at Aegis Software Pvt Ltd. Vipul is having 10+ years of experience in Java Development, having strong hands-on Spring, Spring Boot, EJB, Hibernate & Apache Spark. Vipul manages Java Practices at Aegis Group that includes Projects from Multinational clients across the world.
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Newest Most Voted
Inline Feedbacks
View all comments
Nick Christopher
Nick Christopher
3 years ago

Gradle used to depend on Groovy as a DSL, for a while now however it is equally happy using Kotlin.

Back to top button