jackson module not working in 2.2.30
I'm not using swagger-core directly but using springdoc-openapi-starter-webmvc-ui (2.8.8) and springwolf-kafka (1.13.0) and both are using swagger-core-jakarta (2.2.30).
Since using those versions, I have the following error when trying to access swagger :
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 optional type `java.util.Optional` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jdk8" to enable handling (through reference chain: io.swagger.v3.oas.models.OpenAPI["paths"]->io.swagger.v3.oas.models.Paths["/api/v1/organizations"]->io.swagger.v3.oas.models.PathItem["get"]->io.swagger.v3.oas.models.Operation["parameters"]->java.util.ArrayList[2]->io.swagger.v3.oas.models.parameters.Parameter["schema"]->io.swagger.v3.oas.models.media.JsonSchema["default"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1340)
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:770)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:184)
at io.swagger.v3.core.jackson.Schema31Serializer.serialize(Schema31Serializer.java:42)
at io.swagger.v3.core.jackson.Schema31Serializer.serialize(Schema31Serializer.java:12)
I do have the Jdk8Module :
@Bean
Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder
.modulesToInstall(new JavaTimeModule(), new Jdk8Module())
...
;
}
When forcing swagger-core-jakarta to version 2.2.29 in my pom.xml, everything works fine.
Is there something to change to have it working with 2.2.30 ? Thanks
Hi @AnneJacquet, thanks for reporting the issue! Could you please provide:
- a definition that reproduces the error
- a full stack trace
I have the same error. However while creating a minimal example, I found the problem. The reproduction can be found https://github.com/Til7701/springdoc-openapi-2.8.7-error-demo
I seems to be caused by a default value in an enum. The following OpenAPI Document repoduces the error:
openapi: 3.0.3
info:
description: TH1
title: TH1
version: 0.0.1
paths:
/converter:
post:
operationId: convertTable
parameters:
- in: query
name: mode
required: false
schema:
$ref: '#/components/schemas/dataInsertionMode'
responses:
"200":
description: OK
components:
schemas:
dataInsertionMode:
type: string
enum:
- CREATE
- EXTEND
- REPLACE
- RESTRUCTURE
default: CREATE
If you remove the default value, the error disappears. It does not matter, if the schema is defined in the request directly.
Here is the log full log output of the application:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.0)
2025-06-10T20:53:23.181+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] docOpenapiStarterWebmvcUiDemoApplication : Starting SpringdocOpenapiStarterWebmvcUiDemoApplication using Java 21.0.7 with PID 66884 (/home/tilman/IdeaProjects/springdoc-openapi-starter-webmvc-ui-demo/target/classes started by tilman in /home/tilman/IdeaProjects/springdoc-openapi-starter-webmvc-ui-demo)
2025-06-10T20:53:23.182+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] docOpenapiStarterWebmvcUiDemoApplication : No active profile set, falling back to 1 default profile: "default"
2025-06-10T20:53:23.483+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2025-06-10T20:53:23.488+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-06-10T20:53:23.488+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.41]
2025-06-10T20:53:23.501+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-06-10T20:53:23.501+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 306 ms
2025-06-10T20:53:23.676+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2025-06-10T20:53:23.679+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [ main] docOpenapiStarterWebmvcUiDemoApplication : Started SpringdocOpenapiStarterWebmvcUiDemoApplication in 0.628 seconds (process running for 0.854)
2025-06-10T20:53:26.789+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-06-10T20:53:26.789+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-06-10T20:53:26.790+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2025-06-10T20:53:26.954+02:00 INFO 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [nio-8080-exec-4] o.springdoc.api.AbstractOpenApiResource : Init duration for springdoc-openapi is: 59 ms
2025-06-10T20:53:26.964+02:00 ERROR 66884 --- [springdoc-openapi-starter-webmvc-ui-demo] [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 optional type `java.util.Optional` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jdk8" to enable handling (or disable `MapperFeature.REQUIRE_HANDLERS_FOR_JAVA8_OPTIONALS`) (through reference chain: io.swagger.v3.oas.models.OpenAPI["paths"]->io.swagger.v3.oas.models.Paths["/converter"]->io.swagger.v3.oas.models.PathItem["post"]->io.swagger.v3.oas.models.Operation["parameters"]->java.util.ArrayList[0]->io.swagger.v3.oas.models.parameters.Parameter["schema"]->io.swagger.v3.oas.models.media.JsonSchema["default"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1359) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:34) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:760) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:183) ~[jackson-databind-2.19.0.jar:2.19.0]
at io.swagger.v3.core.jackson.Schema31Serializer.serialize(Schema31Serializer.java:42) ~[swagger-core-jakarta-2.2.30.jar:2.2.30]
at io.swagger.v3.core.jackson.Schema31Serializer.serialize(Schema31Serializer.java:12) ~[swagger-core-jakarta-2.2.30.jar:2.2.30]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:760) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:183) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serializeContents(IndexedListSerializer.java:119) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:79) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer.serialize(IndexedListSerializer.java:18) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:760) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:183) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:760) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:183) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeOptionalFields(MapSerializer.java:868) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeWithoutTypeInfo(MapSerializer.java:759) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:719) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:34) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.SerializerProvider.defaultSerializeValue(SerializerProvider.java:1185) ~[jackson-databind-2.19.0.jar:2.19.0]
at io.swagger.v3.core.jackson.PathsSerializer.serialize(PathsSerializer.java:33) ~[swagger-core-jakarta-2.2.30.jar:2.2.30]
at io.swagger.v3.core.jackson.PathsSerializer.serialize(PathsSerializer.java:13) ~[swagger-core-jakarta-2.2.30.jar:2.2.30]
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:732) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:760) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:183) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:503) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:423) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1583) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1289) ~[jackson-databind-2.19.0.jar:2.19.0]
at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1140) ~[jackson-databind-2.19.0.jar:2.19.0]
at org.springdoc.api.AbstractOpenApiResource.writeJsonValue(AbstractOpenApiResource.java:1472) ~[springdoc-openapi-starter-common-2.8.9.jar:2.8.9]
at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:128) ~[springdoc-openapi-starter-webmvc-api-2.8.9.jar:2.8.9]
at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:117) ~[springdoc-openapi-starter-webmvc-api-2.8.9.jar:2.8.9]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258) ~[spring-web-6.2.7.jar:6.2.7]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191) ~[spring-web-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:986) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.7.jar:6.2.7]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.7.jar:6.2.7]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.41.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.7.jar:6.2.7]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.41.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.7.jar:6.2.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.7.jar:6.2.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.7.jar:6.2.7]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.7.jar:6.2.7]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.41.jar:10.1.41]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
Upon further analysis this seen to not be restricted to enums, but affect all data types.
I was able to fix the issue by registering the Jdk8Module with the ObjectMapper like this Json31.mapper().registerModule(new Jdk8Module());.
This is not directly a swagger-core issue. Since 2.8.7 org.springdoc:springdoc-openapi-starter-webmvc-ui passes a default value as an optional. Previously this was always null. Thus registering the module was not necessary.
Hi @djankows, sorry for the delay.
The problem indeed appears when a default value is set for an optional parameter. I admit it is a bit weird to use an optional when providing a default value. But it does work in 2.2.29.
Here is an example: demo.zip
There are two resources (one with default value and one without) and a spring profile to load only one of them. There are also two tests : only one of them pass in 2.2.30.
Changing line 26 on pom.xml to revert to 2.2.29 and both tests pass.
Interesting. If you register the module directly using my suggestion, it works. Even with 2.2.30
In your demo, you are using a Jackson2ObjectMapperBuilderCustomizer which does not seem to work.
@AnneJacquet Please provide some example with pure swagger-core involved without any external dependencies. We're currently unable to address this ticket without a reproducible test case in a clean environment.