本文介绍了JsonMappingException :(是java.lang.ArrayIndexOutOfBoundsException)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,服务器以JSON格式返回任何结果。为了创建JSON,我使用,版本1.9.8。

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.

当发生异常时,服务器返回(是java.lang.ArrayIndexOutOfBoundsException )(通过引用链:com.onior.modm.restlet.helpers.ServiceResult [success]),这意味着'toJSON'中引发的异常被捕获并通过'toRepresentation'映射到JSON,否则它会有返回空。

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<T> {
    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<ModmServiceStatus> serviceException(
        ServiceError error) {
        return new ServiceResult<ModmServiceStatus>(false,
            new ModmServiceStatus(error.getCode(), error.getDescription()));
    }

    public static ServiceResult<ModmServiceStatus> dbError() {
        return ServiceResult
            .serviceException(ServiceError.GENERIC_DATABASE_ERROR);
    }

    public static ServiceResult<ModmServiceStatus> invalidJson() {
        return ServiceResult
            .serviceException(ServiceError.GENERIC_INVALID_JSON);
    }

    public static ServiceResult<ModmServiceStatus> missingEntity() {
        return ServiceResult                .serviceException(ServiceError.GENERIC_MISSING_OR_INCOMPLETE_ENTITY);
    }

    public static ServiceResult<ModmServiceStatus> entityNotFound() {
        return ServiceResult
            .serviceException(ServiceError.GENERIC_ENTITY_NOT_FOUND);
    }

    public static ServiceResult<ModmServiceStatus> entityDeleted(String entity) {
        return new ServiceResult<ModmServiceStatus>(true,
            new ModmServiceStatus(0, entity + " deleted."));
    }
}

映射:

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 <T> JacksonRepresentation<T> toJSON(T t) throws IOException {
        JsonRepresentation jsonRepresentation = null;
        JacksonRepresentation<T> jacksonRepresentation = null;
        jsonRepresentation = new JsonRepresentation(
            OBJECT_WRITER.writeValueAsString(t)); // Origin of incidental
                                                    // server error
        jacksonRepresentation = new JacksonRepresentation<T>(
            jsonRepresentation, (Class<T>) t.getClass());
        return jacksonRepresentation;
    }

    public static <T> Representation toRepresentation(ServiceResult<T> 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;
    }
}

电话:

RestUtils.toRepresentation(new ServiceResult<List<Group>>(groups));

stacktrace的例外:

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


推荐答案

与Jackson 1.9.9完全相同的ArrayIndexOutOfBoundsException

Got the exact same ArrayIndexOutOfBoundsException with Jackson 1.9.9

经过调查,我们的根本原因是多个线程使用的共享PrettyPrinter。
如果您查看DefaultPrettyPrinter的Jackson代码,您会看到:

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最终用于访问数组。处理对象时,此变量递增和递减。如果多个线程减少它,它可能会导致负数导致ArrayIndexOutOfBoundsException。一旦消极,它将不会再次增加,因为异常将在到达一段会增加它的代码之前生成。

_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.

在你的代码中,我看到你有静态对象编写器。您最终可能会使用DefaultPrettyPrinter的单个实例。如果你的应用程序可以同时生成json对象,给定足够的时间,你将获得异常。

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

这篇关于JsonMappingException :(是java.lang.ArrayIndexOutOfBoundsException)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 06:27