Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recipes to upgrade to Spring Boot 3.4 #642

Open
2 of 8 tasks
timtebeek opened this issue Nov 28, 2024 · 13 comments
Open
2 of 8 tasks

Recipes to upgrade to Spring Boot 3.4 #642

timtebeek opened this issue Nov 28, 2024 · 13 comments
Labels
boot-3.4 recipe Recipe requested

Comments

@timtebeek
Copy link
Contributor

timtebeek commented Nov 28, 2024

We want to support folks looking to migrate to Spring Boot 3.4

Here's an incomplete list of tasks related to this migration

  • Recipes to upgrade to Spring Framework 6.2 #627
  • Generate Spring Boot property migration recipes (runs on a schedule)
  • WebJars Locator Integration: instead of org.webjars:webjars-locator-core depend on org.webjars:webjars-locator-lite
  • OkHttp Dependency Management Removed
    • verify change parent already adds the explicit version where that was managed before
  • Netty in Native Image: upgrade the GraalVM reachability metadata version
  • Add ReplaceMockBeanAndSpyBean Recipe #646
  • Deprecations in RestTemplateBuilder
    • requestFactory -> requestFactoryBuilder
    • setConnectTimeout ->connectTimeout
    • setReadTimeout -> readTimeout
    • setSslBundle -> sslBundle
  • Bean configuration properties need to be marked with @Valid where previously only @Validated was required see
@timtebeek timtebeek added the recipe Recipe requested label Nov 28, 2024
@timtebeek timtebeek moved this to Recipes Wanted in OpenRewrite Nov 28, 2024
@123Haynes
Copy link
Contributor

123Haynes commented Dec 5, 2024

I created a recipe for the last point (replacing @MockBean and @SpyBean) which I can contribute. 😃
Probably needs some cleanup though since this is my first recipe. I'll try to create a pr for it tomorrow after work.

@123Haynes
Copy link
Contributor

I also found one more point for the list. The RestTemplateBuilder has several deprecations with Spring Boot 3.4
https://docs.spring.io/spring-boot/api/java/org/springframework/boot/web/client/RestTemplateBuilder.html

requestFactory -> requestFactoryBuilder
setConnectTimeout ->connectTimeout
setReadTimeout -> readTimeout
setSslBundle -> sslBundle

@timtebeek Can you add that as one TODO item on the list so it isn't forgotten? 😃

@123Haynes
Copy link
Contributor

I'm thinking about trying to tackle the migration for RestTemplateBuilder.
Seems mostly straightforward apart from one method.
requestFactory -> requestFactoryBuilder

This would require code like this:

class BuilderClass {
  void buildermethod() {
    RestTemplateBuilder builder = new RestTemplateBuilder();
    builder.requestFactory(requestFactory).build();
  }
}

to look like this after the migration:

import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;

class BuilderClass {
  void buildermethod() {
    RestTemplateBuilder builder = new RestTemplateBuilder();
    builder.requestFactory(ClientHttpRequestFactoryBuilder.of(requestFactory)).build();
  }
}

Is something like that possible with yaml recipes?

I'm also struggeling a bit to get the test cases to run for this because the method parameter of setConnectTimeout is java.time.Duration
I get:

LST contains missing or invalid type information
Identifier->MethodInvocation->MethodInvocation->Block->MethodDeclaration->Block->ClassDeclaration->CompilationUnit
/(Identifier type is missing or malformed)>/Duration

I know that I need to add it to the classpath somehow, but how do i do that for java internal classes like Duration?
Currently my method for loading the recipe looks like this:

 @Override
    public void defaults(RecipeSpec spec) {
        spec.recipeFromResources("org.openrewrite.java.boot3.resttemplatebuilder")
          .parser(JavaParser.fromJavaVersion()
            .classpathFromResources(new InMemoryExecutionContext(),
              "spring-boot"));
    }

@123Haynes 123Haynes mentioned this issue Dec 6, 2024
3 tasks
@timtebeek
Copy link
Contributor Author

