We have upgraded from Spring boot 2.7.12/Java 11 to 3.1.7/Java 17. Some of our endpoints were working as expected while some are failing. One of the failing endpoint has GetMapping(value="/resource/test/") as given below.
And the error is
Handler dispatch failed: java.lang.NoSuchMethodError: 'org.springframework.http.HttpStatus org.springframework.http.client.ClientHttpResponse.getStatusCode()'.
Controller:
@javax.annotation.Resource
private RestTemplate externalRestTemplate;
@GetMapping(value = "/resource/test", produces = MediaType.APPLICATION_PDF_VALUE)
public ResponseEntity<org.springframework.core.io.Resource> getValue(
@RequestParam @Size(max = 5)
@Pattern(regexp = "^[A-Za-z0-9]+$") String code,
@RequestParam @Size(max = 10)
@Pattern(regexp = "^[0-9]+$") String key) {
try {
org.springframework.core.io.Resource resource = externalValue(code, key);
if (resource == null) {
return new ResponseEntity("Not available", HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(resource, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity("error", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
public org.springframework.core.io.Resource externalValue(String code, String key){
final ResponseEntity<Resource> responseEntity;
try{
RequestEntity<String> requestEntity = new RequestEntity<>(getRequestHeaders(), HttpMethod.GET, buildURIforValue(code, key));
responseEntity = externalRestTemplate.exchange(requestEntity, org.springframework.core.io.Resource.class);
return responseEntity.getBody();
} catch (final RestClientException e) {
return null;
}
catch (final Exception e) {
return null;
}
}
public HttpHeaders getRequestHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_PDF, MediaType.APPLICATION_OCTET_STREAM));
return headers;
}
private URI buildURIforValue(String code, String key){
return UriComponentsBuilder.fromUriString("https://wwwsb.testxyz.com/test/value.json"+"?"+
"key"+"="+key
+"&"+"vin"+"="+vin).build().toUri();
}
build.gradle:
plugins {
id 'java'
id 'maven-publish'
id 'org.springframework.boot' version '3.1.7'
id 'gradle-boost' version '5.0.1'
id 'org.sonarqube' version "4.2.1.3168"
id 'com.google.cloud.tools.jib' version '3.4.0'
id 'com.jfrog.artifactory' version '5.+'
id 'jacoco'
}
group = 'com.test.one'
version = gradleBoost.fn.gitVersion()
println "Build Version = ${version ?: '[none]'}"
sourceCompatibility = JavaVersion.VERSION_17
dependencies {
// Bill Of Materials Imports
bomImport platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)
bomImport platform('com.google.cloud:spring-cloud-gcp-dependencies:4.8.4')
//Core libraries
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'com.testone.cloudnative:spring-boot-starter-testone:5.0.0'
// Spring Integration
implementation 'org.springframework.integration:spring-integration-core'
//gcp logging
implementation 'com.google.cloud:spring-cloud-gcp-starter'
implementation 'com.google.cloud:spring-cloud-gcp-starter-trace'
implementation 'com.google.cloud:spring-cloud-gcp-starter-logging'
//implementation 'org.springframework.cloud:spring-cloud-sleuth-api:3.1.10'
//security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'com.testone.cloudnative:spring-base-security:2.0.0'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.security.oauth:spring-security-oauth2:2.5.0.RELEASE'
//secrets manager
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager'
implementation 'com.testone.spring.filters:forwarded-auth-header-rewrite:1.0.0'
//database
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.flywaydb:flyway-core'
localOnly 'com.h2database:h2'
implementation 'org.postgresql:postgresql'
implementation 'com.google.cloud.sql:postgres-socket-factory:1.13.1'
implementation 'com.google.cloud:spring-cloud-gcp-starter'
//SRE Metrics
implementation 'com.testone.mpp.pe.sre:metrics:3.0.5'
//Feign
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.0.4'
// https://mvnrepository.com/artifact/com.netflix.feign/feign-jackson
implementation 'com.netflix.feign:feign-jackson:8.18.0'
//BigTable
implementation ('com.google.cloud:google-cloud-bigtable:2.27.0')
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
implementation 'org.springframework:spring-core:6.0.16'
//others
implementation 'org.springdoc:springdoc-openapi-ui:1.7.0'
implementation 'org.modelmapper:modelmapper:2.4.5'
implementation fileTree(dir: "$rootDir/src/main/resources/lib", include: '*.jar')
implementation 'javax.ws.rs:javax.ws.rs-api:2.1.1'
implementation 'org.apache.commons:commons-collections4:4.4'
implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-jakarta-xmlbind-annotations', version: '2.16.1'
//other
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'com.mikesamuel:json-sanitizer:1.2.2'
implementation group: 'org.json', name: 'json', version: '20230227'
implementation 'org.skyscreamer:jsonassert:1.5.0'
implementation 'org.apache.httpcomponents.client5:httpclient5'
///BEGIN - Temporary Workarounds
///END - Temporary Workarounds
/*********** TEST libs ***********/
testImplementation 'com.testone.cloudnative:spring-base-test:5.0.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testAnnotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.mockito:mockito-inline:2.13.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
testImplementation 'net.javacrumbs.json-unit:json-unit-assertj:2.36.0'
testImplementation 'org.glassfish.jersey.core:jersey-common:2.22.2'
testImplementation 'org.junit.jupiter:junit-jupiter-migrationsupport:5.9.0'
testImplementation 'com.google.cloud:google-cloud-bigtable-emulator:0.150.0'
}
tasks.withType(Test) {
useJUnitPlatform()
}
test {
finalizedBy jacocoTestReport // report is always generated after tests run
}
repositories {
maven {
url 'https://jfrog.testone.com/artifactory/test-sbox-local'
credentials {
username System.getenv('JFROG_USERNAME')
password System.getenv('JFROG_PASSWORD')
}
}
}
Tried changing the javax dependency in build.gradle to jakarta dependency. Still getting same error.
Also tried few options from online blogs, but nothing worked. Failing in externalRestTemplate.exchange(requestEntity, org.springframework.core.io.Resource.class);
Does RestTemplate work with Spring boot 3?
If so, how to handle this error?
Currently, we have 'javax.ws.rs-api dependency', tried updating it to 'jakarta.ws.rs-api', still no luck.
The same code and endpoint with Spring boot 2 is working without any issues.
How to get rid of this error? Anything else to be checked while upgrading from spring boot 2 to 3 which may be causing this issue?
RestTemplate does work with Spring Boot 3. Spring Boot 3 continues to support RestTemplate, although it's marked as deprecated in favor of WebClient (introduced in Spring WebFlux).
Consider apply Spring Boot BOM (Bill of Materials) in your project explained here: How to find out which dependency version I should use?
Also, validade your SB external dependencies in: https://docs.spring.io/spring-boot/docs/current/reference/html/dependency-versions.html