Reputation: 891
I recently upgraded my Spring Boot application from version 3.4.0 to 3.4.1 and encountered an issue with Spring Data REST.
In version 3.4.0 (and all previous 3.x versions), the following configuration worked as expected:
spring.data.rest.base-path=/api
With this property set, I could successfully access my REST API resources via: http://localhost:8080/api/todos
However, after upgrading to Spring Boot 3.4.1, this configuration no longer works. Attempting to access the API endpoints with the configuration spring.data.rest.base-path
results in a 404 Not Found error. I suspect there might be a conflict with the Spring Boot DevTools dependency, as removing it resolves the issue.
Environment
How To Reproduce
I have a reproducible example at this repo
mvn clean spring-boot:run
curl -v http://localhost:8080/api/todos
You will receive a 404 Not Found error.
Observed Behavior
Accessing the API endpoint results in a Whitelabel Error Page:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
There was an unexpected error (type=Not Found, status=404).
No static resource api/todos.
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource api/todos.
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:585)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:52)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
at java.base/java.lang.Thread.run(Thread.java:1575)
Expected Behavior:
I expected a successful response with 200 status code and following output:
{
"_embedded": {
"todos": []
},
"_links": {
"self": {
"href": "http://localhost:8080/api/todos?page=0&size=20"
},
"profile": {
"href": "http://localhost:8080/api/profile/todos"
}
},
"page": {
"size": 20,
"totalElements": 0,
"totalPages": 0,
"number": 0
}
}
Possible Conflict with DevTools:
After troubleshooting, I discovered that removing the Spring Boot DevTools dependency resolves the issue. For example:
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
-->
Once the DevTools dependency is removed, the application runs successfully. You are able to access the endpoint http://localhost:8080/api/todos and it returns a 200 response as expected along with the following content.
{
"_embedded": {
"todos": []
},
"_links": {
"self": {
"href": "http://localhost:8080/api/todos?page=0&size=20"
},
"profile": {
"href": "http://localhost:8080/api/profile/todos"
}
},
"page": {
"size": 20,
"totalElements": 0,
"totalPages": 0,
"number": 0
}
}
What I’ve Tried
spring.data.rest.base-path
property but couldn’t find anything relevant.Questions
spring.data.rest.base-path
property changed in Spring Boot 3.4.1?Any guidance or workarounds would be greatly appreciated!
I also filed this as a bug with the Spring Boot project team.
Upvotes: 1
Views: 769
Reputation: 1
Yes, the issue appears to be a bug introduced in latest spring 3.4.1 released on 19th Dec 2024. Two possible workarounds are,
(Ref: https://www.udemy.com/course/spring-hibernate-tutorial/learn/lecture/36836512#questions/22798063)
Upvotes: 0