java.lang.ArrayIndex,JsonMappingException :(是java.lang.ArrayIndexOutOfBoundsException)

I have a web application where the server returns any results in JSON format. For creating the JSON, I use the codehaus Jackson ObjectWriter, version 1.9.8.

The problem I'm having that sometimes there is an error, in the mapping, and from then on all server calls result in an error. I haven't been able to determine what causes the error, I did discover the origin.

When the exception occurs, the server returns "(was java.lang.ArrayIndexOutOfBoundsException) (through reference chain: com.onior.modm.restlet.helpers.ServiceResult["success"])", which means that the exception thrown in 'toJSON' was catched and mapped to JSON by 'toRepresentation', otherwise it would have returned empty.

I just don't know why it is sometimes failing. I will be able to use the application all morning without problems, and then suddenly I will get this error. It happens on different calls, but these calls will succeed at other times. From my point of view it seems quite random, but maybe someone can help me see the light? :)

The server result that is being mapped:

public class ServiceResult {

private boolean success;

private T results = null;

private ModmServiceStatus message = null;

public ServiceResult() {

}

public ServiceResult(T results) {

this.success = true;

this.results = results;

}

public ServiceResult(boolean success, ModmServiceStatus message) {

this.success = success;

this.message = message;

}

public ServiceResult(ServiceError error) {

this(false, new ModmServiceStatus(error));

}

public static ServiceResult serviceException(

ServiceError error) {

return new ServiceResult(false,

new ModmServiceStatus(error.getCode(), error.getDescription()));

}

public static ServiceResult dbError() {

return ServiceResult

.serviceException(ServiceError.GENERIC_DATABASE_ERROR);

}

public static ServiceResult invalidJson() {

return ServiceResult

.serviceException(ServiceError.GENERIC_INVALID_JSON);

}

public static ServiceResult missingEntity() {

return ServiceResult .serviceException(ServiceError.GENERIC_MISSING_OR_INCOMPLETE_ENTITY);

}

public static ServiceResult entityNotFound() {

return ServiceResult

.serviceException(ServiceError.GENERIC_ENTITY_NOT_FOUND);

}

public static ServiceResult entityDeleted(String entity) {

return new ServiceResult(true,

new ModmServiceStatus(0, entity + " deleted."));

}

}

The mapping:

public class RestUtils {

private static final boolean PRETTY_PRINT = true;

public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

public static final ObjectWriter OBJECT_WRITER = (PRETTY_PRINT ? OBJECT_MAPPER

.writerWithDefaultPrettyPrinter() : OBJECT_MAPPER.writer());

@SuppressWarnings("unchecked")

public static JacksonRepresentation toJSON(T t) throws IOException {

JsonRepresentation jsonRepresentation = null;

JacksonRepresentation jacksonRepresentation = null;

jsonRepresentation = new JsonRepresentation(

OBJECT_WRITER.writeValueAsString(t)); // Origin of incidental

// server error

jacksonRepresentation = new JacksonRepresentation(

jsonRepresentation, (Class) t.getClass());

return jacksonRepresentation;

}

public static Representation toRepresentation(ServiceResult ss) {

Representation representation = null;

try {

representation = RestUtils.toJSON(ss);

} catch (IOException jsonException) {

jsonException.printStackTrace();

try {

jsonException.printStackTrace();

representation = RestUtils.toJSON(jsonException.getMessage());

} catch (Exception e) {

e.printStackTrace();

}

}

return representation;

}

}

The call:

RestUtils.toRepresentation(new ServiceResult>(groups));

The exception with stacktrace:

org.codehaus.jackson.map.JsonMappingException: (was java.lang.ArrayIndexOutOfBoundsException) (through reference chain: com.onior.modm.restlet.helpers.ServiceResult["success"])

at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)

at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)

at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)

at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158)

at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)

at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)

at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)

at org.codehaus.jackson.map.ObjectWriter._configAndWriteValue(ObjectWriter.java:456)

at org.codehaus.jackson.map.ObjectWriter.writeValueAsString(ObjectWriter.java:393)

at com.onior.modm.restlet.helpers.RestUtils.toJSON(RestUtils.java:52)

at com.onior.modm.restlet.helpers.RestUtils.toRepresentation(RestUtils.java:71)

at com.onior.modm.restlet.resources.GroupCollectionResource.toJsonRead(GroupCollectionResource.java:191)

at sun.reflect.GeneratedMethodAccessor143.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.restlet.resource.ServerResource.doHandle(ServerResource.java:506)

at org.restlet.resource.ServerResource.get(ServerResource.java:707)

at org.restlet.resource.ServerResource.doHandle(ServerResource.java:589)

at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:649)

at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:348)

at org.restlet.resource.ServerResource.handle(ServerResource.java:952)

at org.restlet.resource.Finder.handle(Finder.java:246)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Router.doHandle(Router.java:431)

at org.restlet.routing.Router.handle(Router.java:648)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Router.doHandle(Router.java:431)

at org.restlet.routing.Router.handle(Router.java:648)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.routing.Filter.doHandle(Filter.java:159)

at org.restlet.routing.Filter.handle(Filter.java:206)

at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)

at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:84)

at org.restlet.Application.handle(Application.java:381)

at org.restlet.ext.servlet.ServletAdapter.service(ServletAdapter.java:206)

at org.restlet.ext.spring.RestletFrameworkServlet.doService(RestletFrameworkServlet.java:124)

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)

at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)

at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)

at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)

at java.lang.Thread.run(Unknown Source)

Caused by: java.lang.ArrayIndexOutOfBoundsException

at org.codehaus.jackson.impl.WriterBasedGenerator.writeRaw(WriterBasedGenerator.java:577)

at org.codehaus.jackson.util.DefaultPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultPrettyPrinter.java:279)

at org.codehaus.jackson.util.DefaultPrettyPrinter.beforeObjectEntries(DefaultPrettyPrinter.java:98)

at org.codehaus.jackson.impl.WriterBasedGenerator._writePPFieldName(WriterBasedGenerator.java:410)

at org.codehaus.jackson.impl.WriterBasedGenerator._writeFieldName(WriterBasedGenerator.java:340)

at org.codehaus.jackson.impl.WriterBasedGenerator.writeFieldName(WriterBasedGenerator.java:217)

at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:444)

at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150)

... 58 more

解决方案

Got the exact same ArrayIndexOutOfBoundsException with Jackson 1.9.9

After investigating, our root cause was a shared PrettyPrinter used by multiple threads.

If you look in the Jackson code for the DefaultPrettyPrinter, you will see:

/**

* Number of open levels of nesting. Used to determine amount of

* indentation to use.

*/

protected int _nesting = 0;

_nesting ends up being used to access arrays. This variable is incremented and decremented when processing object. If multiple threads decrements it, it may end up negative causing the ArrayIndexOutOfBoundsException. Once negative, it will not be ever increased again because the exception will be generated before reaching a piece of code that would increment it.

In your code, I see you have a static object writer. You probably end up with a single instance of the DefaultPrettyPrinter. If your application can concurrently produce json object, given enough time, you will get the exception.

Stéphan

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值