queueLookup API method throwing ConcurrentModificationException
Krakenied opened this issue ยท 6 comments
List<String[]> queueLookup = api.queueLookup(block);
really often throws ConcurrentModificationException (probably especially on bigger servers)
[23:29:59 WARN]: java.util.ConcurrentModificationException
[23:29:59 WARN]: at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
[23:29:59 WARN]: at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
[23:29:59 WARN]: at CoreProtect-22.2.jar//net.coreprotect.api.QueueLookup.performLookup(QueueLookup.java:52)
[23:29:59 WARN]: at CoreProtect-22.2.jar//net.coreprotect.CoreProtectAPI.queueLookup(CoreProtectAPI.java:182)
The cause of the error is probably consumerData
being modified while iterating.
@Intelli still not fixed
It doesn't fix the issue. I wrote a simple class:
public static void a() {
final ArrayList<Object[]> list = new ArrayList<>();
for (Object[] data : list) {
System.out.println(data.length);
}
}
public static void b() {
final ArrayList<Object[]> list = new ArrayList<>();
final ListIterator<Object[]> it = list.listIterator();
while (it.hasNext()) {
Object[] data = it.next();
System.out.println(data.length);
}
}
And bytecode for both methods is nearly the same:
$ javap -c Test.class
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void a();
Code:
0: new #7 // class java/util/ArrayList
3: dup
4: invokespecial #9 // Method java/util/ArrayList."<init>":()V
7: astore_0
8: aload_0
9: invokevirtual #10 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;
12: astore_1
13: aload_1
14: invokeinterface #14, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
19: ifeq 43
22: aload_1
23: invokeinterface #20, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
28: checkcast #24 // class "[Ljava/lang/Object;"
31: astore_2
32: getstatic #26 // Field java/lang/System.out:Ljava/io/PrintStream;
35: aload_2
36: arraylength
37: invokevirtual #32 // Method java/io/PrintStream.println:(I)V
40: goto 13
43: return
public static void b();
Code:
0: new #7 // class java/util/ArrayList
3: dup
4: invokespecial #9 // Method java/util/ArrayList."<init>":()V
7: astore_0
8: aload_0
9: invokevirtual #38 // Method java/util/ArrayList.listIterator:()Ljava/util/ListIterator;
12: astore_1
13: aload_1
14: invokeinterface #42, 1 // InterfaceMethod java/util/ListIterator.hasNext:()Z
19: ifeq 43
22: aload_1
23: invokeinterface #45, 1 // InterfaceMethod java/util/ListIterator.next:()Ljava/lang/Object;
28: checkcast #24 // class "[Ljava/lang/Object;"
31: astore_2
32: getstatic #26 // Field java/lang/System.out:Ljava/io/PrintStream;
35: aload_2
36: arraylength
37: invokevirtual #32 // Method java/io/PrintStream.println:(I)V
40: goto 13
43: return
}
Also, as you can see, ListIterator is fail-fast too:
It means, that will throw CME too:
I'm currently using a custom CoreProtect fork on my server to prevent this error from occurring. My solution to this is:
for (Object[] data : consumerData.toArray(Object[][]::new)) {
and it hasn't thrown any errors since the change.
Switched the for loop for a ListIterator -- let me know if that resolves the issue.
Still present LMBishop/Quests#707
Can you provide the code you're using which triggers this error?
Crucial step: have dozens of players online
You just need to invoke CoreProtectAPI#queueLookup
which calls QueueLookup#performLookup
. And this thing throws: