How to resolve the JodaTime serailization issue with kafka?

72 views Asked by At

I have two microservice, say service1 and service 2, now when i am sending the dto to kafka topic and want it to be consumed in both service which is happening as expected, but the problem is when it's getting consumed to service1 it has dto defined in application level with property DateTime Laucnhdate whereas the service 2 having dto defined with LocalDateTime Laucnhdate , so in the service 2 it's getting consumed and working fine, whereas in service 1, it's throwing the error given below

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.joda.time.Chronology` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
    at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1234) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at org.springframework.kafka.support.serializer.JsonDeserializer.deserialize(JsonDeserializer.java:372) ~[spring-kafka-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
    at org.apache.kafka.clients.consumer.internals.Fetcher.parseRecord(Fetcher.java:1041) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.internals.Fetcher.access$3300(Fetcher.java:110) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1223) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1400(Fetcher.java:1072) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:562) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:523) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1230) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1187) ~[kafka-clients-2.0.1.jar!/:na]
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1154) ~[kafka-clients-2.0.1.jar!/:na]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:743) ~[spring-kafka-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:700) ~[spring-kafka-2.2.8.RELEASE.jar!/:2.2.8.RELEASE]
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
    at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1611) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:369) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.9.9.3.jar!/:2.9.9.3]
 at [Source: (byte[])"{"amc":"ICICI","name":"ICICI Prudential","address":"One Complex, Mumbai 400051","phone":null,"aum":465598.96249788,"launch_date":{"millisOfDay":600000,"minuteOfDay":10,"secondOfDay":600,"centuryOfEra":19,"yearOfEra":1993,"yearOfCentury":93,"weekyear":1993,"monthOfYear":1,"weekOfWeekyear":2,"hourOfDay":0,"minuteOfHour":10,"secondOfMinute":0,"millisOfSecond":0,"dayOfWeek":2,"dayOfYear":12,"era":1,"year":1993,"dayOfMonth":12,"zone":{"fi"[truncated 690 bytes]; line: 1, column: 540] (through reference chain: com.commons.sdk.dto.web.AmcDto["launch_date"]->org.joda.time.DateTime["chronology"])

AmcDto in service 1 as below:

import org.joda.time.DateTime;
public class AmcDto implements Serializable {
    @JsonProperty("amc")
    private String amc;

    @JsonProperty("name")
    private String name;

    @JsonProperty("address")
    private String address;

    @JsonProperty("launch_date")
    private DateTime launchDate;
  }

AmcDto in service 2 as below:


import java.time.LocalDateTime;
public class AmcDto implements Serializable {
    @JsonProperty("amc")
    private String amc;

    @JsonProperty("name")
    private String name;

    @JsonProperty("address")
    private String address;
    
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonProperty("launch_date")
    private LocalDateTime launchDate;
  }

I have added the below dependecy and tried to register the JodaModule:

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
            <version>2.1.1</version>
        </dependency>

and register module in Application file

    @Bean
    @Primary
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.build();
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.registerModule(new JodaModule());
        return objectMapper;
    }

How this can be resolved so that it works in both the service without creating a new common Dto for both the service, ideally it should have been through common dto ?

0

There are 0 answers