SpongePowered / Mixin

Mixin is a trait/mixin and bytecode weaving framework for Java using ASM
MIT License
1.41k stars 194 forks source link

Anonymous inner class merging is broken in Java 11+ (missing nest mates) #495

Closed Earthcomputer closed 3 years ago

Earthcomputer commented 3 years ago

I was updating my mod to the latest snapshot, which changed Minecraft's minimum Java version from Java 8 to Java 16. I am now encountering an error in this mixin that I wasn't encountering before:

java.lang.IllegalAccessError: class net.minecraft.stat.StatType$Anonymous$52f366c92aa04045b5e9107f50c3aec4 tried to access private field net.minecraft.stat.StatType.stats (net.minecraft.stat.StatType$Anonymous$52f366c92aa04045b5e9107f50c3aec4 and net.minecraft.stat.StatType are in unnamed module of loader net.fabricmc.loader.launch.knot.KnotClassLoader @2a9a538d), (Type net.minecraft.stat.StatType$Anonymous$52f366c92aa04045b5e9107f50c3aec4 (loader: net.fabricmc.loader.launch.knot.KnotClassLoader @2a9a538d) is not a nest member of type net.minecraft.stat.StatType (loader: net.fabricmc.loader.launch.knot.KnotClassLoader @2a9a538d): current type is not listed as a nest member)
    at net.minecraft.stat.StatType$Anonymous$52f366c92aa04045b5e9107f50c3aec4.onUpdate(MixinStatType.java:49)
    at net.minecraft.util.registry.SimpleRegistry.md59df10$lambda$purge$3$5(SimpleRegistry.java:675)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at net.minecraft.util.registry.SimpleRegistry.purge(SimpleRegistry.java:675)
    at net.earthcomputer.multiconnect.protocols.generic.ISimpleRegistry.purge(ISimpleRegistry.java:67)
    at net.earthcomputer.multiconnect.impl.Utils.rename(Utils.java:150)
    at net.earthcomputer.multiconnect.impl.IUtils.rename(IUtils.java:75)
    at net.earthcomputer.multiconnect.protocols.v1_16_5.Protocol_1_16_5.mutateBlockRegistry(Protocol_1_16_5.java:569)
    at net.earthcomputer.multiconnect.protocols.generic.RegistryMutator.runMutations(RegistryMutator.java:51)
    at net.earthcomputer.multiconnect.protocols.generic.AbstractProtocol.doRegistryMutation(AbstractProtocol.java:57)
    at net.earthcomputer.multiconnect.bridge.AbstractRegistryTest.initialize(AbstractRegistryTest.java:34)
    at net.earthcomputer.multiconnect.bridge.RegistryTestLastMajor.beforeAll(RegistryTestLastMajor.java:15)

This mixin merges an anonymous class which accesses the private field stats in the target class via a @Shadow. My guess is that Mixin needs to declare the target class as a nest mate, rather than the mixin class, when merging anonymous classes.

Mumfrey commented 3 years ago

Nesting is supported from Java 11 onwards so should be able to handle this with the current version of ASM, good catch.

Mumfrey commented 3 years ago

@Earthcomputer this should be fixed in current 0.8.4 snapshot now that nesting is properly supported, can you verify please.

Earthcomputer commented 3 years ago

This appears to work as intended on 0.8.4, thanks! For the benefit of anyone reading this in the future, to use inner classes in mixins in Java 11+, you need to remember to set the compatibility level to JAVA_11 in the mixin config.