I encountered a crash when loading a world with many mods installed. The crash is a java.util.concurrent.RejectedExecutionException originating from
FeatureRecycler
.
It appears that the mod initializes a ThreadPoolExecutor with a fixed maximum pool size (likely 11, matching the vanilla GenerationStep.Decoration enum length). However, with modded biomes (like those from Terralith/Biomes O' Plenty), the number of feature steps often exceeds 11.
When the mod attempts to submit tasks for these additional steps to the executor, the pool is exhausted (using SynchronousQueue), causing the executor to reject the new task and crash the game.
Crash Log Snippet
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.CompletableFuture$AsyncSupply@... rejected from java.util.concurrent.ThreadPoolExecutor@...
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2065)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:833)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1365)
at java.util.concurrent.CompletableFuture.asyncSupplyStage(CompletableFuture.java:1782)
at java.util.concurrent.CompletableFuture.supplyAsync(CompletableFuture.java:2005)
at dev.corgitaco.featurerecycler.FeatureRecycler.recycle(FeatureRecycler.java:79)
The Fix
I was able to fix this locally by changing the ThreadPoolExecutor to be dynamic (Cached Thread Pool style), allowing it to spawn as many threads as needed for the number of feature steps detected.
Old Code (Inferred):
return new ThreadPoolExecutor(0, 11, // or GenerationStep.Decoration.values().length
60L, TimeUnit.SECONDS,
new SynchronousQueue<>(), ...);
New Code (Fix):
// Change max pool size to Integer.MAX_VALUE to allow dynamic expansion
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<>(), (runnable) -> {
Thread thread = new Thread(runnable);
thread.setName("Feature-Recycler-Worker-" + WORKER_COUNT.getAndIncrement());
// ... (uncaught handler)
return thread;
});
This ensures that no matter how many feature steps a biome has, the executor can handle the workload without rejecting tasks.
I encountered a crash when loading a world with many mods installed. The crash is a java.util.concurrent.RejectedExecutionException originating from
FeatureRecycler
.
It appears that the mod initializes a ThreadPoolExecutor with a fixed maximum pool size (likely 11, matching the vanilla GenerationStep.Decoration enum length). However, with modded biomes (like those from Terralith/Biomes O' Plenty), the number of feature steps often exceeds 11.
When the mod attempts to submit tasks for these additional steps to the executor, the pool is exhausted (using SynchronousQueue), causing the executor to reject the new task and crash the game.
Crash Log Snippet
The Fix
I was able to fix this locally by changing the ThreadPoolExecutor to be dynamic (Cached Thread Pool style), allowing it to spawn as many threads as needed for the number of feature steps detected.
Old Code (Inferred):
New Code (Fix):
This ensures that no matter how many feature steps a biome has, the executor can handle the workload without rejecting tasks.