Skip to content

Conversation

@xhaggi
Copy link
Collaborator

@xhaggi xhaggi commented Sep 24, 2025

Fixes #174

@xhaggi xhaggi marked this pull request as draft September 24, 2025 08:28
@xhaggi xhaggi requested a review from wimdeblauwe September 24, 2025 08:28
@xhaggi
Copy link
Collaborator Author

xhaggi commented Sep 24, 2025

@wimdeblauwe In preparation for the upcoming release of Spring Boot 4.0. The PR is currently still a draft and may be updated once Spring Boot 4.0 is released.

@xhaggi xhaggi force-pushed the feature/spring-boot-4 branch 3 times, most recently from 25286ae to 36434fb Compare September 24, 2025 09:34
@xhaggi xhaggi added this to the 5.0.0 milestone Sep 24, 2025
@xhaggi xhaggi self-assigned this Sep 24, 2025
@xhaggi xhaggi force-pushed the feature/spring-boot-4 branch from 36434fb to 5e74c05 Compare September 24, 2025 10:18
@wimdeblauwe
Copy link
Owner

Thanks for preparing this. Looks good at first sight. I will test once we get to the first release candidate of Spring Boot 4.

@wimdeblauwe
Copy link
Owner

@xhaggi I updated the branch for Spring Boot 4.0.0-RC1. Could you fix the merge conflict? After that, I will merge and do a 5.0.0-rc.1 release so people can test with it.

@xhaggi xhaggi changed the title Upgrade to Spring Boot 4.0 Upgrade to Spring Boot 4.0-RC1 Oct 29, 2025
@xhaggi xhaggi force-pushed the feature/spring-boot-4 branch from 92ca147 to ec0f7a8 Compare October 29, 2025 08:08
@xhaggi xhaggi force-pushed the feature/spring-boot-4 branch from ec0f7a8 to 65fae30 Compare October 29, 2025 08:11
@xhaggi xhaggi marked this pull request as ready for review October 29, 2025 08:11
@xhaggi
Copy link
Collaborator Author

xhaggi commented Oct 29, 2025

@xhaggi I updated the branch for Spring Boot 4.0.0-RC1. Could you fix the merge conflict? After that, I will merge and do a 5.0.0-rc.1 release so people can test with it.

Thank you. I pulled your changes, but all tests in HtmxResponseHandlerMethodArgumentResolverIT failed, caused by REST-assured with a strange NullPointerException. I couldn't get it to work with REST-assured, so I removed that client and switched to Spring's RestTestClient. Now everything is green.

java.lang.NullPointerException
	at java.base/java.lang.Class.isAssignableFrom(Native Method)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObject(ClosureMetaClass.java:367)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:335)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:324)
	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:63)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
	at io.restassured.internal.RequestSpecificationImpl$_sendHttpRequest_closure27.doCall(RequestSpecificationImpl.groovy:1484)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)
	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:270)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1008)
	at groovy.lang.Closure.call(Closure.java:471)
	at groovy.lang.Closure.call(Closure.java:460)
	at io.restassured.internal.http.HTTPBuilder.doRequest(HTTPBuilder.java:494)
	at io.restassured.internal.http.HTTPBuilder.request(HTTPBuilder.java:453)
	at io.restassured.internal.http.HTTPBuilder$request$2.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:166)
	at io.restassured.internal.RequestSpecificationImpl.sendHttpRequest(RequestSpecificationImpl.groovy:1480)
	at io.restassured.internal.RequestSpecificationImpl.this$2$sendHttpRequest(RequestSpecificationImpl.groovy)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1235)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1008)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:793)
	at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:46)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:57)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
	at io.restassured.internal.RequestSpecificationImpl.sendRequest(RequestSpecificationImpl.groovy:1229)
	at io.restassured.internal.RequestSpecificationImpl.this$2$sendRequest(RequestSpecificationImpl.groovy)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1235)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1008)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:793)
	at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:46)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:166)
	at io.restassured.internal.filter.SendRequestFilter.filter(SendRequestFilter.groovy:30)
	at io.restassured.filter.Filter$filter.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at io.restassured.filter.Filter$filter$0.call(Unknown Source)
	at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72)
	at io.restassured.filter.time.TimingFilter.filter(TimingFilter.java:56)
	at io.restassured.filter.Filter$filter$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at io.restassured.filter.Filter$filter.call(Unknown Source)
	at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72)
	at io.restassured.filter.FilterContext$next.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
	at io.restassured.internal.filter.CsrfFilter.filter(CsrfFilter.groovy:89)
	at io.restassured.filter.Filter$filter.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:157)
	at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72)
	at io.restassured.filter.FilterContext$next.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148)
	at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1704)
	at io.restassured.internal.RequestSpecificationImpl.this$2$applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1235)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1008)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:793)
	at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:46)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:57)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203)
	at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1710)
	at io.restassured.internal.RequestSpecificationImpl.this$2$applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:338)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:274)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1235)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1008)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:793)
	at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:46)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:57)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:171)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203)
	at io.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy:172)
	at io.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy)
	at io.restassured.RestAssured.get(RestAssured.java:721)
	at io.github.wimdeblauwe.htmx.spring.boot.mvc.HtmxResponseHandlerMethodArgumentResolverIT.testPreventHistoryUpdate(HtmxResponseHandlerMethodArgumentResolverIT.java:60)

@xhaggi xhaggi changed the title Upgrade to Spring Boot 4.0-RC1 Upgrade to Spring Boot 4.0.0-RC1 Oct 29, 2025
@xhaggi xhaggi force-pushed the feature/spring-boot-4 branch from 65fae30 to 0cb7a7d Compare October 29, 2025 08:45
@xhaggi
Copy link
Collaborator Author

xhaggi commented Oct 29, 2025

@wimdeblauwe the issues with REST-assured are caused by the upgrade from Groovy 4.x to 5.x in Spring Boot 4. REST-assured relies on Groovy 4.x.

@wimdeblauwe
Copy link
Owner

I guess we can go ahead with RestTestClient instead of Rest-assured for the release now?

@xhaggi
Copy link
Collaborator Author

xhaggi commented Oct 29, 2025

Sure, I would recommend it.

@wimdeblauwe wimdeblauwe merged commit 26826e9 into wimdeblauwe:main Oct 29, 2025
2 checks passed
@xhaggi xhaggi deleted the feature/spring-boot-4 branch November 19, 2025 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incompatibility with Spring Boot 4.0.0-M1 due to missing WebMvcRegistrations class

2 participants