Repository: alibaba/fastjson2
Pull request #3604 (2025-06-25 11:42:26)

fix modules iterator error, again
### What this PR does / why we need it?
hello 温少：

这个 PR 是从 https://github.com/alibaba/fastjson2/issues/2358 这个延生过来的。
我根据这个 issue 升级到了 2.0.48，今天发现线上还是有 ConcurrentModificationException。
看了最新代码后发现 2024.7.7 你又改了一次。
我今天堆栈是四个 getFieldInfo 方法中最后一个没有改成下标读取 modules 的了...
两行代码顺手改了下，再提交个 PR。
ps. 我还是不懂为什么这么改， it works...

祝好！


`java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
at com.alibaba.fastjson2.reader.ObjectReaderProvider.getFieldInfo(ObjectReaderProvider.java:901)
at com.alibaba.fastjson2.reader.ObjectReaderCreator.createFieldReader(ObjectReaderCreator.java:1411)
at com.alibaba.fastjson2.reader.ObjectReaderCreator.lambda$createFieldReaders$4(ObjectReaderCreator.java:1660)
at com.alibaba.fastjson2.util.BeanUtils.setters(BeanUtils.java:493)
at com.alibaba.fastjson2.reader.ObjectReaderCreator.createFieldReaders(ObjectReaderCreator.java:1656)
at com.alibaba.fastjson2.reader.ObjectReaderCreatorASM.createObjectReader(ObjectReaderCreatorASM.java:260)
at com.alibaba.fastjson2.reader.ObjectReaderProvider.getObjectReaderInternal(ObjectReaderProvider.java:856)
at com.alibaba.fastjson2.reader.ObjectReaderProvider.getObjectReader(ObjectReaderProvider.java:748)
at com.alibaba.fastjson2.JSONReader.readArray(JSONReader.java:2339)
at com.alibaba.fastjson2.JSON.parseArray(JSON.java:2658)`

### Summary of your change
fix ObjectReaderProvider getFieldInfo modules iterator error, again


#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.


CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/alibaba/fastjson2?pullRequest=3604) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/alibaba/fastjson2?pullRequest=3604) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/alibaba/fastjson2?pullRequest=3604) it.</sub>

Patch:
diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONLargeObjectException.java b/core/src/main/java/com/alibaba/fastjson2/JSONLargeObjectException.java
new file mode 100644
index 000000000..e374266a6
--- /dev/null
+++ b/core/src/main/java/com/alibaba/fastjson2/JSONLargeObjectException.java
@@ -0,0 +1,17 @@
+package com.alibaba.fastjson2;
+
+/**
+ * Exception thrown when attempting to serialize an object that exceeds size limits
+ * and the LargeObject feature is not enabled.
+ *
+ * @since 2.0.58
+ */
+public class JSONLargeObjectException
+        extends JSONException {
+    public JSONLargeObjectException(String message) {
+        super(message);
+    }
+    public JSONLargeObjectException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java b/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
index f4316bf59..06fff5264 100644
--- a/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
+++ b/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
@@ -2728,7 +2728,8 @@ public abstract class JSONWriter
             if (minCapacity < maxArraySize) {
                 newCapacity = maxArraySize;
             } else {
-                throw new OutOfMemoryError("try enabling LargeObject feature instead");
+                throw new JSONLargeObjectException("Maximum array size exceeded. Try enabling LargeObject feature instead. "
+                        + "Requested size: " + minCapacity + ", max size: " + maxArraySize);
             }
         }
         return newCapacity;
diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderProvider.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderProvider.java
index 347e2363a..deb4d782f 100644
--- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderProvider.java
+++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderProvider.java
@@ -888,8 +888,8 @@ public class ObjectReaderProvider
     }
 
     public void getFieldInfo(FieldInfo fieldInfo, Class objectClass, Method method) {
-        for (ObjectReaderModule module : modules) {
-            ObjectReaderAnnotationProcessor annotationProcessor = module.getAnnotationProcessor();
+        for (int i = 0; i < modules.size(); i++) {
+            ObjectReaderAnnotationProcessor annotationProcessor = modules.get(i).getAnnotationProcessor();
             if (annotationProcessor == null) {
                 continue;
             }


Test patch:
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_2300/Issue2323.java b/core/src/test/java/com/alibaba/fastjson2/issues_2300/Issue2323.java
index 2f04edf20..fa45e7c7f 100644
--- a/core/src/test/java/com/alibaba/fastjson2/issues_2300/Issue2323.java
+++ b/core/src/test/java/com/alibaba/fastjson2/issues_2300/Issue2323.java
@@ -2,6 +2,7 @@ package com.alibaba.fastjson2.issues_2300;
 
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONLargeObjectException;
 import com.alibaba.fastjson2.JSONWriter;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
@@ -12,7 +13,7 @@ import java.util.List;
 import java.util.Map;
 
 public class Issue2323 {
-    String errMsg = "try enabling LargeObject feature instead";
+    String errMsgStart = "Maximum array size exceeded. Try enabling LargeObject feature instead. Requested size: ";
 
     @Test
     public void test() throws Exception {
@@ -32,20 +33,23 @@ public class Issue2323 {
 
         try {
             JSONWriter.ofUTF16().write(params);
-        } catch (OutOfMemoryError error) {
-            Assertions.assertEquals(errMsg, error.getMessage());
+        } catch (JSONLargeObjectException error) {
+            Assertions.assertTrue(error.getMessage().startsWith(errMsgStart),
+                    "Error message should start with: " + errMsgStart + ", but was: " + error.getMessage());
         }
 
         try {
             JSONWriter.ofUTF8().write(params);
-        } catch (OutOfMemoryError error) {
-            Assertions.assertEquals(errMsg, error.getMessage());
+        } catch (JSONLargeObjectException error) {
+            Assertions.assertTrue(error.getMessage().startsWith(errMsgStart),
+                    "Error message should start with: " + errMsgStart + ", but was: " + error.getMessage());
         }
 
         try {
             JSONWriter.ofJSONB().write(params);
-        } catch (OutOfMemoryError error) {
-            Assertions.assertEquals(errMsg, error.getMessage());
+        } catch (JSONLargeObjectException error) {
+            Assertions.assertTrue(error.getMessage().startsWith(errMsgStart),
+                    "Error message should start with: " + errMsgStart + ", but was: " + error.getMessage());
         }
     }
 }