0

I know there is, like, over 5 questions that ask this but mine is different. I am trying to get all classes in a package and run the tick function. Here is what one of my classes look like:

package com.stupidrepo.mydirectory.yayay;

public class test {
    public void tick(MinecraftClient client) {
        System.out.println(client.player.getName());
    }
}

Here is how I am attempting to call this function:

    ScanResult scanResult = new ClassGraph().acceptPackages("com.stupidrepo.mydirectory.yayay").enableClassInfo().scan();

    private void doIt(MinecraftClient client) {
        scanResult.getAllClasses().forEach((classInfo -> {
//            System.out.println(classInfo.getName());

            try {
                classInfo.loadClass().getMethod("tick", MinecraftClient.class).invoke(null, client);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }));
    }

When I call the doIt function, it keeps giving me the java.lang.NoSuchMethodException error. When I print classInfo.getMethods();, it shows me [public void com.stupidrepo.mydirectory.yayay.test.tick(net.minecraft.client.MinecraftClient)].

So the method is there but java says it isn't. Please help! (By the way the code is for a Fabric MC mod)

WhatTheClown
  • 464
  • 1
  • 7
  • 24
  • 1
    You are calling `getMethod` on `classInfo.loadClass()`, so you have to use `classInfo.loadClass().getMethods()` for verification, not `classInfo.getMethods()` – Holger Dec 12 '22 at 12:55
  • I did that and it's same thing: `[public static void com.stupidrepo.mydirectory.yayay.test.tick(net.minecraft.client.MinecraftClient), ...]` – WhatTheClown Dec 12 '22 at 18:56
  • 1
    So does `MinecraftClient.class` refer to the same class? Does `MinecraftClient.class.getName()` evaluate to the same qualified name `"net.minecraft.client.MinecraftClient"`? And even if so, what does a comparison like `classInfo.loadClass().getMethods()[0].getParameterTypes()[0] == MinecraftClient.class` get you? (If the names match but the classes are considered different, it would indicate an issue of different class loaders) – Holger Dec 13 '22 at 08:48

1 Answers1

0

The method tick is not static. But, when you are invoking method, you are not giving instance (but null), so it try to run the method as static. Such as It's not static, it failed.

To fix it, you can:

  1. Set your method as static, for example:
package com.stupidrepo.mydirectory.yayay;

public class test {
    public static void tick(MinecraftClient client) {
        System.out.println(client.player.getName());
    }
}
  1. Create a new instance like that:
try {
   Class<?> clzz = classInfo.loadClass(); // get class
   Object obj = clzz.getConstructor().newInstance(); // create instance
   clzz.getMethod("tick", MinecraftClient.class).invoke(obj, client); // get and call method
} catch (Exception e) {
   e.printStackTrace();
}
Elikill58
  • 4,050
  • 24
  • 23
  • 45