JsonMappingException while serializing : (was java.lang.ArrayIndexOutOfBoundsException)

Learner

I am facing a very strange issue. I am using Jackson databind version 2.7.4 in my application for serialization. Application runs fine for many days but sometimes it starts throwing data serialization errors (Explanation is similar to JsonMappingException: (was java.lang.ArrayIndexOutOfBoundsException) )

This happens randomly and starts throwing ArrayOutOfBoundException when serializing a date field using custom serializer.

Exception trace

R] 2017-02-11 23:39:16 ERROR GlobalExceptionHandlerController:171 - Trace for 500:org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: (was java.lang.ArrayIndexOutOfBoundsException) (through reference chain: com.mycompany.model.DTO.ApiResponse["data"]->com.mycompany.model.Entity["date"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.ArrayIndexOutOfBoundsException) (through reference chain: com.mycompany.model.DTO.ApiResponse["data"]->com.mycompany.model.Entity["date"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:276)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:100)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:222)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:153)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:165)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:81)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:832)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:743)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:961)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.ArrayIndexOutOfBoundsException) (through reference chain: com.mycompany.model.DTO.ApiResponse["data"]->com.mycompany.model.Entity["date"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:378)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:338)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:342)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:686)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:672)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:678)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1428)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:930)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:269)
    ... 36 more
Caused by: java.lang.ArrayIndexOutOfBoundsException

It seems like a shared variable is getting negative value and causing this issue but I am not able to identify the code .

Entity class

public class Entity {
    @JsonSerialize(using=CustomDateSerializer.class)
    @JsonDeserialize(using=CustomDateDeserializer.class)
    private Date date;

    public Entity(){}

    public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }       
}

De-Serializer

public class CustomDateDeserializer extends JsonDeserializer<Date>{

    private SimpleDateFormat formatter = 
              new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        Date date=null;
        String str=p.getText();
        try{
            date=formatter.parse(str);
        }catch(ParseException e){
            throw new RuntimeException(e);
        }
        return date;
    }    
}

Serializer

 public class CustomDateSerializer extends JsonSerializer<Date>{

        private SimpleDateFormat formatter = 
          new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");

        @Override
        public void serialize (Date value, JsonGenerator gen, SerializerProvider arg)
          throws IOException, JsonProcessingException {
            gen.writeString(formatter.format(value));
        }

}

Any help will be appreciated .

Henrik Aasted Sørensen

Quickfix: If you're using Java 8 or above, consider using the thread-safe DateTimeFormatter class instead.

Original answer:

SimpleDateFormat is not thread-safe, as mentioned in its javadoc:

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

This blog post demonstrates the problem and lists a selection of the errors that may be encountered, among them ArrayIndexOutOfBoundsException, if the above recommendation is not followed.

I suggest synchronizing on the date formatter instances. The simplest approach looks something like this:

public void serialize (Date value, JsonGenerator gen, SerializerProvider arg)
    throws IOException, JsonProcessingException {
    synchronized(formatter) {
        gen.writeString(formatter.format(value));
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Getting java.lang.ArrayIndexOutOfBoundsException while splitting

java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException: 26

Error java.lang.ArrayIndexOutOfBoundsException?

error java.lang.ArrayIndexOutOfBoundsException

getting java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException :10

java.lang.ArrayIndexOutOfBoundsException mistake

java.lang.ArrayIndexOutOfBoundsException: 0

THIS java.lang.ArrayIndexOutOfBoundsException ERROR

Error: java.lang.ArrayIndexOutOfBoundsException?

RESTEasy with jackson causes serializing JsonMappingException

Receiving "javax.net.ssl.SSLException: java.lang.ArrayIndexOutOfBoundsException" while connecting to "https:" site

IoTDB:Exception occurred while inserting records. java.lang.ArrayIndexOutOfBoundsException

JAVA Discord Bot (java.lang.ArrayIndexOutOfBoundsException)

How to solve java.lang.ArrayIndexOutOfBoundsException in java?

java.lang.ArrayIndexOutOfBoundsException error in java

Java - java.lang.ArrayIndexOutOfBoundsException occuring in code?

bufferedImage error while serializing and deserializing objects in Java

Can't trace an java.lang.ArrayIndexOutOfBoundsException:

Unable to fix java.lang.ArrayIndexOutOfBoundsException

java.lang.ArrayIndexOutOfBoundsException: 9 error

Error -> java.lang.ArrayIndexOutOfBoundsException: 8

FilteredList gives java.lang.ArrayIndexOutOfBoundsException on update

indexOf error java.lang.ArrayIndexOutOfBoundsException exception

java.lang.ArrayIndexOutOfBoundsException during stack implementation

Getting java.lang.ArrayIndexOutOfBoundsException: 2 >= 2

Geomesa: Caused by: java.lang.ArrayIndexOutOfBoundsException

How to overcome java.lang.ArrayIndexOutOfBoundsException error