Spring Data Rest 2.0.0.RELEASE Breaks Code Working Previously With RC1
Asked Answered
L

1

3

I have a project which is utllizing Spring Data Rest. I originally had version 2.0.0.BUILD-SNAPSHOT in my pom.xml, but during my last update the code broke and began throwing the following IllegalStateException when accessing most endpoints:

java.lang.IllegalStateException: No suitable resolver for argument [0]
[type=org.springframework.http.converter.HttpMessageNotReadableException]
HandlerMethod details: 
Controller [org.springframework.data.rest.webmvc.RepositoryEntityController]
Method [public org.springframework.http.ResponseEntity<org.springframework.data.rest.webmvc.support.ExceptionMessage> org.springframework.data.rest.webmvc.AbstractRepositoryRestController.handleNotReadable(org.springframework.http.converter.HttpMessageNotReadableException)]

at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:169)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:340)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:138)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:75)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1164)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1005)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilter(WebRequestTraceFilter.java:114)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextFilterConfiguration$1.doFilterInternal(EndpointWebMvcAutoConfiguration.java:128)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:201)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration$MetricsFilter.doFilterInternal(MetricFilterAutoConfiguration.java:84)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:680)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

Then the following error is logged by Spring Boot Actuate:

2014-02-28 07:58:54.986 ERROR 9232 --- [nio-8080-exec-6] o.s.b.actuate.web.BasicErrorController : org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException) (through reference chain: org.springframework.hateoas.Resource["content"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: org.springframework.hateoas.Resource["content"])

If I modify my pom.xml to use SDR version 2.0.0.RC1 then everything seems to work as expected.

I'd like to get this resolved since there are bug fixes included in the latest release which I have been waiting on, but this issue is preventing me from upgrading. Is there a workaround? It's difficult from the stacktrace to even tell where the issue is, but based on timing alone I think this issue may be related to this commit:

https://github.com/spring-projects/spring-data-rest/commit/3e5914d84f9708015b36a8840a25e9fa10a7f6ae

As requested the dependencies are:

spring-data-rest-webmvc 2.0.0.RELEASE

spring-boot-starter-web 1.0.0.BUILD-SNAPSHOT

spring-boot-starter-actuator 1.0.0.BUILD-SNAPSHOT

spring-boot-starter-security 1.0.0.BUILD-SNAPSHOT

spring-boot-starter-data-jpa 1.0.0.BUILD-SNAPSHOT

spring-boot-starter-shell-remote 1.0.0.BUILD-SNAPSHOT

spring-boot-starter-tomcat [provided]

spring-boot-starter-test 1.0.0.BUILD-SNAPSHOT

spring-security-ldap 3.2.0.RELEASE

It appeared that spring-boot-starter-jpa was providing an older version of spring-data-commons than spring-data-rest-webmvc, but reordering the dependencies to pull 1.7.0.RELASE instead of 1.7.0.RC1 doesn't seem to have had an effect.

Lurlenelurline answered 28/2, 2014 at 14:19 Comment(4)
Post your dependencies. Looks like you are mixing incompatible versions of jars.Gastronomy
I agree with Marten, it's probably just your transitive dependencies. If you switch to a SNAPSHOT of Spring Boot there is a spring-boot-starter-data-rest (from Marten) that we just added. I can see from the Data Rest sample that spring-data-commons:1.7.0.RELEASE is included for instance, so I think that might fix things.Oarlock
pastebin of dependency tree here: pastebin.com/raw.php?i=KfqXQgZQ This is the tree using SDR 2.0.0.RELEASE and Boot 1.0.0.RC3. I still can't seem to figure out what could be causing this error...Lurlenelurline
After looking at this all day I'm almost convinced that this is a bug in SDR. Jackson ends up throwing the exception and the dependent version (2.3.1) is the same in both the RC1 and RELEASE versions of SDR. The only thing that could've changed would have been the Resource being passed in for serialization. As I also mentioned 2 out of 9 endpoints (when using SDR 2.0.0.RELEASE) return paged results correctly. The other 7 throw this exception, but I cannot for the life of me figure out what the commonality is.Lurlenelurline
S
2

This is a known and fixed bug basically masking a Jackson serialization problem on our side. The fix is already in and will be in the 2.0.1 release as well as 2.1 M1.

Feel free to give the snapshots a try.

Straitjacket answered 1/3, 2014 at 7:20 Comment(3)
2.1.0-BUILD-SNAPSHOT is working after adding in @JsonIgnore annotations on some relationships. However, I am now having trouble posting an entity w/ required associated properties. I get: No suitable HttpMessageConverter found to read request body into object of type class com.renovo.schedulerapi.domain.Reservation from request with content type of application/json! How are the links supposed to be included in the json during the post? Something like this was working before: "requestor":{"rel":"users.User","href":"localhost:8080/users/5"},Lurlenelurline
As of 2.0, only submit the URI for the association: { "requestor" : "…/users/5" } should do the trick.Straitjacket
Still can't seem to get it working. Created a new question here since it's more specific: #22152072Lurlenelurline

© 2022 - 2024 — McMap. All rights reserved.