spring-cloud / spring-cloud-stream

Framework for building Event-Driven Microservices
http://cloud.spring.io/spring-cloud-stream
Apache License 2.0
1.01k stars 613 forks source link

BindingsLifecycleController isolated ObjectMapper caused jsr310 error at /actuator/bindings endpoint for Duration of azure Service Bus bindings #2794

Closed LaurineLeNet closed 11 months ago

LaurineLeNet commented 1 year ago

Describe the issue Hi, I saw that you closed this issue : https://github.com/spring-cloud/spring-cloud-stream/issues/2272 I am using spring-cloud-stream with rabbit and azure servicebus and I am still facing that issue for servicebus bindings.

To Reproduce Steps to reproduce the behavior:

  1. Go to http://localhost:8080/actuator/bindings
  2. See error
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Duration` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.springframework.cloud.stream.binder.ExtendedProducerProperties["extension"]->com.azure.spring.cloud.stream.binder.servicebus.core.properties.ServiceBusProducerProperties["sendTimeout"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4371) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4324) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.doGetExtendedInfo(AbstractMessageChannelBinder.java:1037) ~[spring-cloud-stream-3.2.9.jar:3.2.9]
    at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder.access$100(AbstractMessageChannelBinder.java:98) ~[spring-cloud-stream-3.2.9.jar:3.2.9]
    at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder$1.getExtendedInfo(AbstractMessageChannelBinder.java:315) ~[spring-cloud-stream-3.2.9.jar:3.2.9]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4371) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4324) ~[jackson-databind-2.13.4.2.jar:2.13.4.2]
    at org.springframework.cloud.stream.binding.BindingsLifecycleController.queryStates(BindingsLifecycleController.java:142) ~[spring-cloud-stream-3.2.9.jar:3.2.9]
    at org.springframework.cloud.stream.endpoint.BindingsEndpoint.queryStates(BindingsEndpoint.java:52) ~[spring-cloud-stream-3.2.9.jar:3.2.9]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74) ~[spring-boot-actuator-2.6.13.jar:2.6.13]
    at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60) ~[spring-boot-actuator-2.6.13.jar:2.6.13]
    at org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$ServletWebOperationAdapter.handle(AbstractWebMvcEndpointHandlerMapping.java:353) ~[spring-boot-actuator-2.6.13.jar:2.6.13]
    at org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(AbstractWebMvcEndpointHandlerMapping.java:458) ~[spring-boot-actuator-2.6.13.jar:2.6.13]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.23.jar:5.3.23]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:670) ~[tomcat-embed-core-9.0.68.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.23.jar:5.3.23]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) ~[tomcat-embed-core-9.0.68.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.23.jar:5.3.23]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.23.jar:5.3.23]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) ~[spring-boot-actuator-2.6.13.jar:2.6.13]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.23.jar:5.3.23]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.23.jar:5.3.23]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1789) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.68.jar:9.0.68]
    at java.lang.Thread.run(Thread.java:834) ~[?:?]

Version of the framework Spring Cloud version : 2021.0.8 Azure service bus version : 4.10.0

olegz commented 1 year ago

Do you have the following on your classpath?

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
sobychacko commented 1 year ago

Closing due to no activity. Feel free to re-open if there is a need. Otherwise, please follow the recommendation from @olegz above.

ferblaca commented 1 year ago

@sobychacko I am comment the issue because I am having exactly the same problem but for the Eventhubs binder.

I have opened an issue here but I am not sure if the problem is with Azure but with the ObjectMapper configured for the actuator.

I have tried to configure it in several ways by extending the actuator but I still have the same problem.

To reproduce it just follow the steps in the other issue.

In the project that I give as an example in the issue, there is the dependency jackson-datatype-jsr310.

saragluna commented 12 months ago

Replied https://github.com/spring-cloud/spring-cloud-stream/issues/2272#issuecomment-1829376565.

LaurineLeNet commented 12 months ago

Sorry, I missed the comment, yes I have the dependency jackson in my pom

juliojgd commented 11 months ago

@sobychacko Any thoughts on this?

@ferblaca provided a reproducer case and he said the project has already the jackson-datatype-jsr310 dependency

sobychacko commented 11 months ago

I will take a look today. First, I want to see if this is any binder-specific or a general issue.

sobychacko commented 11 months ago

@juliojgd @ferblaca Before I proceed, did you try it with one of the out-of-the-box binders (Kafka, rabbit, or Pulsar) and see if the issue happens there? If not, could you try that first? That way, we can isolate the issue.

ferblaca commented 11 months ago

@juliojgd @ferblaca Before I proceed, did you try it with one of the out-of-the-box binders (Kafka, rabbit, or Pulsar) and see if the issue happens there? If not, could you try that first? That way, we can isolate the issue.

Hi @sobychacko, this only occurs for eventhubs binder. For example, the Kafka binder works correctly.

The problem is that the ObjectMapper configured for the actuator bindings is not capable of serializing data of type Duration used for the eventhubs bindings, even with the jackson-datatype-jsr310 dependency at the classpath.

sobychacko commented 11 months ago

As a workaround to the problem, can you create a custom ObjectMapper bean in your application as below and see if that fixes the problem?

@Bean 
public ObjectMapper objectMapper() {
  ObjectMapper objectMapper = new ObjectMapper();
  objectMapper.registerModule(new JavaTimeModule());
  return objectMapper;
}

When you provide a custom ObjectMapper bean in the application, Spring Cloud Stream will use that instead of creating one.

See this SO thread for more details. If it works, we will incorporate this change into the framework.

ferblaca commented 11 months ago

Hi @sobychacko ,

I have tested the workaround but the same problem remains.

sobychacko commented 11 months ago

@ferblaca The binder runs in a child context, and that's the reason why you can't add that bean from the application. I didn't think about that when I made the suggestion. My apologies. To look into this, I created an issue in the backlog.

In the meantime, I think I fixed the issue by directly modifying the custom ObjectMapper in AMCB. Please take a look at the commits mentioned above. The changes are in the main branch (4.1.1-SNAPSHOT) and cherry-picked to 4.0.x. You might want to upgrade your spring-cloud version, as the one you are using (2021) may already be out of the OSS support. The Spring Cloud Stream version corresponding to that spring cloud version is 3.2.x.

ferblaca commented 11 months ago

@ferblaca The binder runs in a child context, and that's the reason why you can't add that bean from the application. I didn't think about that when I made the suggestion. My apologies. To look into this, I created an issue in the backlog.

In the meantime, I think I fixed the issue by directly modifying the custom ObjectMapper in AMCB. Please take a look at the commits mentioned above. The changes are in the main branch (4.1.1-SNAPSHOT) and cherry-picked to 4.0.x. You might want to upgrade your spring-cloud version, as the one you are using (2021) may already be out of the OSS support. The Spring Cloud Stream version corresponding to that spring cloud version is 3.2.x.

@sobychacko Indeed, with SCS version 4.1.1-SNAPSHOT the problem is fixed 👍

sobychacko commented 11 months ago

Good to hear that, @ferblaca.

DouglasZillah commented 8 months ago

Good to hear that, @ferblaca.

hi, im sorry for wake this closed issue, but i have same error at ChannelsEndpoint on SCS version 4.0.4. and i guess maybe it should be fix like this?