Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to selectively upgrade a dependency in Spring Boot? (sample case: Spring Data)

Tags:

I use the Spring Data JPA starter of Spring Boot (1.4.1). It contains Spring Data JPA 1.10.3. However, I need to use @DomainEvents annotation which does not yet exist in this version spring data. When I try to add latest version of Spring Data JPA i get errors when my application runs.

My pom example:

<parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>1.4.1.RELEASE</version>         <relativePath/> </parent>  <dependencies>         ...         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-data-jpa</artifactId>         </dependency>         ... </dependencies> 

When i try to add latest version of Spring Data JPA like that:

<dependencyManagement>     <dependencies>         <dependency>             <groupId>org.springframework.data</groupId>             <artifactId>spring-data-jpa</artifactId>             <version>1.11.6.RELEASE</version>         </dependency>     </dependencies> </dependencyManagement> 

I get erorrs when i start my app. Errors like this:

Caused by: java.lang.NoSuchMethodException: org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.<init>()   at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_121]   at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_121]   at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE]   ... 53 common frames omitted 

How can I use the newer version of Spring Data JPA? I need @DomainEvents in my app. Thanks!

like image 440
V. Kuznetsov Avatar asked Aug 30 '17 18:08

V. Kuznetsov


People also ask

How do you override Jackson dependency in spring boot?

Adding jackson-bom. version to your properties section of the pom. xml file should update jackson dependencies. This will override jackson version in the Spring Boot Parent POM.

How do I manage spring boot dependencies?

Spring Boot manages dependencies and configuration automatically. Each release of Spring Boot provides a list of dependencies that it supports. The list of dependencies is available as a part of the Bills of Materials (spring-boot-dependencies) that can be used with Maven.

How do you override a transitive dependency?

How do you do this if the wrong dependency is a transitive dependency? By taking advantage of Maven's nearest definition logic, developers can override the version of a dependency by declaring it on the root pom. xml file.


1 Answers

There multiple ways to skin the cat here that all come with different up- and downsides:

Option 1: Upgrading to newer version of Boot

The safest way overall is to upgrade to a more recent version of Spring Boot. We generally advise to be on the latest minor version in the current major generation. In your case 1.5 is the most recent minor, so we recommend to upgrade to that (currently 1.5.6). This is usually achieved by just changing the version number of the parent pom you use.

<parent>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-parent</artifactId>   <version>1.5.6.RELEASE</version> </parent> 

Pros

  • You'll automatically upgrade all Boot managed dependencies to their latest, compatible versions. This is advisable as this will make sure you get latest fixes for security updates in third party dependencies

Cons

  • A minor version upgrade might require you to slightly change things about your configuration or in the APIs in case you depend on third-party API from your application code. Minor version upgrades in Boot are usually very careful when it comes to not pulling in breaking changes in third-party libs, but unfortunately not all of them follow semantic versioning. However, if you have a decent test suite it should be easy to find out whether you'd run into problems. It's recommended to have a look at the release notes as they usually contain migration guides.

Option 2: Upgrading dependencies individually

An alternative to the previous approach is staying at the Boot version you're at but selectively upgrading third party dependencies. The preferred way to do that is by checking which version placeholders exist in spring-boot-dependencies. Then you just need to redeclare the property in your project and tweak the version. For Spring Data, that'd be:

<properties>   <spring-data-releasetrain.version>Ingalls-SR6<spring-data-releasetrain.verion> </properties> 

In case of Spring Data you're upgrading the entire release train at once here so that you don't run into the incompatibility between Spring Data modules internally if you just upgrade one module. That's one of the main reasons this "upgrade by property" is recommended over re-declaring a dependency in a newer version explicitly (which still can be a last resort in some cases).

Pros

  • The upgrade is much more selective operation. In contrast to the previous approach, you're not risking running into upgrade problems of unrelated dependencies.

Cons

  • It might not work! - Sometimes dependencies change some internal APIs that Boot's auto-configuration depends on in a minor release. This could cause the auto-configuration to not work at startup which you can try to then replace by excluding the auto-configuration explicitly and writing manual configuration.

Suggested steps

In practice I usually try the following steps:

  1. Use option 1 to upgrade with as little impact as possible. If that succeeds: Done.
  2. If that causes problems, evaluate how hard it is to replace the auto-configuration with manual config (usually requires a bit of insight and experience with Boot. If that succeeds: Done.
  3. Use option 2 to upgrade to a newer version of Boot and evaluate the impact this has on your application code.

2 and 3 might be interchangeable depending on what you personally prefer or the dependency upgrade policy you've defined for your team.

Generally speaking it's a good idea to keep an eye on Boot releases and regularly try to dry-upgrade the project to that newer version but not necessarily ship that upgrade to production. That allows you the evaluate the risk of upgrading and estimate the amount of work that needs to go into this. Avoiding upgrades basically just makes them more painful, but yeah, sometimes they can't be made right away because of political reasons or because the upgrade is running into problems in newer versions.

like image 130
Oliver Drotbohm Avatar answered Sep 25 '22 09:09

Oliver Drotbohm