
Game crashes with AbstractMethodError caused by custom enchantments (dev ones)
rikka0w0 opened this issue ยท 15 comments
To replicate this issue, first add a shield using this lib, then somehow run the following code after a single-player game starts:
public class Debug {
public static void debug() {
ItemStack itemStack = new ItemStack(Items.DIAMOND_BOOTS);
for (Enchantment enchantment : BuiltInRegistries.ENCHANTMENT) {
try {
System.out.println(enchantment.category.name());
enchantment.category.canEnchant(itemStack.getItem());
} catch (AbstractMethodError e) {
System.out.println("Crash!");
}
}
}
}
Here is my output before the game crashes:
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_FEET
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_HEAD
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_HEAD
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_CHEST
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_FEET
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_FEET
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEARABLE
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_FEET
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: ARMOR_LEGS
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: WEAPON
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: DIGGER
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: DIGGER
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BREAKABLE
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: DIGGER
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: FISHING_ROD
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: FISHING_ROD
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: TRIDENT
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: TRIDENT
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: TRIDENT
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: TRIDENT
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: CROSSBOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: CROSSBOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: CROSSBOW
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: BREAKABLE
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: VANISHABLE
[16:25:50] [Render thread/INFO] (Minecraft) [STDOUT]: FABRIC_SHIELD
Here is the crash log:
---- Minecraft Crash Report ----
// I let you down. Sorry :(
Time: 2023-09-27 16:23:42
Description: Unexpected error
java.lang.AbstractMethodError: Missing implementation of resolved method 'abstract boolean canEnchant(net.minecraft.world.item.Item)' of abstract class net.minecraft.world.item.enchantment.EnchantmentCategory.
at net.mobz.fabric.Debug.debug(Debug.java:14)
at net.mobz.item.Orb2.use(Orb2.java:35)
at net.minecraft.world.item.ItemStack.use(ItemStack.java:255)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.method_41929(MultiPlayerGameMode.java:334)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.startPrediction(MultiPlayerGameMode.java:237)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.useItem(MultiPlayerGameMode.java:325)
at net.minecraft.client.Minecraft.startUseItem(Minecraft.java:1563)
at net.minecraft.client.Minecraft.handleKeybinds(Minecraft.java:1766)
at net.minecraft.client.Minecraft.tick(Minecraft.java:1617)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:1054)
at net.minecraft.client.Minecraft.run(Minecraft.java:746)
at net.minecraft.client.main.Main.main(Main.java:225)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:468)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------
-- Head --
Thread: Render thread
Stacktrace:
at net.mobz.fabric.Debug.debug(Debug.java:14)
at net.mobz.item.Orb2.use(Orb2.java:35)
at net.minecraft.world.item.ItemStack.use(ItemStack.java:255)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.method_41929(MultiPlayerGameMode.java:334)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.startPrediction(MultiPlayerGameMode.java:237)
at net.minecraft.client.multiplayer.MultiPlayerGameMode.useItem(MultiPlayerGameMode.java:325)
at net.minecraft.client.Minecraft.startUseItem(Minecraft.java:1563)
at net.minecraft.client.Minecraft.handleKeybinds(Minecraft.java:1766)
It seems that this line of code add a new enum entry to a vanilla enum, but it does not implement public abstract boolean isAcceptableItem
of EnchantmentTarget:
But looking at
it does implement such method.
Not sure if this problem is specific to the development environment...
Conclusion from this:
1.20.4 and below will have to take a different approach to fix this bug
1.20.5 and will have to be a new version (separate branch) from 1.20.4, since we will have to change our enchantment code. Additionally, 1.20.5 changes a lot of backend systems, meaning we will have to refactor a bunch of things.
and use a specific item list or item tag
For example:
public interface CustomEnchantmentExtension {
@Nullable default TagKey<Item> categoryItemTag() {
return null;
}
}
@Mixin(EnchantmentHelper.class)
class EnchantmentHelperMixin {
@ModifyExpressionValue(method = "getAvailableEnchantmentResults", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/enchantment/EnchantmentCategory;canEnchant(Lnet/minecraft/world/item/Item;)Z"))
private static boolean useEnchantmentCategoryItemsTag(boolean vanillaCategoryCheck, @Local(argsOnly = true) ItemStack item, @Local Enchantment enchantment) {
var enchantmentExtension = (CustomEnchantmentExtension) enchantment;
return enchantmentExtension.categoryItemTag() != null ? item.is(enchantmentExtension.categoryItemTag()) : vanillaCategoryCheck;
}
}
I also get this bug when I just spawn mobs. With MixinExtra you can ditch FabricASM and use a specific item list or item tag. I also want to ask, is a fix possible for 1.20.1? Or should I do PR?
I also want to ask, is a fix possible for 1.20.1? Or should I do PR?
A PR to the 1.20.1 branch would be great so that I could see how it's implemented and work it into our other versions, as I don't know much about MixinExtras. Thanks for finding a solution!
1.20.6 still in the works, issues with enchantment tables showing blanks, but, now when I go back to the 1.20,4 branch, this issue isn't present, though I have not changed anything there. I wont close this issue yet, but it seems like it fixed itself
As per Discord, this seems to be a dev-environment-only issue, just like the very similar past issue #82.
Just ran into this again aswell:
java.lang.AbstractMethodError: Missing implementation of resolved method 'abstract boolean isAcceptableItem(net.minecraft.item.Item)' of abstract class net.minecraft.enchantment.EnchantmentTarget.
at net.minecraft.enchantment.EnchantmentHelper.getPossibleEntries(EnchantmentHelper.java:420)
at net.minecraft.enchantment.EnchantmentHelper.generateEnchantments(EnchantmentHelper.java:369)
at net.minecraft.screen.EnchantmentScreenHandler.generateEnchantments(EnchantmentScreenHandler.java:216)
at net.minecraft.screen.EnchantmentScreenHandler.method_17411(EnchantmentScreenHandler.java:133)
at net.minecraft.screen.ScreenHandlerContext.method_17394(ScreenHandlerContext.java:35)
at net.minecraft.screen.ScreenHandlerContext$2.get(ScreenHandlerContext.java:22)
at net.minecraft.screen.ScreenHandlerContext.run(ScreenHandlerContext.java:34)
at net.minecraft.screen.EnchantmentScreenHandler.onContentChanged(EnchantmentScreenHandler.java:112)
at net.minecraft.screen.EnchantmentScreenHandler$1.markDirty(EnchantmentScreenHandler.java:38)
at net.minecraft.inventory.SimpleInventory.redirect$zij000$fabric-transfer-api-v1$fabric_redirectMarkDirty(SimpleInventory.java:543)
at net.minecraft.inventory.SimpleInventory.setStack(SimpleInventory.java:144)
at net.minecraft.screen.slot.Slot.setStackNoCallbacks(Slot.java:75)
at net.minecraft.screen.slot.Slot.setStack(Slot.java:66)
at net.minecraft.screen.slot.Slot.setStack(Slot.java:63)
at net.minecraft.screen.EnchantmentScreenHandler.quickMove(EnchantmentScreenHandler.java:271)
at net.minecraft.screen.ScreenHandler.internalOnSlotClick(ScreenHandler.java:394)
at net.minecraft.screen.ScreenHandler.onSlotClick(ScreenHandler.java:294)
at net.minecraft.server.network.ServerPlayNetworkHandler.onClickSlot(ServerPlayNetworkHandler.java:1640)
at net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket.apply(ClickSlotC2SPacket.java:58)
at net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket.apply(ClickSlotC2SPacket.java:13)
at net.minecraft.network.NetworkThreadUtils.method_11072(NetworkThreadUtils.java:24)
at net.minecraft.server.ServerTask.run(ServerTask.java:18)
at net.minecraft.util.thread.ThreadExecutor.executeTask(ThreadExecutor.java:156)
at net.minecraft.util.thread.ReentrantThreadExecutor.executeTask(ReentrantThreadExecutor.java:23)
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:797)
at net.minecraft.server.MinecraftServer.executeTask(MinecraftServer.java:165)
at net.minecraft.util.thread.ThreadExecutor.runTask(ThreadExecutor.java:130)
at net.minecraft.server.MinecraftServer.runOneTask(MinecraftServer.java:779)
at net.minecraft.server.MinecraftServer.runTask(MinecraftServer.java:773)
at net.minecraft.util.thread.ThreadExecutor.runTasks(ThreadExecutor.java:139)
at net.minecraft.server.MinecraftServer.runTasksTillTickEnd(MinecraftServer.java:758)
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:687)
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:270)
at java.base/java.lang.Thread.run(Thread.java:1589)
again:
java.lang.AbstractMethodError: Receiver class net.minecraft.enchantment.EnchantmentTarget$15 does not define or inherit an implementation of the resolved method 'abstract boolean isAcceptableItem(net.minecraft.item.Item)' of abstract class net.minecraft.enchantment.EnchantmentTarget.
at net.minecraft.enchantment.Enchantment.isAcceptableItem(Enchantment.java:132)
at net.minecraft.screen.AnvilScreenHandler.updateResult(AnvilScreenHandler.java:216)
at net.minecraft.screen.ForgingScreenHandler.onContentChanged(ForgingScreenHandler.java:106)
at net.minecraft.screen.ForgingScreenHandler$3.markDirty(ForgingScreenHandler.java:96)
at net.minecraft.inventory.SimpleInventory.redirect$zbm000$fabric-transfer-api-v1$fabric_redirectMarkDirty(SimpleInventory.java:543)
at net.minecraft.inventory.SimpleInventory.setStack(SimpleInventory.java:144)
at net.minecraft.screen.slot.Slot.setStackNoCallbacks(Slot.java:75)
at net.minecraft.screen.slot.Slot.setStack(Slot.java:66)
at net.minecraft.screen.slot.Slot.setStack(Slot.java:63)
at net.minecraft.screen.ScreenHandler.insertItem(ScreenHandler.java:662)
at net.minecraft.screen.ForgingScreenHandler.quickMove(ForgingScreenHandler.java:147)
at net.minecraft.screen.ScreenHandler.internalOnSlotClick(ScreenHandler.java:394)
at net.minecraft.screen.ScreenHandler.onSlotClick(ScreenHandler.java:294)
at net.minecraft.client.network.ClientPlayerInteractionManager.clickSlot(ClientPlayerInteractionManager.java:448)
at net.minecraft.client.gui.screen.ingame.HandledScreen.onMouseClick(HandledScreen.java:557)
at net.minecraft.client.gui.screen.ingame.HandledScreen.mouseClicked(HandledScreen.java:349)
at net.minecraft.client.Mouse.method_1611(Mouse.java:99)
at net.minecraft.client.gui.screen.Screen.wrapScreenError(Screen.java:414)
at net.minecraft.client.Mouse.onMouseButton(Mouse.java:99)
at net.minecraft.client.Mouse.method_22686(Mouse.java:180)
at net.minecraft.util.thread.ThreadExecutor.execute(ThreadExecutor.java:102)
at net.minecraft.client.Mouse.method_22684(Mouse.java:180)
at org.lwjgl.glfw.GLFWMouseButtonCallbackI.callback(GLFWMouseButtonCallbackI.java:43)
at org.lwjgl.system.JNI.invokeV(Native Method)
at org.lwjgl.glfw.GLFW.glfwPollEvents(GLFW.java:3438)
at com.mojang.blaze3d.systems.RenderSystem.pollEvents(RenderSystem.java:202)
at com.mojang.blaze3d.systems.RenderSystem.flipFrame(RenderSystem.java:213)
at net.minecraft.client.util.Window.swapBuffers(Window.java:287)
at net.minecraft.client.MinecraftClient.render(MinecraftClient.java:1349)
at net.minecraft.client.MinecraftClient.run(MinecraftClient.java:888)
at net.minecraft.client.main.Main.main(Main.java:265)
at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470)
at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
at net.fabricmc.devlaunchinjector.Main.main(Main.java:86)
happens specifically with the custom enchantments we made; vanilla enchantments work fine; vanilla shields also cause crash
From closed issue:
Did not occur when I tried the same thing with the same code in an actual instance
[18:27:46] [Server thread/ERROR] (Minecraft) Encountered an unexpected exception
java.lang.AbstractMethodError: Missing implementation of resolved method 'abstract boolean canEnchant(net.minecraft.world.item.Item)' of abstract class net.minecraft.world.item.enchantment.EnchantmentCategory.
at net.minecraft.world.item.enchantment.EnchantmentHelper.getAvailableEnchantmentResults(EnchantmentHelper.java:420) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.item.enchantment.EnchantmentHelper.selectEnchantment(EnchantmentHelper.java:369) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.EnchantmentMenu.getEnchantmentList(EnchantmentMenu.java:212) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.EnchantmentMenu.method_17411(EnchantmentMenu.java:127) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.ContainerLevelAccess.method_17394(ContainerLevelAccess.java:35) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.ContainerLevelAccess$2.evaluate(ContainerLevelAccess.java:22) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.ContainerLevelAccess.execute(ContainerLevelAccess.java:34) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.EnchantmentMenu.slotsChanged(EnchantmentMenu.java:106) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.EnchantmentMenu$1.setChanged(EnchantmentMenu.java:32) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.SimpleContainer.redirect$zmk000$fabric-transfer-api-v1$fabric_redirectMarkDirty(SimpleContainer.java:543) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.SimpleContainer.setItem(SimpleContainer.java:144) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.Slot.set(Slot.java:72) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.Slot.setByPlayer(Slot.java:63) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.EnchantmentMenu.quickMoveStack(EnchantmentMenu.java:267) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.AbstractContainerMenu.doClick(AbstractContainerMenu.java:394) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.world.inventory.AbstractContainerMenu.clicked(AbstractContainerMenu.java:294) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.network.ServerGamePacketListenerImpl.handleContainerClick(ServerGamePacketListenerImpl.java:1682) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.network.protocol.game.ServerboundContainerClickPacket.handle(ServerboundContainerClickPacket.java:58) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.network.protocol.game.ServerboundContainerClickPacket.handle(ServerboundContainerClickPacket.java:13) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.network.protocol.PacketUtils.method_11072(PacketUtils.java:22) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.TickTask.run(TickTask.java:18) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.util.thread.BlockableEventLoop.doRunTask(BlockableEventLoop.java:156) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.util.thread.ReentrantBlockableEventLoop.doRunTask(ReentrantBlockableEventLoop.java:23) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:782) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:164) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.util.thread.BlockableEventLoop.pollTask(BlockableEventLoop.java:130) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:764) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:758) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.util.thread.BlockableEventLoop.runAllTasks(BlockableEventLoop.java:115) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:742) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:675) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]
at net.minecraft.server.MinecraftServer.method_29739(MinecraftServer.java:265) ~[minecraft-common-81b56f91bc-1.20.1-loom.mappings.1_20_1.layered+hash.1899487486-v2.jar:?]