SpongePowered / Mixin

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

Mixin throws NullPointerException when using array redirect without args="array=get" with no information about what the problem is #166

Closed Barteks2x closed 7 years ago

Barteks2x commented 7 years ago

The problem isn't that it crashes, but that it doesn't show any information about which redirect causes the issue, in my case the exception looked like this:

/*******************************************************************************************************************/
/*                                                  Invalid Mixin                                                  */
/*-----------------------------------------------------------------------------------------------------------------*/
/*     Action : APPLY                                                                                              */
/*      Mixin : cubicchunks.asm.mixin.core.common.MixinChunk_Cubes                                                 */
/*     Config : cubicchunks.mixins.core.json                                                                       */
/*      Phase : DEFAULT                                                                                            */
/*-----------------------------------------------------------------------------------------------------------------*/
/*     org.spongepowered.asm.mixin.transformer.throwables.InvalidMixinException                                    */
/*-----------------------------------------------------------------------------------------------------------------*/
/*     Unexpecteded NullPointerException whilst applying the mixin class: null                                     */
/*-----------------------------------------------------------------------------------------------------------------*/
/*         org.spongepowered.asm.mixin.transformer.MixinApplicatorStandard.apply(MixinApplicatorStandard.java:266) */
/*         org.spongepowered.asm.mixin.transformer.TargetClassContext.applyMixins(TargetClassContext.java:280)     */
/*         org.spongepowered.asm.mixin.transformer.MixinTransformer.apply(MixinTransformer.java:817)               */
/*         org.spongepowered.asm.mixin.transformer.MixinTransformer.applyMixins(MixinTransformer.java:787)         */
/*         org.spongepowered.asm.mixin.transformer.MixinTransformer.transform(MixinTransformer.java:592)           */
/*         org.spongepowered.asm.mixin.transformer.MixinTransformer$Proxy.transform(MixinTransformer.java:183)     */
/*         net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279)               */
/*         net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176)                     */
/*         java.lang.ClassLoader.loadClass(ClassLoader.java:424)                                                   */
/*         java.lang.ClassLoader.loadClass(ClassLoader.java:357)                                                   */
/*         java.lang.Class.getDeclaredMethods0(Native Method)                                                      */
/*         java.lang.Class.privateGetDeclaredMethods(Class.java:2701)                                              */
/*         java.lang.Class.getDeclaredMethod(Class.java:2128)                                                      */
/*         net.minecraftforge.fml.common.eventhandler.EventBus.register(EventBus.java:94)                          */
/*         net.malisis.core.util.blockdata.BlockDataHandler.<init>(BlockDataHandler.java:84)                       */
/*         net.malisis.core.util.blockdata.BlockDataHandler.<clinit>(BlockDataHandler.java:73)                     */
/*         java.lang.Class.forName0(Native Method)                                                                 */
/*         java.lang.Class.forName(Class.java:264)                                                                 */
/*         net.malisis.core.MalisisCore.autoLoadClasses(MalisisCore.java:198)                                      */
/*         net.malisis.core.MalisisCore.preInit(MalisisCore.java:237)                                              */
/*         sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                           */
/*         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   */
/*         java.lang.reflect.Method.invoke(Method.java:498)                                                        */
/*         net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:643)             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                           */
/*         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   */
/*         java.lang.reflect.Method.invoke(Method.java:498)                                                        */
/*         com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)                         */
/*         com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) */
/*         com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)                                         */
/*         com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)                             */
/*         com.google.common.eventbus.EventBus.post(EventBus.java:275)                                             */
/*         net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:246)           */
/*         net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:224)             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                           */
/*         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   */
/*         java.lang.reflect.Method.invoke(Method.java:498)                                                        */
/*         com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)                         */
/*         com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) */
/*         com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)                                         */
/*         com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)                             */
/*         com.google.common.eventbus.EventBus.post(EventBus.java:275)                                             */
/*         net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:147)            */
/*         net.minecraftforge.fml.common.Loader.preinitializeMods(Loader.java:628)                                 */
/*         net.minecraftforge.fml.client.FMLClientHandler.beginMinecraftLoading(FMLClientHandler.java:268)         */
/*         net.minecraft.client.Minecraft.init(Minecraft.java:478)                                                 */
/*         net.minecraft.client.Minecraft.run(Minecraft.java:387)                                                  */
/*         net.minecraft.client.main.Main.main(Main.java:118)                                                      */
/*         sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                           */
/*         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   */
/*         java.lang.reflect.Method.invoke(Method.java:498)                                                        */
/*         net.minecraft.launchwrapper.Launch.launch(Launch.java:135)                                              */
/*         net.minecraft.launchwrapper.Launch.main(Launch.java:28)                                                 */
/*         sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)                                             */
/*         sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)                           */
/*         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)                   */
/*         java.lang.reflect.Method.invoke(Method.java:498)                                                        */
/*         net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)                           */
/*         GradleStart.main(GradleStart.java:26)                                                                   */
/*******************************************************************************************************************/
Mumfrey commented 7 years ago

Hmm weird, can you gist/link the mixin in question.

Barteks2x commented 7 years ago

I already fixed the problem but it shouldn't be hard to re-create it. As I said, the problem isn't that it's crashing, because the mixin is not valid. All I did was skip args = "array=get" in redirect.

This mixin shows that confusing crash:


@Mixin(Chunk.class)
public abstract class MixinChunk_Cubes {

    @Redirect(
            method = "getEntitiesWithinAABBForEntity",
            at = @At(value = "FIELD", target = "Lnet/minecraft/world/chunk/Chunk;entityLists:[Lnet/minecraft/util/ClassInheritanceMultiMap;"/*, args = "array=get"*/)
    )
    private ClassInheritanceMultiMap<Entity> getEntAABBFor_CubicChunks_EntityListsGetRedirect(ClassInheritanceMultiMap<Entity>[] array, int index) {
        return array[index];
    }
}

It should crash, but also shoudl tell me which redirect it is.

Mumfrey commented 7 years ago

Right, yes that makes sense. It shouldn't crash there though if that argument is omitted, and it certainly shouldn't let an NPE propagate that far up the stack without being caught by the injector. There are two problems it seems: 1- missing a null check on that arg and 2- the cause is being omitted when pretty-printing the error. Both of these are fixable.

Barteks2x commented 7 years ago

Also, does it really have to repeat the stacktrace in different forms 6 times in total?