World Blender (Forge)

World Blender (Forge)

134k Downloads

[1.16] Classloading issue with Vampirism

maxanier opened this issue · 3 comments

commented

There is a weird crash with WorldBlender and Vampirism TeamLapen/Vampirism#787
For some reason the Screen class of one of Vampirism's tileentities cannot be loaded/initialized.
I have no idea how this can happen. From a quick look at your mixins I couldn't find anything related.
Do you have any idea how WorldBlender might be involved?

Steps to reproduce

  • Forge 34.1.(0)
  • Vampirism 1.6.0
  • WorldBlender 2.2.0
  • Create new creative world
  • Place "Altar Infusion"

Error

java.lang.NoClassDefFoundError: Could not initialize class de.teamlapen.vampirism.inventory.container.AltarInfusionContainer
	at de.teamlapen.vampirism.tileentity.AltarInfusionTileEntity.<init>(AltarInfusionTileEntity.java:79) ~[?:1.6.0] {re:classloading}
	at de.teamlapen.vampirism.blocks.AltarInfusionBlock.func_196283_a_(AltarInfusionBlock.java:73) ~[?:1.6.0] {re:classloading}
	at net.minecraftforge.common.extensions.IForgeBlock.createTileEntity(IForgeBlock.java:157) ~[?:?] {re:classloading}
	at net.minecraftforge.common.extensions.IForgeBlockState.createTileEntity(IForgeBlockState.java:120) ~[?:?] {re:classloading}
	at net.minecraft.world.chunk.Chunk.func_177436_a(Chunk.java:289) ~[?:?] {re:classloading,re:mixin}
	at net.minecraft.world.World.func_241211_a_(World.java:199) ~[?:?] {re:classloading,pl:accesstransformer:B,re:mixin,pl:accesstransformer:B}
	at net.minecraft.world.World.func_180501_a(World.java:176) ~[?:?] {re:classloading,pl:accesstransformer:B,re:mixin,pl:accesstransformer:B}
	at net.minecraft.item.BlockItem.func_195941_b(BlockItem.java:149) ~[?:?] {re:classloading}
	at net.minecraft.item.BlockItem.func_195942_a(BlockItem.java:54) ~[?:?] {re:classloading}
	at net.minecraft.item.BlockItem.func_195939_a(BlockItem.java:39) ~[?:?] {re:classloading}
	at net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(ForgeHooks.java:603) ~[?:?] {re:classloading}
	at net.minecraft.item.ItemStack.func_196084_a(ItemStack.java:184) ~[?:?] {re:classloading}
	at net.minecraft.server.management.PlayerInteractionManager.func_219441_a(PlayerInteractionManager.java:350) ~[?:?] {re:classloading}
	at net.minecraft.network.play.ServerPlayNetHandler.func_184337_a(ServerPlayNetHandler.java:889) ~[?:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.func_148833_a(SourceFile:36) ~[?:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemOnBlockPacket.func_148833_a(SourceFile:10) ~[?:?] {re:classloading}
	at net.minecraft.network.PacketThreadUtil.func_225383_a(SourceFile:21) ~[?:?] {re:classloading}
	at net.minecraft.util.concurrent.TickDelayedTask.run(SourceFile:18) ~[?:?] {re:classloading}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213166_h(SourceFile:144) ~[?:?] {re:classloading,pl:accesstransformer:B,re:mixin,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.RecursiveEventLoop.func_213166_h(SourceFile:23) ~[?:?] {re:classloading,re:mixin}
	at net.minecraft.server.MinecraftServer.func_213166_h(MinecraftServer.java:730) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.server.MinecraftServer.func_213166_h(MinecraftServer.java:156) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213168_p(SourceFile:118) ~[?:?] {re:classloading,pl:accesstransformer:B,re:mixin,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.func_213205_aW(MinecraftServer.java:713) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.server.MinecraftServer.func_213168_p(MinecraftServer.java:707) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213160_bf(SourceFile:103) ~[?:?] {re:classloading,pl:accesstransformer:B,re:mixin,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.func_213202_o(MinecraftServer.java:692) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:642) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}
	at net.minecraft.server.MinecraftServer.lambda$func_240784_a_$0(MinecraftServer.java:229) ~[?:?] {re:mixin,pl:accesstransformer:B,re:classloading,pl:accesstransformer:B,pl:mixin:APP:world_blender.mixins.json:MinecraftServerMixin,pl:mixin:A}

Full trace log: https://paste.ee/p/SvAez

commented

Ok, some further investigation shows that this is related to the mentioned code and the issue you discovered in #11

When the tileentity is loaded during common setup the static initializer in the container class tries to use Tags. This fails because they are not loaded yet and therefore the entire class somehow gets (marked as) "corrupt".
When Vampirism later tries to access the class again, it fails because it is (marked as) "corrupt".

A workaround I found is to move the tag access from a static initializer to a static method used. While this will still cause an exception during your chest check, it won't break the class.
I will check if I can delay the tag access to ensure it is only done when tags are available.

So, this issue is mostly on Vampirism side.
I'm not sure if it is considered "legal" by Forge/Vanilla to instantiate a TE outside the game, but I guess with a try-catch it should be fine in most cases.

commented

Hmm. I could try making it rebuild the list of valid chest tile-entities at startup of every world so that way the world exist and less tile-entities could crash. Yeah I'll try this on my side so other chest tile-entities doesn't get swallowed by the try catch if they are doing tags and such. Thank you for letting me know about this!

commented

The only place where I may interact with another mod's tile entity in a strange way is here at FMLCommonSetupEvent to try my best to find all possible modded chests. However, this still doesn't explain the issue you are seeing I think:

for(TileEntityType<?> blockEntityType : Registry.BLOCK_ENTITY_TYPE)
{
try{
TileEntity tileEntity = blockEntityType.create();
if(tileEntity != null){
WBPortalSpawning.VALID_CHEST_BLOCKS_ENTITY_TYPES.put(
blockEntityType,
tileEntity.getClass().getSimpleName().toLowerCase().contains("chest") &&
blockEntityType.create() instanceof IInventory);
}
}
catch(Throwable e){
WorldBlender.LOGGER.log(Level.WARN, "Failed to check if "+blockEntityType.getRegistryName()+" is a chest. If is not a chest, ignore this message. If it is, let telepathicGrunt (World Blender dev) know this.");
}
}

Any thoughts?

I can try running the code in a event.deferred to make it run as late as possible. Maybe it’s too early?