In Control!

In Control!

72M Downloads

RuleCache.CachePerWorld.count(IWorld) may cause java.util.ConcurrentModificationException

Closed this issue ยท 4 comments

commented

CountPerMod count = countPerMod.computeIfAbsent(mod, s -> new CountPerMod());

HashMap.computeIfAbsent() might be modify current map if the specified key is not already associated with a value (or is mapped to null). So you can't use it in foreach.

For example:

[27Jun2023 17:28:34.858] [Worker-Main10/ERROR] [net.minecraftforge.eventbus.EventBus/EVENTBUS]: Exception caught during firing event: null
	Index: 10
	Listeners:
		0: HIGH
		1: ASM: class me.shedaniel.architectury.event.forge.EventHandlerImplCommon event(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
		2: NORMAL
		3: ASM: class net.pavocado.exoticbirds.ForgeEventSubscriber checkSpawns(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
		4: ASM: class com.minecraftabnormals.environmental.core.other.EnvironmentalEvents onLivingSpawn(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
		5: net.minecraftforge.eventbus.EventBus$$Lambda$2729/0x0000000800e2d840@541f143a
		6: net.minecraftforge.eventbus.EventBus$$Lambda$2729/0x0000000800e2d840@6dce5b1c
		7: LOWEST
		8: ASM: vazkii.quark.content.world.module.underground.SpiderNestUndergroundBiomeModule@6eebfba5 onZombieSpawn(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
		9: ASM: vazkii.quark.content.mobs.module.ForgottenModule@75683ee3 onSkeletonSpawn(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
		10: ASM: mcjty.incontrol.ForgeEventHandlers@77b64e0a onEntitySpawnEvent(Lnet/minecraftforge/event/entity/living/LivingSpawnEvent$CheckSpawn;)V
java.util.ConcurrentModificationException
	at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1135)
	at mcjty.incontrol.rules.RuleCache$CachePerWorld.lambda$count$1(RuleCache.java:208)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
	at mcjty.incontrol.rules.RuleCache$CachePerWorld.count(RuleCache.java:202)
	at mcjty.incontrol.rules.RuleCache$CachePerWorld.getCount(RuleCache.java:226)
	at mcjty.incontrol.rules.RuleCache.getCount(RuleCache.java:62)
	at mcjty.incontrol.rules.support.GenericRuleEvaluator.lambda$getCounter$34(GenericRuleEvaluator.java:492)
	at mcjty.incontrol.rules.support.GenericRuleEvaluator.lambda$addMinCountCheck$18(GenericRuleEvaluator.java:395)
	at mcjty.incontrol.rules.support.GenericRuleEvaluator.match(GenericRuleEvaluator.java:607)
	at mcjty.incontrol.rules.SpawnRule.match(SpawnRule.java:277)
	at mcjty.incontrol.ForgeEventHandlers.onEntitySpawnEvent(ForgeEventHandlers.java:113)
	at net.minecraftforge.eventbus.ASMEventHandler_1868_ForgeEventHandlers_onEntitySpawnEvent_CheckSpawn.invoke(.dynamic)
	at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85)
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302)
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283)
	at net.minecraftforge.event.ForgeEventFactory.canEntitySpawn(ForgeEventFactory.java:187)
	at net.minecraftforge.common.ForgeHooks.canEntitySpawn(ForgeHooks.java:1152)
	at untamedwilds.world.FaunaSpawn.performWorldGenSpawning(FaunaSpawn.java:131)
	at untamedwilds.world.gen.feature.FeatureDenseWater.generate(FeatureDenseWater.java:26)
	at untamedwilds.world.gen.feature.FeatureDenseWater.place(FeatureDenseWater.java:17)
	at net.minecraft.world.gen.feature.ConfiguredFeature.place(SourceFile:55)
	at net.minecraft.world.gen.feature.DecoratedFeature.lambda$place$0(SourceFile:23)
	at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
	at net.minecraft.world.gen.feature.DecoratedFeature.place(SourceFile:22)
	at net.minecraft.world.gen.feature.DecoratedFeature.place(SourceFile:14)
	at net.minecraft.world.gen.feature.ConfiguredFeature.place(SourceFile:55)
	at net.minecraft.world.biome.Biome.generate(Biome.java:254)
	at net.minecraft.world.gen.ChunkGenerator.applyBiomeDecoration(SourceFile:220)
	at net.minecraft.world.chunk.ChunkStatus.lambda$static$9(ChunkStatus.java:77)
	at net.minecraft.world.chunk.ChunkStatus.generate(ChunkStatus.java:198)
	at net.minecraft.world.server.ChunkManager.lambda$null$18(ChunkManager.java:524)
	at com.mojang.datafixers.util.Either$Left.map(Either.java:38)
	at net.minecraft.world.server.ChunkManager.lambda$scheduleChunkGeneration$20(ChunkManager.java:522)
	at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
	at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:478)
	at net.minecraft.world.chunk.ChunkTaskPriorityQueueSorter.lambda$null$1(SourceFile:58)
	at net.minecraft.util.concurrent.DelegatedTaskExecutor.pollTask(SourceFile:94)
	at net.minecraft.util.concurrent.DelegatedTaskExecutor.pollUntil(SourceFile:137)
	at net.minecraft.util.concurrent.DelegatedTaskExecutor.run(SourceFile:105)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
commented

I'll check it out soon. Thanks for reporting

commented

Hmm that can't be the reason. It's perfectly fine to do computeIfAbsent on another map while iterating over something else. And that's exactly what is happening. Not sure what you get that error though. This seems to be a bug in UntamedWilds

commented

UntamedWilds seems to be spawning mobs during feature generation. I don't think that's how you should do this to be honest

commented

Right that's the problem. Worldgen happens in another thread. You cannot do entity spawning there. This is a concurrent modification exception because the computeIfAbsent is done in the wrong thread. So report to them