0

When I check my server error log, I found

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

the JsonResult class

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();
    }
}

and the JsonpBaseAction.write code is

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();
    }
}

I think I didn't modify the JSONObject while write.

Why I get ConcurrentModificationException?

1
  • Do you share your JSONResult between multiple threads (multiple HTTP requests)? That you have need of a clear method to reset it seems to support that theory. Stop doing that. Make it a request scope object. Commented Apr 28, 2015 at 5:24

1 Answer 1

1

Instances of JSONObject are not thread-safe. See documentation.


As I can see from your code:

The write method is probably called from multiple threads and alters _result, which causes this exception.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.