Quite significant changes were made to Spring Boot in 2.3.0, which is the first release of a project built using Gradle instead of Maven.

Each Spring project is developed and operated by an independent project team, which is consistent in the white-box part (such as API design) most commonly used by users. For the black-box part invisible to users, there is no unified agreement for each project team to choose its own suitable tool.

Example: project build tools. The Spring Framework has been built using Gradle since 3.2.0 in 2012, followed by Spring Boot a year later and Spring Cloud shortly thereafter, both based on Maven.

project Build tools
Spring Framework Gradle
Spring Boot Maven
Spring Cloud Maven

Why switch

The main reason the Spring Boot team considered switching from Maven to Gradle was to reduce the time required to build projects. During development and testing, the time spent waiting for builds to complete increases the time spent fixing bugs and implementing new features.

To address this issue, the team tried to leverage Maven’s support for parallel builds. The attempt failed due to the complexity of the Spring Boot build, particularly the use of the Invoker plug-in. Solve the CI problem by breaking the build into four parts. Build the main core of the project first, then build three separate parts in parallel. But CI can still take an hour or more to build. In addition, because of the modular CI build, there is no change in developer native build efficiency.

The Spring Boot team has seen incremental and parallel builds of Gradle in other Spring projects that utilize Gradle as a build tool, as well as the benefits of Gradle’s build cache in third-party projects. You expect similar benefits from using Gradle for Spring Boot builds.

Gradle has a very flexible build model and can define the inputs and outputs of each task and their interdependencies. The benefit of this build model is that it allows tasks to run in parallel, while also incrementing, caching, or skipping altogether. In other words, Gradle can perform the necessary CI tasks with minimal effort. Although we can use Gradle Enterprise’s Maven support, we can also enjoy the benefits of build caching and skipping. But to fully benefit from all four aspects, you must try switching to Gradle.

How to switch

Gradle configurations are too flexible, making its builds harder to maintain and understand than Maven-based builds. For example, the same build result can be implemented through different configurations. If you switch to Gradle, you need to avoid this situation. From the four Milestone Spring Boot 2.3 releases released so far, no major build issues have been detected among the core team or contributors.

  • The key feature of Spring Boot is convention over configuration, so apply this approach to builds. To avoid including imperative logic in build.gradle files, I wrote a few small plugins to buildSrc that can be found in the project.

While the existing Gradle ecosystem is almost empty for Spring Boot builds, requiring many generic Gradle plug-ins to be written from scratch to apply to Spring Boot, the commit to move to Gradle removes nearly 9500 lines from the code base.

Switch the result

Moving builds to Gradle is undoubtedly a success in terms of reducing project build time. As mentioned above, a full Maven-based build takes an hour or more on both CI and developer machines. The average successful build time based on Gradle is 9 minutes and 22 seconds, as shown in the screenshot below:

If you’re interested in building performance in more detail, you can get more data on a public Gradle Enterprise instance of Spring Boot.

In addition to improving performance, explore other features. For example, there have been a number of erratic tests for some time. For these reasons, builds fail more often than expected, as you can see in the Tests dashboard. Gradle sharding tests are used instead of CI’s generic testing scheme and help us know if we have successfully solved the problem.

conclusion

CI builds now take about 20 minutes on average, 3-4 times faster than before. Local builds take an average of 2 minutes and 30 seconds, 20-30 times faster than before.

migrating-spring-boot-s-build-to-gradle

Gradle follows the standardization practice: A Single line of code makes a difference!