After update from Spring Boot 2.4.5 to Spring 2.5.0 I noticed the following exceptions in the application logs:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: org.telegram.telegrambots.meta.api.objects.Update["my_chat_member"]->org.telegram.telegrambots.meta.api.objects.ChatMemberUpdated["new_chat_member"]->org.telegram.telegrambots.meta.api.objects.ChatMember["untilDateAsInstant"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1514) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1215) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1059) ~[jackson-databind-2.12.3.jar!/:2.12.3]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.mapToTextMessage(MappingJackson2MessageConverter.java:279) ~[spring-jms-5.3.7.jar!/:5.3.7]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.toMessage(MappingJackson2MessageConverter.java:184) ~[spring-jms-5.3.7.jar!/:5.3.7]
... 37 common frames omitted
this is my pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
I reverted to Spring Boot 2.4.5 and not everything works fine. What may be wrong with Spring Boot 2.5.0 ?
UPDATED
The same issue exists in Spring Boot 2.5.1
Corresponding question on StackOverflow https://stackoverflow.com/questions/67874510/spring-boot-2-5-0-and-invaliddefinitionexception-java-8-date-time-type-java-ti
Comment From: wilkinsona
There are several people already trying to help on Stack Overflow. To avoid duplication of effort, let’s keep things in one place for now please. We can re-open this issue if a bug is identified and a change in Spring Boot is required.
Comment From: oridool
@wilkinsona - I think this is a bug.
For me, I get the same error when calling the /actuator/info endpoint :
2021-06-14 14:46:23.897 ERROR 1500 --- [io-19019-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class java.time.Instant]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.Collections$UnmodifiableMap["git"]->java.util.LinkedHashMap["commit"]->java.util.LinkedHashMap["time"])] with root cause
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.Collections$UnmodifiableMap["git"]->java.util.LinkedHashMap["commit"]->java.util.LinkedHashMap["time"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:808) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:764) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:720) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:35) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:808) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:764) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:720) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:35) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFields(MapSerializer.java:808) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:764) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:720) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:35) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1514) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1006) ~[jackson-databind-2.12.3.jar:2.12.3]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:454) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.boot.actuate.autoconfigure.web.servlet.CompositeHandlerAdapter.handle(CompositeHandlerAdapter.java:58) ~[spring-boot-actuator-autoconfigure-2.5.1.jar:2.5.1]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) ~[tomcat-embed-core-9.0.46.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.46.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:121) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:105) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183) ~[spring-security-web-5.5.0.jar:5.5.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Comment From: wilkinsona
@oridool 2.5.x should automatically register the JSR-310 module when it's available on the classpath just as 2.4.x does. Our own Actuator API documentation for the /info endpoint relies upon this and Boot's own build would fail if the endpoint didn't work.
In this case the module is one that is known to Spring Framework's Jackson2ObjectMappearBuilder which registers the module if it's on the classpath. I'd recommend debugging your application with a breakpoint in this code to determine why it's apparently not being registered in your specific situation.
Comment From: oridool
thanks @wilkinsona .
I debugged my application, and I do see the module com.fasterxml.jackson.datatype.jsr310.JavaTimeModule loaded in the registerWellKnownModulesIfAvailable method you sent.
However, I still get the same error for the /actuator/info endpoint.
On the other hand, I noticed that another application I have and also upgraded to 2.5.1 doesn't have this issue...
Unfortunately, I cannot tell at this point what is the difference between the two apps and what the root cause is. It will require additional investigation.
Comment From: EugenMayer
I confirm this issue. I think 2.5.x does show up this issue out of different issues. I think the common thing i see is, that other libraries also including js310, use 2.11 and not 2.12. Candidates
- springfox https://mvnrepository.com/artifact/io.springfox/springfox-core/2.10.5
- spring sessino mongo: https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-mongodb/2.5.0
So when using springfox < 3.0.0 (which just has been released) people run into the same issue (https://github.com/spring-projects/spring-boot/issues/26685) Same goes with session-mongo (for me).
So i assume not all projects run into this issue, only those, who use other dependencies which include an < 2.12 jackson jsr303 wich then is not compatible during runtime and cannot be used. the reason is, that scanning the classpath for the right one can lead to the first, older one.
You can check the ones you have in your classpath by running
./gradlew dependencyInsight --dependency=jsr310
Comment From: oridool
@EugenMayer , I'm using latest springfox 3.0.0 and also JSR310 version 2.12.3. But still experiencing this issue on the actuator/info endpoint. Here is the output of dependencyInsight:
C:\Dev\Java\git\server-data-ingestion-service>gradlew dependencyInsight --dependency=jsr310
> Task :dependencyInsight
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3
variant "apiElements" [
org.gradle.category = library
org.gradle.dependency.bundling = external
org.gradle.libraryelements = jar (compatible with: classes)
org.gradle.usage = java-api
org.gradle.status = release (not requested)
Requested attributes not found in the selected variant:
org.gradle.jvm.environment = standard-jvm
org.gradle.jvm.version = 11
]
Selection reasons:
- Selected by rule
- By constraint
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3
+--- com.fasterxml.jackson:jackson-bom:2.12.3
| +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.3
| | +--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| | \--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.3
| | +--- compileClasspath
| | \--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3
| | +--- org.springframework.boot:spring-boot-starter-json:2.5.1
| | | \--- org.springframework.boot:spring-boot-starter-web:2.5.1
| | | \--- compileClasspath (requested org.springframework.boot:spring-boot-starter-web)
| | \--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3 (*)
| +--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.12.3
| | +--- org.springframework.boot:spring-boot-starter-json:2.5.1 (*)
| | \--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| +--- com.fasterxml.jackson.core:jackson-databind:2.12.3
| | +--- org.springframework.boot:spring-boot-starter-json:2.5.1 (*)
| | +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.3 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3 (*)
| | +--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.12.3 (*)
| | +--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| | \--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.3 (*)
| +--- com.fasterxml.jackson.core:jackson-core:2.12.3
| | +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.3 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.12.3 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3 (*)
| | +--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.12.3 (*)
| | +--- com.fasterxml.jackson.core:jackson-databind:2.12.3 (*)
| | +--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| | \--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.3 (*)
| +--- com.fasterxml.jackson.core:jackson-annotations:2.12.3
| | +--- com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.12.3 (*)
| | +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.3 (*)
| | +--- com.fasterxml.jackson.core:jackson-databind:2.12.3 (*)
| | +--- com.fasterxml.jackson:jackson-bom:2.12.3 (*)
| | \--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.3 (*)
| \--- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.12.3 (*)
\--- org.springframework.boot:spring-boot-starter-json:2.5.1 (*)
(*) - dependencies omitted (listed previously)
A web-based, searchable dependency report is available by adding the --scan option.
BUILD SUCCESSFUL in 9s
1 actionable task: 1 executed
Comment From: EugenMayer
@oridool then there is probably even more to it. It is absolutely sure that this is related to SB 2.5 and the jaxon upgrade. Yet i assumed a version mix up alone is enough, maybe there is even more to it:
I could isolate and reproduce this issue with our project in a test. Upgrading to 2.5.1 leads to the issue, downgrading fixes it.
Comment From: oridool
Update:
I found the root cause for my issue regarding the actuator/info endpoint. :smiley:
Apparently, there was a place in the code generating a new ObjectMapper bean, and overriding the default.
In this case, the ObjectMapper did not load jsr310 and additional java.time classes converters such as Instant.
There are 2 ways to fix:
1. Remove the custom ObjectMapper bean overriding the springboot default.
2. Configure the custom bean: objectMapper.registerModule(new JavaTimeModule());
Comment From: eranf91
Update: I found the root cause for my issue regarding the
actuator/infoendpoint. Apparently, there was a place in the code generating a new ObjectMapper bean, and overriding the default. In this case, the ObjectMapper did not load jsr310 and additional java.time classes converters such asInstant. There are 2 ways to fix:
- Remove the custom ObjectMapper bean overriding the springboot default.
- Configure the custom bean:
objectMapper.registerModule(new JavaTimeModule());
regarding the first solution. can you provide the class that generate the bean and did you remove it? In addition that is just a workaround, the fix should be in spring library.
Comment From: oridool
@eranf91 , What I meant in (1) is an internal Bean of my application, not related to springboot at all, doing something like that:
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
I don't think it can be considered as as springboot issue. I do agree that something has changed in 2.5.X, since it wasn't hapenning before upgrade. But I cannot say what exactly or whether the new behavior is the expected one or not.
Comment From: wilkinsona
If you define your own ObjectMapper it is to be expected that this will switch off Spring Boot’s Jackson auto-configuration. This is to allow an application to take complete control of Jackson’s configuration. Spring Boot will use the user-defined defined ObjectMapper as-is.
Nothing should have changed in this area in Spring Boot 2.5. If someone can provide a minimal sample application that works with 2.4.x and then fails after upgrading to 2.5.x, we will happily take a look.
Comment From: oridool
@wilkinsona , I think the following small demo shows the issue: https://github.com/oridool/springboot-issue-26859
In this app, I use my own ObjectMapper (and without any customizations) . I noticed that when using 2.4.6, the info endpoint returns a numeric timestamp and not a string:
{
"git": {
"branch": "master",
"commit": {
"id": "28fdb36",
"time": {
"nano": 0,
"epochSecond": 1624189812
}
}
}
}
This can explain why the issue did not pop up before the upgrade to 2.5.1.
After upgrading to 2.5.1 , it reverts to default behavior and tries to return the time as an ISO8601 string. This is where you get the exception:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.Collections$UnmodifiableMap["git"]->java.util.LinkedHashMap["commit"]->java.util.LinkedHashMap["time"])
The default response, if I remove my ObjectMapper , looks like this:
{
"git": {
"branch": "master",
"commit": {
"id": "28fdb36",
"time": "2021-06-20T11:50:12Z"
}
}
}
Comment From: wilkinsona
Thanks for the sample. Spring Boot upgraded to Jackson 2.12 which contains this change. As a result, if an attempt is made to serialise a java.time.* type and the com.fasterxml.jackson.datatype:jackson-datatype-jsr310 module isn't on the classpath, it will now fail with an error message rather than limping along and serialising to something unexpected. The same problem occurs with Spring Boot 2.4.x if you use ext['jackson.version'] = '2.12.3' in your build.gradle to upgrade to Jackson 2.12.
Comment From: EugenMayer
@wilkinsona i'am not sure this is the only cause, but it is a good case. I guess there are cases where jsr310 was never used and yet was not leading to any issues (due to the fallback in jackson 2.11) - this changed with 2.5.x and thus errors are thrown.
It is though, not explained, why so many people are affected, IMHO.
org.springframework.boot:spring-boot-starter-web does by default include jsr310 and most of the users will use that.
So the only possible reason here then is either
1. the class path scanner is defunct (to check if the jsr310 is present and then automatically activate it)
2. or every single person having org.springframework.boot:spring-boot-starter-web included and running into that issue, has redefined the object mapper, thus removed the auto-configuration and thus has no longer jsr310 support
The question then is, how can i check 2. and how can 2. be done right? First part is for analysis, the next part is for actually fixing it.
For example i use the builder customizer
@Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer()
{
return builder -> builder.serializationInclusion(JsonInclude.Include.NON_NULL);
}
Did that already reset the autoconfiguration (i though using the builder this would not happen)
Comment From: wilkinsona
No, using a builder customizer will not disable the auto-configuration. The various options for configuration Jackson and the effect that they will have on the auto-configuration are described in the documentation that I linked to above. As described in the documentation, defining an ObjectMapper or your own Jackson2ObjectMapperBuilder will disable the auto-configuration. In these two cases, the registration of the JSR 310 module will depend upon how the ObjectMapper has been configured or the builder has been used.
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Comment From: eranf91
No, using a builder customizer will not disable the auto-configuration. The various options for configuration Jackson and the effect that they will have on the auto-configuration are described in the documentation that I linked to above. As described in the documentation, defining an
ObjectMapperor your ownJackson2ObjectMapperBuilderwill disable the auto-configuration. In these two cases, the registration of the JSR 310 module will depend upon how theObjectMapperhas been configured or the builder has been used.If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
This is a bug. upgrade springboot from 2.4.6 to: 2.5.0 breaks backward compatibility, it is no longer possible to work with pojo that contains ZonedDateTim, Instant, etc... Creating a new object mapper to 'fix' the issue is not a solution because it will cause spring to ignore the object mapper properties configured in application.yml
This issue should not be closed.
Comment From: EugenMayer
@eranf91 the point is, that yet @wilkinsona does not believe that there is a spring boot issue. I fully support what you just said.
a) The issue does not only exist when someone has a custom ObjectMapper and thus willingly has a disabled jsr310 support (this is not a spring boot issue, but rather by desing and an configuration issue).
b) The issue also exists when one does not ovveride the jackson mapper at all. What you propose is a hot fix in this cases, basically doing a) and enabling jsr310 manually, instead of spring boot doing it in the auto configuration.
Comment From: wilkinsona
@eranf91 Sorry, I'm not sure that I understand exactly what it is that you believe to be a bug. Let me try to clarify the situation and then we can take things from there.
With Spring Boot 2.5's default configuration, serialization of java.time.* types to JSON should work in 2.5 exactly as it did in 2.4 and earlier. The ObjectMapper will be automatically configured with the JSR-310 module and java.time.* types will be serialised to JSON in their expected form.
One thing that has changed here is what happens when the JSR-310 module isn't available to Jackson. Due to a change in Jackson 2.12, this will now result in a serialization failure rather than Jackson limping along and serialising to an unexpected format.
If you are using the auto-configured ObjectMapper, have the JSR-310 module on the classpath, and serialization of java.time.* types is failing with Spring Boot 2.5, please provide a minimal sample that reproduces the problem and we can take a look.
If you don't have the JSR-310 module on the classpath or have customized the ObjectMapper such that it's not registered automatically, the change in behaviour is out of Spring Boot's control. In this case, I'd recommend correcting the configuration so that Jackson can use the JSR-310 module. If that's not an option for you and you want the JSON to match was Jackson 2.11 produces without the JSR-310 module, sticking with Spring Boot 2.4.x may be your best option. As a last resort, you could also try using Spring Boot 2.5 with Jackson 2.11 but I don't believe that combination has been tested.
Comment From: wilkinsona
The issue also exists when one does not ovveride the jackson mapper at all.
@EugenMayer We've yet to see anyone in that situation. If you have a sample application that reproduces this behaviour then we're more than happy to take a look.
Comment From: EugenMayer
@wilkinsona i maybe circled in on this a little more.
When running an WebMvcTest test and using @Import({ObjectMapper.class}), then during serialization in the Controller (just a normal Pojo with an LocalDateTime) the objectMapper used in AbstractJackson2HttpMessageConverter seems to be one without any registered modules.
Removing @Import({ObjectMapper.class}) fixed this. I n my test, i do not manipulate nor use the objetMapper at all, it was just imported.
This seems to have been changed with 2.5, in spring 2.4 this was not an issue. Any clues what could be a change in 2.5 causing this?
Comment From: wilkinsona
As far as I can tell, @Import(ObjectMapper.class) has the same effect on the context's ObjectMapper in 2.4 and 2.5. In both cases an ObjectMapper in its default configuration is defined as a bean and, therefore, the auto-configured ObjectMapper backs off. This leaves the context's ObjectMapper with no registered modules.
In 2.4, this replacement of the auto-configured ObjectMapper results in a LocalDateTime being converted to the following JSON:
{
"dayOfYear":178,
"month":"JUNE",
"dayOfWeek":"SUNDAY",
"nano":345824000,
"year":2021,
"monthValue":6,
"dayOfMonth":27,
"hour":12,
"minute":7,
"second":32,
"chronology": {
"calendarType":"iso8601",
"id":"ISO"
}
}
In 2.5 it fails:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1276)
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4487)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3742)
…
This difference in Jackson's behaviour is due to the aforelinked change in Jackson 2.12. They decided that it was better to fail fast recommending the use of jackson-datatype-jsr310 than to limp along and produce the JSON above. FWIW, I think that was a good change to make as the JSON is very unlikely to be what you want as it's leaking details of LocalDateTime rather being in a standard timestamp format that can be easily consumed by clients.
Comment From: EugenMayer
@wilkinsona i understardn your thesis. It is basically, that the ObjectMapper was not supporting jsr310 in both, 2.4 and 2.5 when using @Import({ObjectMapper.class}) - just in 2.5 the missing support and the serialization of such a type leads to an exception (due to jackson 2.12), but in spring boot 2.4 it does fallback to a different representation without an exception (and went undetected).
To me, this sounds fairly realistic.
One thing i do not understand though, why does @Import({ObjectMapper.class}) lead to the auto-configured ObjectMapper to be disabled? I was expecting to basically import what there is "auto configured" - but this is not the case? This means there are 2 beans in SB for the ObjectMapper, one is just an empty Bean without configuration - and if that one has not been initialized the auto-configured bean is loaded? Yet never stepped into such an case of configuration, kind of new too me how this is implemented
Comment From: wilkinsona
@Import registers a new component as a bean in the application context. That's typically a @Configuration class, but can also be a regular component. In this case, it means that your class with @Import(ObjectMapper.class) has defined an ObjectMapper bean. In response to this user-defined ObjectMapper, Spring Boot's Jackson auto-configuration backs off and allows you to take complete control over Jackson's configuration. This is standard behaviour for Spring Boot's auto-configuration and @ConditionalOnMissing bean with the Jackson auto-configuration uses.
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Comment From: eranf91
The issue does not relate to the import annotation. I am attaching a tar file contains a project with 2 modules, the only different is the springboot version. each module contains a webmvc test 1. springboot version2.5.2. 2. springboot version 2.4.5
- mvn clean install -> failure
- mvn clean install success
Comment From: wilkinsona
@eranf91 You are creating the ObjectMapper instance yourself in your test which means it is in its default configuration and does not have the JSR-310 module registered. As describe above, this fails with Jackson 2.12 due to this change in Jackson. Rather than creating your own ObjectMapper, you can use the auto-configured instance by injecting it into your test:
@WebMvcTest(controllers = {SimpleController.class})
class SimpleControllerTest {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@SneakyThrows
@Test
void test(){
mockMvc.perform(post("/simple")
.contentType(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(SimpleRequest.builder()
.time(now())
.build())))
.andExpect(status().isOk());
}
}
FWIW, your jackson-no-issue test is quite different to the jackson-issue test as it isn't serialising a SimpleRequest instance:
@WebMvcTest(controllers = {SimpleController.class})
@FieldDefaults(level = PRIVATE)
@Slf4j
class SimpleControllerTest {
@Autowired
MockMvc mockMvc;
@SneakyThrows
@Test
void test() {
ObjectMapper objectMapper = new ObjectMapper();
String body = objectMapper.writeValueAsString(Map.of("time", now().toEpochSecond()));
log.info("Send: {}", body);
mockMvc.perform(post("/simple")
.contentType(APPLICATION_JSON)
.content(body))
.andExpect(status().isOk());
}
}
Due to this, it works with either Jackson 2.11 (Spring Boot 2.4) or Jackson 2.12 (Spring Boot 2.5).
Comment From: eranf91
@wilkinsona You are right, I did not produce the defect correctly. In the example I provided a web mvc test that used the auto configured object mapper to parse the object and this is working as expected.
but in my case I have a service: 'simpleService' with auto configured object mapper in service: 'simpleService' I have a method get, the method is using the object mapper to convert a object to hash map. I also have a DataJpaTest the test is auto-wiring the simple service and call the get method.
I have fixed the example to reproduce the issue as explained above.
Comment From: wilkinsona
@eranf91 You are using @Import in your test in the same way that @EugenMayer was above. As I've already explained, this results in the auto-configured ObjectMapper being replaced by an ObjectMapper in its default configuration.
Comment From: eranf91
@eranf91 You are using
@Importin your test in the same way that @EugenMayer was above. As I've already explained, this results in the auto-configuredObjectMapperbeing replaced by anObjectMapperin its default configuration.
I understand now it is not working. but that's raise the question why in version 2.4.5 it works and version 2.5.0 not working. According to explained beaver 2.4.5 should fail as well
Comment From: wilkinsona
According to explained beaver 2.4.5 should fail as well
No it shouldn't. Please see this earlier comment for details of how Jackson 2.11 behaves. Note that serialization to JSON doesn't fail but it isn't in the expected format.
@DataJpaTest doesn't include any Jackson-related auto-configuration. If you want to use the auto-configured ObjectMapper in a Data JPA test, you should import the auto-configuration:
@ImportAutoConfiguration(JacksonAutoConfiguration.class)
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Comment From: 7--
My code creates a lot of ObjectMappers but what does that have to do with the /info endpoint? I didn't write any code for /info and the stack trace only shows Spring and Jackson code. Sounds like it's just an issue with spring. How could I fix that from my side.
I'm not getting errors from any of my ObjectMappers. I only get error on /info. When I ran junit on stackoverflow it failed, probably depends how ObjectMapper is used.
Comment From: wilkinsona
My code creates a lot of ObjectMappers but what does that have to do with the /info endpoint?
If one of those ObjectMapper instances that you create is defined as a @Bean, it will be used by all of the Actuator's endpoints to serialize their responses to json. We may move to a separate Actuator-specific ObjectMapper in the future, but this is the way things work at the moment.
How could I fix that from my side
Ensure that your ObjectMapper @Bean (or the one that is @Primary if you have defined more than one) has the JSR-310 module registered.
Comment From: ShivShivChaturvedi
I confirm this issue. I think 2.5.x does show up this issue out of different issues. I think the common thing i see is, that other libraries also including js310, use 2.11 and not 2.12. Candidates
- springfox https://mvnrepository.com/artifact/io.springfox/springfox-core/2.10.5
- spring sessino mongo: https://mvnrepository.com/artifact/org.springframework.session/spring-session-data-mongodb/2.5.0
So when using springfox < 3.0.0 (which just has been released) people run into the same issue (#26685) Same goes with session-mongo (for me).
So i assume not all projects run into this issue, only those, who use other dependencies which include an < 2.12 jackson jsr303 wich then is not compatible during runtime and cannot be used. the reason is, that scanning the classpath for the right one can lead to the first, older one.
You can check the ones you have in your classpath by running
./gradlew dependencyInsight --dependency=jsr310
This information is explaining the reason. But could not found any fix for this issue.
I am in the process of migration to 2.5.5 My Entity object has localDateTime object needs to be used for repository activities by default jackson 12 version is included. Now, how to fix the issue of InvalidDefinitionException ??
Comment From: jorgebo10
Hi i was able to reproduce the issue while moving from 2.4.5 to 2.5.6. See attached test. Any suggested on how to fix it? ct-core-events.zip
Unzip and run with: ./gradlew clean build test
Comment From: wilkinsona
@jorgebo10 The test fails with the following:
Caused by: com.amazonaws.SdkClientException: Unable to load region information from any provider in the chain
Comment From: jorgebo10
Sorry. I was able to make it work. It seems that the problem was related to SNS Autoconfiguration creating a default MappingJackson2MessageConverter that does not take into account the global ObjectMapper. I have updated the example. If you uncomment the code and comment the one that is currently uncommented the test works.
Comment From: wilkinsona
It seems that the problem was related to SNS Autoconfiguration creating a default MappingJackson2MessageConverter that does not take into account the global ObjectMapper
Thanks for letting us know. As described in previous comments, the problem can be caused by anything that results in an ObjectMapper being used that doesn't have the JSR-310 module registered. A MappingJackson2MessageConverter that doesn't use the auto-configured ObjectMapper is one such cause.
Comment From: 7--
My code creates a lot of ObjectMappers but what does that have to do with the /info endpoint?
If one of those
ObjectMapperinstances that you create is defined as a@Bean, it will be used by all of the Actuator's endpoints to serialize their responses to json. We may move to a separate Actuator-specificObjectMapperin the future, but this is the way things work at the moment.How could I fix that from my side
Ensure that your
ObjectMapper@Bean(or the one that is@Primaryif you have defined more than one) has the JSR-310 module registered.
This didn't work. I defined a @Primary ObjectMapper like below and Spring still throws error on /info endpoint. Can you post a fix for this issue or reopen the ticket. Only my dependencies declare an ObjectMapper. So either Spring or my dependencies need to make a fix there's nothing I can do from my end.
...
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@Primary
public ObjectMapper primaryObjectMapper(){
ObjectMapper o = new ObjectMapper();
o.configure(DeserialiszationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
o.registerModule(new JavaTimeModule());
return o;
}
}
This error is coming from Spring code. Why is this ticket not marked as a bug?
Comment From: philwebb
@7-- I create a new project using Spring Boot 2.6.2 from start.spring.io and added the following code:
@SpringBootApplication
public class DemoApplication {
@Bean
@Primary
public ObjectMapper primaryObjectMapper() {
return JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.addModule(new JavaTimeModule()).build();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
With an application.properties of:
management.endpoints.web.exposure.include=*
management.endpoint.info.enabled=true
info.test=hello
I don't get any failure so there must be something else going on with your application. Please can you provide a sample that shows the problem you're facing.
Comment From: 7--
@7-- I create a new project using Spring Boot 2.6.2 from start.spring.io and added the following code:
```java @SpringBootApplication public class DemoApplication {
@Bean @Primary public ObjectMapper primaryObjectMapper() { return JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .addModule(new JavaTimeModule()).build(); }
public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }
} ```
With an
application.propertiesof:
ini management.endpoints.web.exposure.include=* management.endpoint.info.enabled=true info.test=helloI don't get any failure so there must be something else going on with your application. Please can you provide a sample that shows the problem you're facing.
The dependecy I'm using updated thier ObjectMapper so I don't think I'll have the issue anymore, but thank you for posting I'll try again if I see the error again.
Comment From: Verdoso
Hi there, I just came across this in an application (Spring Boot 2.6.3) where no ObjectMapper is directly created and it is not imported. I verified and all jackson related versions are 2.13.1. I'll see if I can reproduce it in a portable version, this one is not OS. The only way I could fix it was by creating my own ObjectMapper bean and registering the module myself.
It's weird because I have other applications that are basically done using the same versions and it is the only one so far with this issue. There must be some other library doing something with ObjectMapper...
Comment From: Verdoso
Found it! A third party library was messing with the mapper in its configuration.
Comment From: lpicchi
Found it! A third party library was messing with the mapper in its configuration.
Having same problem, can you share which lib was messing up with ObjectMapper?
Comment From: Verdoso
It wasn't a well known open source library but a custom library created by another internal group. It's kind of hard to debug as Configuration magic can happen in many places.
Comment From: thefat32
Indeed, my project is not big and I'm having trouble finding why this is happening. I will try to tailor it down to the cause and share it. Thanks for your answer anyways!
Comment From: mmighri
in my case the problem was another third party library that instantiate his own ObjectMapper.
Comment From: frankiee12a9
@mmighri same as mine. Still don't know why. However, removed the bean of ObjectMapper, and it works.
Comment From: AdiedX
@7-- I create a new project using Spring Boot 2.6.2 from start.spring.io and added the following code:
```java @SpringBootApplication public class DemoApplication {
@Bean @Primary public ObjectMapper primaryObjectMapper() { return JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .addModule(new JavaTimeModule()).build(); }
public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }
} ```
With an
application.propertiesof:
ini management.endpoints.web.exposure.include=* management.endpoint.info.enabled=true info.test=helloI don't get any failure so there must be something else going on with your application. Please can you provide a sample that shows the problem you're facing.
Creating a primary object mapper worked for me. I didn't need the application.properties changes or the jsr310 package. Just make sure to do the obvious: use the object mapper with dependency injection:
@Autowired
private ObjectMapper primaryObjectMapper;
Comment From: AdiedX
You can also do the following:
Include the JSR310 module:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.0'
And register the Java time module the following way:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
Comment From: mmighri
@AdiedX thank you it works for me now. finally the problem was because i used many instances of ObjectMapper. it was not a problem with the JavTimeModule itself
Comment From: ren-liang
You can try adding @EnableWebMvc annotation to the main class
Comment From: zlsq
You can try adding @EnableWebMvc annotation to the main class您可以尝试在主类中添加@EnableWebMvc注释
wow thanks! solved my problem. and why it works?
Comment From: yuriuss
You can also do the following:
Include the JSR310 module:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.11.0'And register the Java time module the following way:
java ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule());
It's good solution. Thanks!
Comment From: philwebb
@vhscom Could you please put together a sample project that replicates your issue and post a link here. If it turns out we have a bug we'll open a new issue.
Comment From: vhscom
All good, Phil. I need to do a little more digging first and will send up an issue with a minimal repro if I really start tearing my hair out. So far I haven't found a way past this issue in my codebase even after following the advice in the backtrace:
Could not write JSON: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
I've added both that and, grasping for straws, Spring Boot Starter JSON to no avail. Let's see...
Comment From: bclozel
@vhscom It looks like your application has defined its own ObjectMapper bean and is not using the auto-configured one. This case has been described multiple times in this thread.
Comment From: vhscom
@vhscom It looks like your application has defined its own
ObjectMapperbean and is not using the auto-configured one. This case has been described multiple times in this thread.
Thanks @bclozel you're 100% correct. I've gone back and thumbs-upped that ref from 2021. Pulling my last code snippet as it may be misleading for others. Much appreciated!!
Comment From: bclozel
@vhscom Thanks for letting us know! In your case, maybe replacing the manual ObjectMapper definition with some properties in application.properties or a Jackson2ObjectMapperBuilderCustomizer bean would make your customizations on Jackson without undoing the auto-configuration.