friendlyhj / ZenUtils

Home Page:https://www.curseforge.com/minecraft/mc-mods/zenutil

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Crash: ConcurrentModificationException on tandem with Catenation

Krutoy242 opened this issue · comments

I'm changing string list inside catenation and getting this server crash:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
    at java.util.ArrayList$Itr.next(ArrayList.java:861)
    at commands\Restart_server.clearPending(commands/restart_server.zs:59)
    at commands\Restart_server.cancelVoting(commands/restart_server.zs:66)
    at Crafttweakercommands\Restart_server89.apply(commands/restart_server.zs:91)
    at youyihj.zenutils.impl.util.catenation.InstantTask.run(InstantTask.java:20)
    at youyihj.zenutils.api.util.catenation.Catenation.tick(Catenation.java:38)
    at youyihj.zenutils.impl.util.catenation.CatenationManager.lambda$onWorldTick$0(CatenationManager.java:31)
    at java.util.Collection.removeIf(Collection.java:414)
    at youyihj.zenutils.impl.util.catenation.CatenationManager.onWorldTick(CatenationManager.java:31)
    at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_1352_CatenationManager_onWorldTick_WorldTickEvent.invoke(.dynamic)

My code: https://github.com/Krutoy242/Enigmatica2Expert-Extended/blob/7ae848b7b5df53c85416e4c5b8d5cde74da9ba6f/scripts/commands/restart_server.zs#L59
Full crash log:
crash-2022-08-31_19.20.37-server.txt

You can not edit the list when you are iterating it. Yea, I forgot to expose clear method. In version 1.11.3, just call this method to fix the issue.

Thank you!

Can you add additional checks so that the game does not crash under these conditions? I like that ZenScript is pretty crash-resistant, and strive that scripts can never crash, only erroring in logs.

Also, I don't know how to program in Java, and I don't know what ConcurrentModificationException is. In JavaScript, I can remove from an array without a problem as long as I iterate it 😁

I don't know how JS implements it. I just try to explain why the exception exists.
Since all loops can be written by while statement. (for and foreach are more like syntactic sugar) I translate the code to while style.
Pseudocode:

var list = ["a", "b", "c", "d"];
var length = list.length;
var i = 0;
while (i < length) { // for i, element in list
    // removes the element at the given index
    list.remove(i);
    i++;
};

In the first loop, list.remove(0) removes the first element a, now the list is ["b", "c", "d"] Then, in the second loop, list.remove(1) removes the second element of the list. But since the list is ["b", "c", "d"], so the statement removes "c" , rather than "b". This is a unexpected behavior. So Java uses fast fail mode, throws an exception to avoid this operation.

Ok, thank you.
So, i guess each other ZenUtils user would encounter this issue if they dont know how java work...

If there any other places where ZenUtils could crash my game, i want to know. Can you add Wiki note for this? Maybe, under function description.