camel-quarkus
camel-quarkus copied to clipboard
JSON/Jackson: How to configure JavaTimeModule in Quarkus Camel?
Hi,
Just started using Quarkus-Camel and am still learning how things work.
I am trying to serialize a POJO with LocalDateTime
and getting the error below.
I've done a ton of searching and found various answers for Quarkus itself here: https://quarkus.io/guides/rest-json#about-serialization
I've tried both options to provide an ObjectMapper configuration and I still get the error.
I've included the dependency as well:
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.14.0</version>
</dependency>
I also looked here: https://camel.apache.org/components/3.20.x/dataformats/jackson-dataformat.html but didn't find anything useful. I tried to set the module class parameter in application.properties
but that didn't seem to help.
camel.dataformat.jackson.auto-discover-object-mapper = true
camel.dataformat.jackson.module-class-names = com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
Any ideas how to get this to work? It will be helpful in the future should I need to add other configuration options.
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 (through reference chain: com.acme.SnapshotEntity["uploadDate"])
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1306)
at com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer.serialize(UnsupportedTypeSerializer.java:35)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
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.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1572)
at com.fasterxml.jackson.databind.ObjectWriter._writeValueAndClose(ObjectWriter.java:1273)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:1098)
at org.apache.camel.component.jackson.AbstractJacksonDataFormat.marshal(AbstractJacksonDataFormat.java:155)
at org.apache.camel.support.processor.MarshalProcessor.process(MarshalProcessor.java:64)
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:477)
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:181)
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:175)
at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:392)
at org.apache.camel.component.platform.http.vertx.VertxPlatformHttpConsumer.lambda$handleRequest$2(VertxPlatformHttpConsumer.java:193)
at io.vertx.core.impl.ContextBase.lambda$null$0(ContextBase.java:137)
at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:264)
at io.vertx.core.impl.ContextBase.lambda$executeBlocking$1(ContextBase.java:135)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Are you using the Camel REST DSL? If so, try this in your RouteBuilder
:
restConfiguration().dataFormatProperty("autoDiscoverObjectMapper", "true");
There is more information on the Camel Quarkus Jackson page. Inspired by this answer on StackOverflow, you can add the following to your RouteBuilder
if not using REST DSL:
JacksonDataFormat df = new JacksonDataFormat();
df.setModuleClassNames("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");
df.setAutoDiscoverObjectMapper(true);
Then add marshal(df)
to your route, for example:
from("direct:start").marshal(df).log("${body}");
Thanks for the info, unfortunately it still doesn't appear to be working. I am using the REST DSL and added the properties you mentioned but I still get the same error.
It appears that manually creating the JacksonDataFormat
and changing my marshaling from .marshal().json
to just .marshal(df)
as suggested by @djcoleman seems to work and the JSON is rendered.
Just wish it would work using the REST DSL.. seems like it should but I see from other Stack Overflow posts people having issues as well using the REST DSL, even with SpringBoot. There are very few posts about Camel and Quarkus. Most results are using SpringBoot.
This doesn't work..
Marshalling
from("direct:displayAll").process(this::displayAll).marshal().json();
REST DSL config
restConfiguration()
.contextPath("/archive")
.skipBindingOnErrorCode(true)
.enableCORS(true)
.dataFormatProperty("prettyPrint", "true")
.dataFormatProperty("autoDiscoverObjectMapper", "true")
.dataFormatProperty("moduleClassNames", "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");
But this does work:
REST DSL Config
restConfiguration()
.contextPath("/archive")
.enableCORS(true);
Marshalling
from("direct:displayAll").process(this::displayAll).marshal(df);
Manually Creating the JacksonDataFormat
JacksonDataFormat df = new JacksonDataFormat();
df.setModuleClassNames("com.fasterxml.jackson.datatype.jsr310.JavaTimeModule");
df.setAutoDiscoverObjectMapper(true);
I was having the same problem using Spring Boot. My issue was that I didn't have the following Maven dependency:
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jackson-starter</artifactId>
</dependency>
Without it there is no support for auto configuration. In result, the configuration
camel.dataformat.jackson.module-class-names = com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
in application.properties was ignored.