Thanks for the continued work here @123Haynes ! For the requestFactory change I think a Refaster style recipe would be most appropriate, which will require the 3.4 on the classpath. similarly for the setConnectTimeout change I think the missing types are due to having 3.3 on the classpath still. We'll need to work out if the existing recipes can coexist, but I don't expect any issues just yet.

@123Haynes
Copy link
Contributor

Alright. I'll take a look at how refaster recipes work then. 😃

I don't think the missing types are related to 3.3 still on the classpath. The issue is that the method parameter of setConnectTimeout is java.time.Duration which is not recognized. But this is part of the jdk so spring dependencies should not matter at all.
The test works fine if I just use something like 10 as the method argument instead of Duration.ofSeconds(10)
The method gets renamed just fine then, but technically the test would not represent the exact code.

@albrechtflo-hg
Copy link

Please note: The MockBean replacment recipe (#646) won't work correctly in all cases, as the new annotation is no full drop-in replacement (see spring-projects/spring-framework#33934). E.g. on types or in TestConfiguration classes, the new annotation has no effect (or even cannot be used). The workarounds are not trivial...

@albrechtflo-hg
Copy link

Also, please check if GoogleCloudPlatform/spring-cloud-gcp#3391 has to be considered. sm:// references in Spring properties (for Google Secret Manager) no longer work and have to be escaped in an ugly way.

@123Haynes
Copy link
Contributor

123Haynes commented Dec 10, 2024

Please note: The MockBean replacment recipe (#646) won't work correctly in all cases, as the new annotation is no full drop-in replacement (see spring-projects/spring-framework#33934). E.g. on types or in TestConfiguration classes, the new annotation has no effect (or even cannot be used). The workarounds are not trivial...

Thanks for the comment. I was not aware of that since i don't use @MockBean like that in my projects.
Given this reply spring-projects/spring-framework#33934 (comment) and that there is currently no clear upgrade path povided by the spring team for some specific use cases I wonder if we should just ignore this for the spring boot 3.4 recipe and take a look again later. The annotations will be around until spring boot 3.6.

Alternatively we could change the recipe so it only replaces the annotation for known, working usecases and ignores everything in @Configuration classes for example. But I don't think having a mix of @MockBean and @MockitoBean would be something that people want.

I'd probably still keep the current recipe in since even in it's current form the recipe can be used by many people and we can iterate on it.

@nmck257
Copy link
Collaborator

nmck257 commented Dec 10, 2024

For MockitoBean support at the type level, this thread is the "live" one: spring-projects/spring-framework#33925

Looking at the broader list of open tasks, I think a recipe to transform type-level usage of MockBean to a field level MockitoBean pattern would be a low priority, unless some contributor has a specific pressing use case for it

@albrechtflo-hg
Copy link

Alternatively we could change the recipe so it only replaces the annotation for known, working usecases and ignores everything in @Configuration classes for example. But I don't think having a mix of @MockBean and @MockitoBean would be something that people want.

TBH, that is exactly what I now have done in our project, but I was not quite happy about it. Maybe it is really the best to not to do that replacement at all, but that also could cause deprecation warnings (or even errors, depending on compiler settings) for many...

Keeping the old annotation would also "solve" the lacking support for the type-level usage of the new annotation.

@123Haynes
Copy link
Contributor

TBH, that is exactly what I now have done in our project, but I was not quite happy about it. Maybe it is really the best to not to do that replacement at all, but that also could cause deprecation warnings (or even errors, depending on compiler settings) for many...

For the warnings the spring boot team provided a workaround to silence those: spring-projects/spring-framework#33934 (comment)
But I don't think this should be included in a recipe because it just hides the warning and people wouldn't know they still have something to do.

@A1016375
Copy link

A1016375 commented Jan 2, 2025

Hi guys, It's almost 1 month that SpringBoot3.4 is released and we know that we have very limited contributor with there great effots, But still any tentative timeline to release 3.4 final recipe so base on that we can plan the work of upgrade to 3.4.
Thanks.

@timtebeek
Copy link
Contributor Author

Hi @A1016375 ; There is no set timeline; any help developing these recipes is welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
boot-3.4 recipe Recipe requested
Projects
Status: Recipes Wanted
Development

No branches or pull requests

5 participants