Search code examples
javareflectionminecraftminecraft-forge

Reflection getMethod(...) throws NoSuchMethodException with a different method name


Using myClass.getMethod("func_181057_v") throws exception in the console - "NoSuchMethodException: myClass.v()".
I don't think it's supposed to do that - why is the method name different in thrown exception compared to what I've actually typed in and how can I retrieve that method?

I have tried both .getMethod(..) and .getDelcaredMethod(..) as well as printed .getDeclaredMethods() list and .func_181057_v() was on the list. When I change anything about the name (for example func_181057__v) then the exact typed in method is looked for rather than "v".

My code:

try {
   Class<?> fmlCommonHandlerClass = Class.forName("net.minecraftforge.fml.common.FMLCommonHandler");
   Class<?> minecraftServerClass = Class.forName("net.minecraft.server.MinecraftServer");
   Class<?> playerListClass = Class.forName("net.minecraft.server.management.PlayerList");

   Method getMinecraftServerInstanceMethod = fmlCommonHandlerClass.getDeclaredMethod("getMinecraftServerInstance");
   Method getPlayerListMethod = minecraftServerClass.getDeclaredMethod("getPlayerList");
   Method getPlayersMethod = playerListClass.getDeclaredMethod("func_181057_v");
} catch (Exception exception) {
   throw new RuntimeException(exception);
}

Full code: https://github.com/KittyNath/ReflectionExample
Exact method name is public java.util.List net.minecraft.server.management.PlayerList.func_181057_v()
If you want to execute it you need to compile and install it as a plugin to Mohist server, I'm using version 1.12.2, build 320.
Java 1.8.0_361.

Full exception:

[18:25:56 ERROR]: Error occurred while enabling ReflectionExample v1.0-SNAPSHOT (Is it up to date?)
 java.lang.RuntimeException: java.lang.NoSuchMethodException: net.minecraft.server.management.PlayerList.v()
        at com.example.plugin.reflectionExample.ReflectionExample.onEnable(ReflectionExample.java:20) ~[?:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:177) ~[JavaPlugin.class:?]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:318) [JavaPluginLoader.class:?]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:399) [SimplePluginManager.class:?]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugin(CraftServer.java:477) [CraftServer.class:?]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugins(CraftServer.java:418) [CraftServer.class:?]
        at net.minecraft.server.MinecraftServer.func_71247_a(MinecraftServer.java:383) [MinecraftServer.class:?]
        at net.minecraft.server.dedicated.DedicatedServer.func_71197_b(DedicatedServer.java:315) [nz.class:?]
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:590) [MinecraftServer.class:?]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_361]
Caused by: java.lang.NoSuchMethodException: net.minecraft.server.management.PlayerList.v()
        at java.lang.Class.getMethod(Unknown Source) ~[?:1.8.0_361]
        at com.mohistmc.bukkit.nms.proxy.ProxyClass.getMethod(ProxyClass.java:43) ~[ProxyClass.class:?]
        at com.example.plugin.reflectionExample.ReflectionExample.onEnable(ReflectionExample.java:18) ~[?:?]
        ... 9 more

Solution

  • I was able to resolve the core issue but not the mystery.

    Turns out you can use both .v() and .func_181057_v() on a clean Mohist server. I forgot to remove a plugin called BKCommonLib (version 1.19.3-v3-1512), which appears to remove .func_181057_v(), but leaves v() working.
    Solution - just use .v().

    As to why the logs say that .v() cannot be found when you use .func_181057_v() while BKCommonLib is present on the server - I have no idea. Perhaps it's a Java bug that appears due to BKCommonLib pathing stuff through reflection.
    Feel free to look into it and add comments!