Spring Boot 2 fails starting due to Hystrix? - spring-boot

I started investigating to migrate a Spring Boot application from 1.5.x to 2.
This appliication has a dependency to hystrix, which does not be compatible to Spring Boot 2 yet.
When I have the following in my pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
I get the following error when starting the application:
java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder.<init>([Ljava/lang/Object;)V
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:125)
Anybody has experienced the same?
Is there a solution yet?

I have faced similar issue while integrating hystrix for my spring boot microservice that uses spring boot 2.0.x.
Instead of
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>${spring-hystrix.version}</version>
</dependency>
I have moved to
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>${spring-hystrix.version}</version>
</dependency>
Spring boot 2.0.x application starts fine with the spring-cloud-starter-netflix-hystrix dependency without this issue.

For SpringBoot 2.0 version artifactID has been changed. Old dependency is
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>${spring-hystrix.version}</version>
</dependency>
Use this new updated dependency with latest version
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.8.RELEASE</version>
</dependency>
for recent release version you can check MVNrepository

After a bit further research I found a solution by adding the following to the pom file:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
all versions of spring-cloud-dependenciesseem to be incompatible to Spring Boot 2.x.x

I had this problem starting Spring Boot 2 as well because spring-cloud-starter-hystrix was a dependency I used in my project. However I found that spring-cloud-starter-hystrix has been deprecated. I also found the feign classes I was using in there have been moved to spring-cloud-openfeign (https://github.com/spring-cloud/spring-cloud-openfeign). So all I did was remove spring-cloud-starter-hystrix from my dependency and added spring-cloud-openfeign instead. This works perfectly for me.
Basically I replaced
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-hystrix', version: '1.4.4.RELEASE'
with
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-openfeign', version: '2.0.0.RELEASE'
and Spring Boot 2 is ready to go. Hope this helps.
NB: I use Gradle, you can easily find the maven pom dependency equivalents if necessary.

I faced a similar problem with Spring Boot 2, concisely 2.2.0.RELEASE. My mvn project compiled well but Spring Boot application stopped starting, without showing any real hints.
The solution that worked was using the artifact spring-cloud-starter-netflix-hystrix instead of spring-cloud-starter-hystrix from the same group. Then you can use the same same version as Spring Boot to retrieve the dependency.
From old pom.xml :
<!-- hysterix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
New part in working pom.xml:
<!-- hysterix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>${spring.boot.version}</version>
</dependency>

After some time spent on researching and testing, here is what I found and noticed
I think that in the latest Spring Boot version (2.5.x), the Hystrix looks to be deprecated or I just couldn't find out way to add it as a dependency.
So I downgraded the Spring boot version to 2.3.x where I managed to run the application
So here is how my working pom.xml looks like:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.hldservices</groupId>
<artifactId>payment-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringCloudPaymentCircuitBreakerApplication</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.SR11</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Keep in mind that I had to add following configuration in my Project:
SpringCloudPaymentCircuitBreakerApplication(main class)
#EnableHystrix
#EnableHystrixDashboard
application.propreties
management.endpoints.web.exposure.include=*
hystrix.dashboard.proxyStreamAllowList=*

Related

What GCP dependencies and versions for Spring Boot 2.5.14 Integration

I'm pretty bad with java and trying to get an older spring boot app moved into GCP. I have a proof of concept app working using spring-boot 3.0.1 and spring-cloud-gcp-starter-secretmanager#3.4.1. It runs fine and pulls secrets from Secret manager like a charm.
Pom snippet:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>edu.mayo</groupId>
<artifactId>secret-manager-poc</artifactId>
<version>1.0.0</version>
<name>secret-manager-poc</name>
<description>Spring boot POC with GCP secret manager</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
I'm trying to do the same thing in my older spring-boot app and getting really confused. Here is what I have for dependancies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.14</version>
<relativePath></relativePath>
</parent>
...
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
When I started loooking at what versions of the secretmanager starter I should use I came across this: https://spring.io/projects/spring-cloud Which makes it looks like I should used 2020.0.6 but then I've noticed that there are two groupIds org.springframework.cloud vs com.google.cloud, and I've been searching through posts and articles but I'm confused as hell. When I try run mvn clean install I get this message:
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'dependencies.dependency.version' for org.springframework.cloud:spring-cloud-gcp-starter-secretmanager:jar is missing. # line 158, column 15
Its complaining bout the version attribute being missing on the starter library, but all the docs I'm reading say that this should work.
mvn --version
Apache Maven 3.8.7 (b89d5959fcde851dcb1c8946a785a163f14e1e29)
Maven home: C:\Program Files\apache-maven-3.8.7-bin\apache-maven-3.8.7
Java version: 17.0.5, vendor: Microsoft, runtime: C:\Program Files\Microsoft\jdk-17.0.5.8-hotspot
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Which dependencies and versions should someone use to connect to GCP secret manager from a springboot 2.5.14 app?
EDIT / UPDATE.
Currently able to start Spring boot with these dependancies with spring-boot 2.5.14:
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>4.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
however my properties aren't being retreived from secret manager. I have this property file:
# General settings
api.version: #project.version#
# Akana settings
akana.secret.name=akana-shared-secret
akana.secret.hash=${sm://mde-akana-secret-hash}
...
But after spring-boot starts and I go to manage/env to print the env variables I see this:
"akana.secret.hash":{"value":"//mde-akana-secret-hash"}
all of the properties that are defined like this:
prop.name=${sm://sm-key}
are loaded into context like this:
prop.name=//sm-key
any idea what I'm missing?
Which dependencies and versions should someone use to connect to GCP secret manager from a springboot 2.5.14 app?
None.
After wasting today trying to figure out which dependency versions of both google and spring provided dependencies I needed to get spring boot to talk to GCP secrets manger, I happened across this random video. https://youtu.be/mRSJmHlkzck. After pausing it and transposing parts of the pom, I finally got the app to kick over and generate this lovely message:
***************************
APPLICATION FAILED TO START
***************************
Description:
Your project setup is incompatible with our requirements due to following reasons:
- Spring Boot [2.5.14] is not compatible with this Spring Cloud release train
Action:
Consider applying the following actions:
- Change Spring Boot version to one of the following versions [2.3.x, 2.4.x] .
You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn].
If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section.
If you want to disable this check, just set the property [spring.cloud.compatibility-verifier.enabled=false]
So I downgraded to springboot 2.4.13 and got it to work. Here are the relevant dependencies and versions:
<properties>
...
<spring-cloud-gcp.version>2.0.5</spring-cloud-gcp.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-secretmanager</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-starter</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>spring-cloud-gcp-dependencies</artifactId>
<version>${spring-cloud-gcp.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Then you'll need this in a bootstrap.properties file:
spring.cloud.gcp.secretmanager.bootstrap.enabled=true
spring.cloud.gcp.secretmanager.secret-name-prefix=sm://

How to override version of libraries included automatically under spring-boot-starter

I have spring-boot-starter in my POM and versions are automatically resolved by Camden dependency management system.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
This gives me version 1.4.3.RELEASE of spring-boot-starter.
One of the jars spring boot starter includes automatically in the maven dependencies is logback-classic: 1.1.18
ch.qos.logback_logback-core version 1.1.8 has a vulnerability because of which I want to switch over to logback version 1.2
This vulnerability is explained in the link below
https://nvd.nist.gov/vuln/detail/CVE-2017-5929
Now, is there a way to override the logback version to 1.2 from what spring-boot-starter automatically resolves it to so that I am not exposed to this vulnerability ?
Based on your pom file, you can achieve this by excluding the dependency of 1.1.8 first then add the dependency of 1.2.0.
For example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.0</version>
</dependency>
add properties tag in pom like this
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<start-class>org.roshan.Application</start-class>
<hibernate.version>5.2.10.Final</hibernate.version>
<liquibase.version>3.5.3</liquibase.version>
<liquibase-hibernate5.version>3.6.0</liquibase-hibernate5.version>
<httpcore.version>4.4.5</httpcore.version>
<httpclient.version>4.5.3</httpclient.version>
<docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
</properties>

Errors caused by not having declared a dependency

Has anyone successfully got Spring Boot, Spring Data Elasticsearch, and Elasticsearch 5.x to work?
I updated my pom to use spring-data-elasticsearch 3.0.0.RELEASE (just released) which has commit notes in Github saying it supports ES 5.
I was getting some errors which were caused by not having declared a dependency on spring-data-common. After adding without a version, I noticed it was being managed by Spring Boot apparently and pulls in 1.13.7.RELEASE
This causes: java.lang.NoClassDefFoundError: org/springframework/data/mapping/model/Property
I then bumped up spring-data-common to 2.0.0.RELEASE thinking the newest releases of everything should be compatible. That causes an AbstractMethodError exception when the repository is wired.
Can anyone give any tips? Here are the dependencies from my POM
Managed versions from Parent POM:
<spring-boot.version>1.5.7.RELEASE</spring-boot.version>
<spring-cloud.version>Dalston.RELEASE</spring-cloud.version>
From POM from the child module where things don't work
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<!-- <version>2.0.0.RELEASE</version> -->
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
Whomever edited the title made an inaccurate description. As originally stated, the issue is a "dependency hell". There wasn't missing dependencies but rather a ton of transitive dependencies that all needed versions to be coordinated in magic nonobvious/undocumented ways. – JvmSd121
I once migrated the spring-data-elasticsearch (with ES 2.x) project to use ES 5.x.
I lost the source but I still have the jar here
You guys put me on the right track. I upgraded as follows:
Spring Core (and related): 5.0.0.RELEASE
Spring Boot: 2.0.0.M4
Spring Cloud: Finchley.M2
With those in place, the managed versions get updated as follows:
spring-data-commons: 2.0.0.RC3 (from release-train KAY-RC3)
spring-data-elasticsearch: 3.0.0.RC3 (from release-train KAY-RC3)
elasticsearch and transport: 5.5.2 (meets my 5.x requirement)
We had managed versions of Jackson in our parent pom for other child modules which caused incompatible versions to be pulled in. I overrode those in our Spring Boot projects to the version ${jackson.version} defined in Spring as follows:
spring-jackson-version=2.9.1
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${spring-jackson.version}</version>
</dependency>
I'm getting another error from my repo which I think is self-inflicted due to my data model. All the classpath errors seem to have gone away. I'll give another update if I find anything further. What a cf!
Thanks for the tips.

spring cloud version Brixton.SR5 with spring boot 1.4

I have a new project that we are doing with spring Brixton.SR1...
and Brixton.SR1 or SR5 is built on 1.3.5.RELEASE but forum says it has been tested with 1.4.0.RELEASE and thus i want to use some features of 1.4.0.
<dependencyManagement>
<dependencies>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
..
</dependencyManagement>
And then we are adding dependencies and are all default versions are used eg.. spring boot is 1.3.5.RELEASE, so current structure is as given below.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
....
But i want to use 1.4.0 . Can i exclude 1.3.5 version and use this new version....and i dont want to overwritte this for all spring boot artifacts . eg.. as given below
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.4.0.RELEASE</version>
</dependency>
and so on so forth..
rather want to have a common version for spring-boot artifact and which should give default versions to all spring artifacts as 1.4.0
just import spring boot's 1.4 bom and spring cloud's bom into your pom.xml:
<dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.4.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

How to exclude transitive dependencies of spring-boot-dependencies from maven import scope

I have the following in my Spring Boot application pom as per the documentation:
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I need to use use dependencyManagement and <scope>import</scope> because I need to use a standard corporate base pom.
However, it doesn't seem possible to exclude transitive dependencies of spring-boot-dependencies. In my particular case, Spring Boot 1.2.1.RELEASE is bringing in a version of Jetty that is too new with respect to some of my other <dependencies>. I tried using an <exclusion> of the form:
<dependencyManagement>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
<!-- Doesn't work -->
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
using Maven 3.2.1's wildcard support, but it doesn't seem to take effect.
Is there a solution to this problem other than explicitly overriding all the Jetty dependencies? There are many Jetty libraries and that approach would be quite brittle. Furthermore, it appears I would need to do the same with Jetty's transitive dependencies as well.
According to the Spring Boot Maven Plugin 2.3.1.RELEASE documentation, to override individual dependencies, you need to add entries in the dependencyManagement section of your project before the spring-boot-dependencies entry.
<dependencyManagement>
<dependencies>
<!-- Your jetty version dependency -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>*</artifactId>
<version>${jetty.version}</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Looks like this isn't possible with Maven import scope:
The import scope can be used to include dependency management
information from a remote POM into the current project. One of the
limitations of this is that it does not allow additional excludes to
be defined for a multi module project.
Likewise, there is a confirmation from the Spring Boot documentation:
If you have added spring-boot-dependencies in your own
dependencyManagement section with <scope>import</scope> you have to
redefine the artifact yourself [...].

Resources