线程“AWT-EventQueue-0”中的异常java.lang.NoSuchMethodError

时间:2012-10-03 14:21:56

标签: java c java-native-interface

我尝试在java代码中获取该方法的jMethodID,但是当我调用此特定函数时,会抛出异常:

Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: displayKeyStrokes
at org.suhail.keylogger.HelperClasses.NativeMethods.initializeJNIVars(Native Method)
at org.suhail.keylogger.GUI.MainGUI.jMenuItem1ActionPerformed(MainGUI.java:356)
.
.
.

我不明白这个的原因。以下是从java方法调用的 C 代码段:

void Java_org_suhail_keylogger_HelperClasses_NativeMethods_initializeJNIVars
(JNIEnv *env, jobject obj) {
 jclass cls = (*env)->GetObjectClass(env,obj);
 callBackToDeliverKeyStroke = (*env)->GetMethodID(env,cls,"displayKeyStrokes","()V");
 object = (*env)->NewGlobalRef(env,obj);
 if(object == NULL | callBackToDeliverKeyStroke == NULL | cls == NULL) {
    printf("Initialization error...One of the variable is Null\n");
 }
}

这是java代码中名为displayKeyStrokes的方法:

 public void displayKeyStrokes() {
    System.out.println("Java Message : A Key has been pressed");
}

我得到例外的原因是什么?

编辑:

调用JNI代码的Java代码:

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {                                           
    jMenuItem1.setEnabled(false);
    jMenuItem2.setEnabled(true);
    try {
       System.loadLibrary("Dll_PKeylogger"); // Load the dll written to listen to the tapping of keys
       nativeMethods.initializeJNIVars(); // CALL
    }catch(Exception exc) {
        exc.printStackTrace();
    }
}

NativeMethods Class (声明本机方法)

package org.suhail.keylogger.HelperClasses;

public class NativeMethods {

 public native void initializeJNIVars();
 public native void unregisterHook(); 

}

注意: 我在另一个名为initializeJNIVars的类的对象上调用方法NativeMethods,方法jMenuItem1ActionPerformed是每当事件发生时从匿名内部类调用:

        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jMenuItem1ActionPerformed(evt);
        }
    });

2 个答案:

答案 0 :(得分:1)

你说:

  

jMenuItem1ActionPerformed是从一个匿名类调用的,该类与displayKeyStrokes在同一个类中。是的jMenuItem1ActionPerformed与jMenuItem1ActionPerformed属于同一个类,除非它是从匿名内部类调用的,如下所示

那可能是你的问题。存在于匿名内部类中的jMenuItem1ActionPerformed很重要,这意味着它与jMenuItem1ActionPerformed位于不同的类中,并且当您尝试从JNI C代码中获取方法ID时,需要将其考虑在内。

考虑为您的initializeJNIVars()方法提供一个参数,该参数接受外部类的实例,然后将该实例传递给参数,并在调用GetMethodID(...)时使用它。请注意,您必须将参数传递为OuterClassName.this

答案 1 :(得分:0)

您获得的例外描述是:

  

如果应用程序尝试调用类的指定方法,则抛出该异常   (静态或实例),该类不再具有定义   那种方法。

     

通常,编译器会捕获此错误;这个错误只能   如果类的定义不兼容,则在运行时发生   改变。

您的代码线程是否分开?当你试图调用这个方法时,一个已经死的线程是否有可能加载displayKeyStrokes方法?