使用Java Reflection时的NoSuchMethodException

时间:2015-11-09 10:15:15

标签: java reflection

我不知道出了什么问题但是我使用反射来调用类中的方法。

以下是我正在做的事情:

已经定义了ClassLoader和MAIN_PATH。我把它剪掉了 ClassLoader是一个URLClassLoader,它有一个JAR文件的URL。 MAIN_PATH是org.example.BlahClass

Class mainClass = classLoader.loadClass(MAIN_PATH);
Class[] params = new Class[] { MyClass.class };
Method method = mainClass.getDeclaredMethod("onEnable", params);
MyClass myClass = new MyClass();
method.invoke(null, myClass);

该方法在此类中声明:

public class BlahClass implements SomeInterface {
     public void onEnable(MyClass myClass){}
     public void onDisable(){}
}

完整的堆栈跟踪:

    [17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: java.lang.NoSuchMethodException: org.example.Main.commenced(org.rocket.plugin.events.PluginInitializationEvent)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at java.lang.Class.getDeclaredMethod(Class.java:2130)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at org.rocket.plugin.java.RocketPluginLoader.func_01321(RocketPluginLoader.java:42)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at org.rocket.RocketMod.setup(RocketMod.java:41)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at java.lang.reflect.Method.invoke(Method.java:497)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:537)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at java.lang.reflect.Method.invoke(Method.java:497)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.post(EventBus.java:275)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:212)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:190)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at java.lang.reflect.Method.invoke(Method.java:497)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at com.google.common.eventbus.EventBus.post(EventBus.java:275)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:119)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.Loader.serverStarting(Loader.java:781)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraftforge.fml.common.FMLCommonHandler.handleServerStarting(FMLCommonHandler.java:319)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraft.server.dedicated.DedicatedServer.startServer(DedicatedServer.java:289)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:500)
[17:58:11] [Server thread/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]:     at java.lang.Thread.run(Thread.java:745)

在此处查看真实来源:https://gitlab.com/PizzaCrust/Rocket/blob/master/Rocket/src/org/rocket/plugin/java/RocketPluginLoader.java

1 个答案:

答案 0 :(得分:0)

NoSuchMethodException只能由mainClass.getDeclaredMethod("onEnable", params)抛出。这意味着类mainClass没有名为onEnable的方法,它采用MyClass类型的单个参数。

导致此问题的唯一一行是classLoader.loadClass(MAIN_PATH),我的打赌是你没有加载你认为正在加载的课程,即你定义MAIN_PATH = "org.example.BlahClass"但你的班级BlahClass不在包org.example中。另一个原因可能与classLoader有关 - 您还没有展示如何初始化它。

尝试添加以下支票:

if (mainClass == org.example.BlahClass.class) {
    System.out.println("It's ok!");
} else {
    System.out.println("It's not ok!");
}

另一个原因可能与params有关。 getDeclaredMethod的第二个参数是var-arg - Class<?>... parameterTypes。你传递一个Class[]类型的参数,所以它应该没问题,因为var-arg只是一个数组。但是,根据JDK,它可能期望第一个参数实际上是一个数组,并且您正在尝试使用以下签名获取方法:onEnable(java.lang.Class[])而不是(不存在)。试着这样做:

mainClass.getDeclaredMethod("onEnable", MyClass.class)