JSONObject.fromObject导致java.util.ConcurrentModificationException

时间:2015-04-28 05:21:16

标签: java json exception

当我检查我的服务器错误日志时,我找到了

net.sf.json.JSONException: java.util.ConcurrentModificationException
    at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:818)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:699)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:172)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:134)
    at com.j1.mai.model.common.JsonResult.toString(JsonResult.java:126)
    at com.j1.mai.model.common.JsonpBaseAction.write(JsonpBaseAction.java:84)
    at com.j1.mai.model.common.JsonpBaseAction.write(JsonpBaseAction.java:65)
    at com.j1.mai.action.SearchAction.list(SearchAction.java:106)
    at sun.reflect.GeneratedMethodAccessor325.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    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.Http11AprProcessor.process(Http11AprProcessor.java:879)
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1774)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at org.apache.commons.collections.iterators.AbstractIteratorDecorator.next(AbstractIteratorDecorator.java:67)
    at org.apache.commons.collections.map.ListOrderedMap$ListOrderedIterator.next(ListOrderedMap.java:605)
    at net.sf.json.JSONObject.hashCode(JSONObject.java:2114)
    at java.util.HashMap.put(HashMap.java:372)
    at java.util.HashSet.add(HashSet.java:200)
    at net.sf.json.AbstractJSON.addInstance(AbstractJSON.java:63)
    at net.sf.json.JSONObject._fromJSONObject(JSONObject.java:900)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:155)
    at net.sf.json.JSONSerializer.toJSON(JSONSerializer.java:108)
    at net.sf.json.AbstractJSON._processValue(AbstractJSON.java:238)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2655)
    at net.sf.json.JSONObject.processValue(JSONObject.java:2721)
    at net.sf.json.JSONObject.setInternal(JSONObject.java:2736)
    at net.sf.json.JSONObject.setValue(JSONObject.java:1424)
    at net.sf.json.JSONObject.defaultBeanProcessing(JSONObject.java:765)
    ... 36 more

JsonResult

public class JsonResult implements Serializable {
    static Logger LOG = Logger.getLogger(JsonResult.class);

    private static final long serialVersionUID = 248463127163578297L;

    private String status;
    private String msg;
    private JSONObject data;

    public JsonResult() {
        this.setSuccess();
        this.data = new JSONObject();
    }

    public String getStatus() {
        return status;
    }

    public JsonResult setStatus(String status) {
        this.status = status;
        return this;
    }

    public JsonResult setSuccess() {
        this.status = MsgStatus.NORMAL.getCode();
        return this;
    }

    public JsonResult setFailure() {
        this.status = MsgStatus.EXCEPTION.getCode();
        return this;
    }

    public String getMsg() {
        return msg;
    }

    public JsonResult setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    public JSONObject getData() {
        return data;
    }

    public boolean success() {
        return this.status.equals(MsgStatus.NORMAL.getCode());
    }

    public JsonResult setData(JSONObject data) {
        this.data = data;
        return this;
    }

    public JsonResult put(Object key, Object val) {
        if (val != null)
            this.data.put(key, val);
        return this;
    }

    public JsonResult setObjData(Object o) {
        if (o == null)
            return this;
        try {
            if (o.getClass().equals(JSONObject.class)) {
                this.data = (JSONObject) o;
            } else {
                this.data = JSONObject.fromObject(o);
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return this;
    }

    public JsonResult putObjData(Object o) {
        if (o == null)
            return this;
        JSONObject jo = null;
        try {
            if (o.getClass().equals(JSONObject.class)) {
                jo = (JSONObject) o;
            } else {
                jo = JSONObject.fromObject(o);
            }
            if (jo != null)
                this.data.putAll(jo);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
        return this;
    }

    public JsonResult clear() {
        this.getData().clear();
        this.setSuccess();
        this.setMsg("");
        return this;
    }

    @Override
    public String toString() {
        return JSONObject.fromObject(this).toString();
    }
}

JsonpBaseAction.write代码为

protected JsonResult _result = new JsonResult();

public void write(HttpServletRequest request, HttpServletResponse response,
        String callback) {
    response.setContentType("text/html;charset=utf-8");
    response.setCharacterEncoding("utf-8");
    String result = null;
    PrintWriter writer = null;
    try {
        writer = response.getWriter();
        if (StringUtil.isEmpty(callback))
            result = _result.toString();
        else
            result = callback + "(" + _result.toString() + ")";
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
        if (writer != null) {
            writer.write(result);
            writer.close();
        }
        if (result != null)
            _result.clear();
    }
}

我认为在写作时我并没有修改JSONObject

为什么我得到ConcurrentModificationException

1 个答案:

答案 0 :(得分:0)

JSONObject的实例不是线程安全的。 请参阅documentation

正如我从您的代码中看到的那样:

write方法可能是从多个线程调用并改变_result,这会导致此异常。