Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Managing Dependencies for Spring Projects with Gradle

Managing Dependencies for Spring Projects with Gradle

Managing dependencies is hard. For Spring projects, Gradle and Maven are just two of the tools we can use to help make dependency management easier. They both handle dependency management effectively, but in very different ways. For example, Maven uses BOMs, and, until recently, Gradle didn’t have an equivalent concept. Because of this and other differences, the Spring Dependency Management plugin was created so that Gradle users who already knew Maven could manage dependencies in a way that was familiar to them.

For earlier versions of Gradle, the plugin’s version enforcement and dependency exclusion features were revolutionary and led to the Spring Dependency Management Plugin’s popularity in the Spring ecosystem and spread to other JVM-based communities such as Android. Now that Gradle 5.X includes native BOM support, users can replace parts of the plugin and take advantage of the productivity gains of the native support.

In this session, we’ll go over some basic use cases for Gradle native BOM support and show you how to use it to manage the dependencies of a Spring Boot application. We’ll also look at some scenarios where you’ll still want to use the Spring Dependency Management Gradle plugin.

jlstrater

May 16, 2019
Tweet

More Decks by jlstrater

Other Decks in Technology

Transcript

  1. spring-boot-dependencies • Maven bill of materials (bom) • Manages dependency

    versions (and Maven plugin versions) • Both Spring and third-party dependencies • Over 150 version properties • Over 800 dependencies
  2. <properties> … <spring-framework.version>5.1.6.RELEASE</spring-framework.version> … <thymeleaf.version>3.0.10.RELEASE</thymeleaf.version> … </properties> <dependencyManagement> <dependencies> …

    <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>${thymeleaf.version}</version> </dependency> … </dependencies> </dependencyManagement> spring-boot-dependencies
  3. • Removes the need to think about versions when declaring

    dependencies • Provides a consistent version across a library’s modules • Avoids accidentally mixing acme-core 1.2 with acme-server 1.1 • Provides default versions that are tested and known to work together • Just an opinion • Override to meet a project’s needs Why is a bom a good thing?
  4. Importing a bom plugins { id 'io.spring.dependency-management' version '1.0.7.RELEASE' }

    dependencyManagement { imports { mavenBom 'o.s.b:spring-boot-dependencies:2.1.4.RELEASE' } }
  5. $ ./gradlew dependencyManagement > Task :dependencyManagement ------------------------------------------------------------ Root project ------------------------------------------------------------

    global - Default dependency management for all configurations … org.thymeleaf:thymeleaf 3.0.11.RELEASE org.thymeleaf:thymeleaf-spring5 3.0.11.RELEASE org.thymeleaf.extras:thymeleaf-extras-java8time 3.0.4.RELEASE org.thymeleaf.extras:thymeleaf-extras-springsecurity5 3.0.4.RELEASE … Importing a bom
  6. dependencies { runtime 'org.thymeleaf:thymeleaf-spring5' } Overriding a version runtimeClasspath -

    Runtime classpath of source set 'main'. \--- org.thymeleaf:thymeleaf-spring5 -> 3.0.11.RELEASE +--- org.thymeleaf:thymeleaf:3.0.11.RELEASE | +--- org.attoparser:attoparser:2.0.5.RELEASE | +--- org.unbescape:unbescape:1.1.6.RELEASE | \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26 \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
  7. Overriding a version dependencies { runtime 'org.thymeleaf:thymeleaf-spring5:3.0.10.RELEASE' } runtimeClasspath -

    Runtime classpath of source set 'main'. \--- org.thymeleaf:thymeleaf-spring5:3.0.10.RELEASE +--- org.thymeleaf:thymeleaf:3.0.10.RELEASE -> 3.0.11.RELEASE | +--- org.attoparser:attoparser:2.0.5.RELEASE | +--- org.unbescape:unbescape:1.1.6.RELEASE | \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26 \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
  8. Overriding a version ext['thymeleaf.version'] = '3.0.10.RELEASE' runtimeClasspath - Runtime classpath

    of source set 'main'. \--- org.thymeleaf:thymeleaf-spring5 -> 3.0.10.RELEASE +--- org.thymeleaf:thymeleaf:3.0.10.RELEASE | +--- org.attoparser:attoparser:2.0.5.RELEASE | +--- org.unbescape:unbescape:1.1.6.RELEASE | \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26 \--- org.slf4j:slf4j-api:1.7.25 -> 1.7.26
  9. Maven-style exclusions <dependencies> <dependency> <groupId>example</groupId> <artifactId>exclusions</artifactId> <version>0.0.1</version> </dependency> <dependency> <groupId>org.springframework</groupId>

    <artifactId>spring-beans</artifactId> </dependency> </dependencies> dependencies { implementation 'example:exclusions:0.0.1' implementation 'org.springframework:spring-beans' }
  10. Maven-style exclusions +- example:exclusions:jar:0.0.1:compile | \- org.springframework:spring-core:jar:4.1.3.RELEASE:compile \- org.springframework:spring-beans:jar:4.1.3.RELEASE:compile +---

    com.example:exclusion-example:1.0 | \--- org.springframework:spring-core:4.1.3.RELEASE | \--- commons-logging:commons-logging:1.2 \--- org.springframework:spring-beans:4.1.3.RELEASE \--- org.springframework:spring-core:4.1.3.RELEASE (*)
  11. Overriding Groups of Dependencies https://docs.gradle.org/current/userguide/customizing_dependency_resolution_behavior.html#sec:dependency_resolve_rules dependencies { implementation platform('org.springframework.boot:spring-boot-dependencies:2.1.4.RELEASE') implementation

    "org.codehaus.groovy:groovy:2.5.7" } configurations.all { resolutionStrategy.eachDependency { DependencyResolveDetails details -> if (details.requested.group == 'org.codehaus.groovy') { details.useVersion '2.5.7' details.because 'upgrade to take advantage of new features' } } }
  12. Exclusions dependencies { implementation('log4j:log4j:1.2.15') { exclude group: 'javax.jms', module: 'jms'

    exclude group: 'com.sun.jdmk', module: 'jmxtools' exclude group: 'com.sun.jmx', module: 'jmxri' } } configurations { implementation { exclude group: 'javax.jms', module: 'jms' exclude group: 'com.sun.jdmk', module: 'jmxtools' exclude group: 'com.sun.jmx', module: 'jmxri' } }
  13. IDE Support • Tooling hasn’t caught up to new 5.0

    features • Issues are filed and should be fixed soon
  14. Overriding Version Properties • The Plugin’s behavior is unique. It

    goes beyond both Maven and Gradle features. • For upgrading, overriding is possible in Gradle. • For downgrading, use: ◦ • Dependency metadata rule to fix what the dependency declares and is wrong ◦ • Substitutions to replace a given version with another ◦ • Force ◦ • Exclude • Look for new Gradle releases to fix the remaining differences.