Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 date/time type java.time.Instant not supported by default #26859

Closed
Artgit opened this issue Jun 11, 2021 · 57 comments
Labels
for: stackoverflow A question that's better suited to stackoverflow.com status: invalid An issue that we don't feel is valid

Comments

@Artgit
Copy link

Artgit commented Jun 11, 2021

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

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 11, 2021
@wilkinsona
Copy link
Member

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.

@wilkinsona wilkinsona added for: stackoverflow A question that's better suited to stackoverflow.com status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 11, 2021
@oridool
Copy link

oridool commented Jun 14, 2021

@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]

@wilkinsona
Copy link
Member

wilkinsona commented Jun 14, 2021

@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.

@oridool
Copy link

oridool commented Jun 14, 2021

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.

@EugenMayer
Copy link

EugenMayer commented Jun 18, 2021

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

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

@oridool
Copy link

oridool commented Jun 19, 2021

@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

@EugenMayer
Copy link

@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.

@oridool
Copy link

oridool commented Jun 19, 2021

Update:
I found the root cause for my issue regarding the actuator/info endpoint. 😃
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());

@eranf91
Copy link

eranf91 commented Jun 20, 2021

Update:
I found the root cause for my issue regarding the actuator/info endpoint.
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());

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.

@oridool
Copy link

oridool commented Jun 20, 2021

@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.

@wilkinsona
Copy link
Member

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.

@oridool
Copy link

oridool commented Jun 20, 2021

@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"
        }
    }
}

@wilkinsona
Copy link
Member

wilkinsona commented Jun 20, 2021

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.

@EugenMayer
Copy link

EugenMayer commented Jun 21, 2021

@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)

@wilkinsona
Copy link
Member

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.

@eranf91
Copy link

eranf91 commented Jun 21, 2021

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.

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.

@EugenMayer
Copy link

@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.

@wilkinsona
Copy link
Member

@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.

@wilkinsona
Copy link
Member

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.

@EugenMayer
Copy link

EugenMayer commented Jun 26, 2021

@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?

@wilkinsona
Copy link
Member

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.

@EugenMayer
Copy link

EugenMayer commented Jun 27, 2021

@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

@wilkinsona
Copy link
Member

@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.

@eranf91
Copy link

eranf91 commented Jun 28, 2021

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

  1. mvn clean install -> failure
  2. mvn clean install success

springboot-isseus.tar.gz

@wilkinsona
Copy link
Member

@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).

@7--
Copy link

7-- commented Oct 2, 2021

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.

@wilkinsona
Copy link
Member

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.

@ShivShivChaturvedi
Copy link

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

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 ??

@jorgebo10
Copy link

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

@wilkinsona
Copy link
Member

@jorgebo10 The test fails with the following:

Caused by: com.amazonaws.SdkClientException: Unable to load region information from any provider in the chain

@jorgebo10
Copy link

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.

ct-core-events.zip

@wilkinsona
Copy link
Member

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.

@7--
Copy link

7-- commented Dec 23, 2021

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.

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?

@philwebb
Copy link
Member

philwebb commented Jan 7, 2022

@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.

@7--
Copy link

7-- commented Jan 7, 2022

@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.

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.

@Verdoso
Copy link

Verdoso commented Feb 21, 2022

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...

@Verdoso
Copy link

Verdoso commented Feb 22, 2022

Found it! A third party library was messing with the mapper in its configuration.

@lpicchi
Copy link

lpicchi commented Oct 27, 2022

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?

@Verdoso
Copy link

Verdoso commented Nov 2, 2022

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.

@thefat32
Copy link

thefat32 commented Nov 2, 2022

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!

@mmighri
Copy link

mmighri commented Dec 26, 2022

in my case the problem was another third party library that instantiate his own ObjectMapper.

@frankiee12a9
Copy link

@mmighri same as mine. Still don't know why. However, removed the bean of ObjectMapper, and it works.

@AdiedX
Copy link

AdiedX commented Feb 19, 2023

@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.

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;

@AdiedX
Copy link

AdiedX commented Feb 19, 2023

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());

@mmighri
Copy link

mmighri commented Feb 19, 2023

@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

@ren-liang
Copy link

You can try adding @EnableWebMvc annotation to the main class

@zlsq
Copy link

zlsq commented Oct 18, 2023

You can try adding @EnableWebMvc annotation to the main class您可以尝试在主类中添加@EnableWebMvc注释

wow thanks! solved my problem. and why it works?

@yuriuss
Copy link

yuriuss commented Nov 30, 2023

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());

It's good solution. Thanks!

@philwebb
Copy link
Member

@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.

@vhscom
Copy link

vhscom commented Aug 21, 2024

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...

@bclozel
Copy link
Member

bclozel commented Aug 22, 2024

@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.

@vhscom
Copy link

vhscom commented Aug 22, 2024

@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.

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!!

@bclozel
Copy link
Member

bclozel commented Aug 22, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: stackoverflow A question that's better suited to stackoverflow.com status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests