FarmersDelightASM appears to be classloading class_1935 before the mixin processor starts
Closed this issue ยท 9 comments
Minecraft version
1.20.1
Farmer's Delight version
2.1.4
Fabric Loader version
Quilt Loader 0.26.4-beta.5 (Fabric Loader 0.16.2)
Fabric API version
QFAPI 7.6.0 (Fabric API 0.92.2)
Description
I've noticed that net.minecraft.class_1935 (ItemConvertible / ItemLike) is being classloaded before the mixin processor starts. This can lead to weird issues with mixins not being applied to that class later on.
Apparently, this is due to Farmer's Delight Refabricated.
[53.781s][info][class,load] vectorwing.farmersdelight.FarmersDelightASM source: quilt.zfs://farmersdelight-1.20.1-2.1.4refabricated.i0:0/
[53.781s][info][class,load] net.minecraft.class_1935 source: quilt.zfs://minecraft-1.20.1.i0:0/
Though I'm not entirely sure what in FarmersDelightASM is causing this issue... it probably has something to do with a synthetic method created by a lambda. I don't have the bytecode in front of me.
Steps to reproduce
- Start the game
Mod list
- Fabric API
- Farmer's Delight Refabricated
Logs
N/A
Minimal instance
- I have tested this on a minimal instance
Performance and shader mods
- I am using performance or shader mods
Mhm, I'll look into a fix for this when I get to making more fixes for 1.20.1, thanks for the report.
I think that the true fix would be to either
a. remove recipe book code and enum extensions. This is a solution that others may find negligible, but as somebody who believes that with Farmer's Delight being a simple vanilla-like mod quite benefits from the recipe book as a thing for players who are less familiar with modded, this isn't ideal for me.
b. implement a custom recipe book menu/screen handler. I'm definitely going to look into this for my own mods, so I'd imagine refabricated could borrow from my own findings here.
I've come to two conclusions about this.
- It was caused by the enchantment enum Fabric ASM that was later removed.
- The confusion of if it existed was caused by Crayfish's former broken recipe book Fabric ASM.
I believe the issue actually involves these lambda statements:
I say this because it appears that the synthetic methods resulting from these lambdas would have a return type of ItemStack[] - or, more likely (given the presence of this issue), ItemLike[] - causing unintended classloading (during class verification or resolution, I think).
Here is the bytecode for that class, as decompiled by IntelliJ's built-in bytecode viewer: https://gist.github.com/unilock/83fc6e2a3a067319ff3731bcdc6721c2
I'm not familiar enough with the Java classloading process to know where class_1935 could be statically loaded in all this :s
I believe the issue actually involves these lambda statements:
FarmersDelightRefabricated/src/main/java/vectorwing/farmersdelight/FarmersDelightASM.java
Lines 24 to 27 in ffaaa91
ClassTinkerers.enumBuilder(recipeBookCategoriesTarget, itemStackParamType).addEnum(COOKING_SEARCH_RECIPE_BOOK_CATEGORY, () -> new Object[]{new ItemStack[]{new ItemStack(Items.COMPASS)}}).build();
ClassTinkerers.enumBuilder(recipeBookCategoriesTarget, itemStackParamType).addEnum(COOKING_MEALS_RECIPE_BOOK_CATEGORY, () -> new Object[]{new ItemStack[]{new ItemStack(ModItems.VEGETABLE_NOODLES.get())}}).build();
ClassTinkerers.enumBuilder(recipeBookCategoriesTarget, itemStackParamType).addEnum(COOKING_DRINKS_RECIPE_BOOK_CATEGORY,() -> new Object[]{new ItemStack[]{new ItemStack(ModItems.APPLE_CIDER.get())}}).build();
ClassTinkerers.enumBuilder(recipeBookCategoriesTarget, itemStackParamType).addEnum(COOKING_MISC_RECIPE_BOOK_CATEGORY, () -> new Object[]{new ItemStack[]{new ItemStack(ModItems.DUMPLINGS.get()), new ItemStack(ModItems.TOMATO_SAUCE.get())}}).build();I say this because it appears that the synthetic methods resulting from these lambdas would have a return type of
ItemStack[]- or, more likely (given the presence of this issue),ItemLike[]- causing unintended classloading (during class verification or resolution, I think).
Mhm, thanks for the investigation. I'll see if I can wrap it into a method that returns Object[], if that'd work.
Holy shiit. I finally figured it out.
- return () -> new Object[]{new ItemStack[]{new ItemStack((Items.COMPASS)}};
+ return () -> new Object[]{new ItemStack[]{new ItemStack(((Supplier<Item>)() -> Items.COMPASS).get())}};Classloading shenanigans here would load ItemLike early from the Items class, which I realise only affected the compass reference. So the fix was to wrap Items#COMPASS into a supplier.