title: JSONObject.fromObject cause java.util.ConcurrentModificationException
body: <p>When I check my server error log, I found </p>
  
  <pre><code>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
  </code></pre>
  
  <p>the <code>JsonResult</code> class </p>
  
  <pre><code>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();
      }
  }
  </code></pre>
  
  <p>and the <code>JsonpBaseAction.write</code> code is </p>
  
  <pre><code>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();
      }
  }
  </code></pre>
  
  <p>I think I didn't modify the <code>JSONObject</code> while write.</p>
  
  <p>Why I get <code>ConcurrentModificationException</code>?</p>