1

I'm upgrading my main application from Spring Boot 2.x to 3.x.

The upgrade is mostly successful, except for a runtime compatibility issue caused by 3rd-party or legacy internal libraries that still depend on Spring Boot 2.x and the RestTemplate API.


Context:

  • My main application now uses:

    • Spring Boot: 3.x
    • Spring Framework: 6.x
    • JDK: 17
  • However, I have hundreds of shared SDKs/libraries (some internal, some 3rd-party) that:

    • Are compiled against Spring Boot 2.x
    • Use org.springframework.web.client.RestTemplate
    • Internally call:
      org.springframework.http.client.ClientHttpResponse#getStatusCode()
      
      expecting it to return org.springframework.http.HttpStatus.

After upgrading, I’m getting the following error during runtime: java.lang.NoSuchMethodError: ‘org.springframework.http.HttpStatus org.springframework.http.client.ClientHttpResponse.getStatusCode()

This happens inside a ClientHttpRequestInterceptor in one of the legacy SDKs that I cannot modify.

Here’s a snippet from the stack trace:

Caused by: java.lang.NoSuchMethodError: ‘org.springframework.http.HttpStatus org.springframework.http.client.ClientHttpResponse.getStatusCode()’
at com.legacy.sdk.interceptor.LegacyInterceptor.intercept(LegacyInterceptor.java:46)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:900)

This makes sense because Spring Framework 6.x changed the method signature:

Old (Spring Boot 2.x / Framework 5.x): HttpStatus ClientHttpResponse.getStatusCode();

New (Spring Boot 3.x / Framework 6.x): HttpStatusCode ClientHttpResponse.getStatusCode();

The old method was removed (not deprecated), so libraries expecting the old signature will crash.

Additional Details

  • I cannot update these legacy libraries immediately — some are external, some very deeply integrated.
  • I’ve already migrated my own code to use RestClient instead of RestTemplate.
  • However, legacy dependencies still use RestTemplate, and I can’t change them.

Is there any official or community-recommended strategy to run Spring Boot 2.x compiled SDKs (that rely on deprecated/removed methods like ClientHttpResponse#getStatusCode()) inside a Spring Boot 3 application?

4
  • No there isn't as they are incompatible. If you cannot upgrade the libraries, you cannot upgrade this to Spring Boot 3 either. Commented Jun 20 at 10:29
  • Thanks, @M.Deinum — Do you think Spring should have provided some backward compatibility (like a shim) for this case? It feels a bit harsh that there's no official support for such a common breaking change. As someone who has read your books, I'd genuinely like to hear your personal take on this. Commented Jun 20 at 10:54
  • @MedCezir It is a major update with breaking changes. It comes with more significant breaking changes like the change to a JDK 17 baseline, the use of Jakarta EE and the removal of WebSecurityConfigurerAdapter. The same version of some code isn't expected to work with both Spring 5 and 6. Commented Jun 21 at 5:24
  • The method hasn't been removed the returntype changed. The HttpStatus (which infact is still being returned) now implements an interface. That interface is the HttpStatusCode. This change was introduced to allow for customized HTTP return codes. So you could write a piece of code which does reflection to extract the HttpStatus enum (either directly or through a cast). So you probably can make it work but that would require some work. That being said that change has been made 3 years ago, so that you run into it now is also a bit on your side that you took that long to upgrade. Commented Jun 23 at 5:56

1 Answer 1

0

So you could write a piece of code which does reflection to extract the HttpStatus enum (either directly or through a cast).

Will the reflection even work in this case? The classes are loaded and the methods linked before any reflection even happens? I don't think it has any chance of working?

Maybe you can try with Byte Buddy. You can intercept the loaded Spring class before your application starts and provide a new method signature there, like

ByteBuddyAgent.install();

new ByteBuddy()
    .redefine(org.springframework.http.client.ClientHttpResponse.class)
    .defineMethod("getStatusCode", HttpStatus.class, java.lang.reflect.Modifier.PUBLIC)
    .intercept(MethodDelegation.to(ClientHttpResponseShim.class))
    .make()
    .load(
        org.springframework.http.client.ClientHttpResponse.class.getClassLoader(),
        ClassReloadingStrategy.fromInstalledAgent()
    );


SpringApplication.run(Application.class);

and define the desired method in your class

public class ClientHttpResponseShim {
    public static HttpStatus getStatusCode() {
        // copy the implementation from Spring 2, it's open source
    }
}

Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.