JNI GetMethodID线程“main”中的异常java.lang.NoSuchMethodError:<method>

时间:2016-09-06 03:00:43

标签: java java-native-interface

我正在尝试使用posix_memalign从java.io.Reader读取到在C中分配的char缓冲区。

在我的java代码中

  public class LowerCaseTokenizer
{

 public native void Initialize(Reader input) throws IOException;
 public static String example = "XY&Z Corporation - xyz@example.com";

  public LowerCaseTokenizer(Reader input) throws IOException {

   Initialize(input);
  }

    public static void main(String[] args) throws IOException {

        System.loadLibrary("LowerCaseTokenizer");

        LowerCaseTokenizer sample = new LowerCaseTokenizer(new StringReader(example));}

}

对于C ++代码,我做了以下内容。

JNIEXPORT void JNICALL Java_LowerCaseTokenizer_Initialize(JNIEnv *env, jobject obj1, jobject obj2){

jclass input_class = env->GetObjectClass(obj2);
  jmethodID jread_method = env->GetMethodID(input_class, "read", "(C[II)I" );

  print_object_class_name(env, obj2);

}

问题是我得到了

Calling class is: java.io.StringReader // print_object_class_name(env, obj2); 
Exception in thread "main" java.lang.NoSuchMethodError: read

获取此方法的目的是我想从读取器读取用C ++分配的缓冲区(我在分配缓冲区时考虑到每个字符问题的UTF16(16位))。

由于这个错误,我没有检查读取缓冲区实现是否会起作用。但是一些见解不会受到伤害。

do{
  numCharsRead  = env->CallIntMethod(obj2, jread_method ,source_ptr ,off , len);

  }while(numCharsRead != -1);

2 个答案:

答案 0 :(得分:2)

java.lang.NoSuchMethodError表示Java无法找到名称和签名与您请求的匹配的方法。您的要求是:

env->GetMethodID(input_class, "read", "(C[II)I" );

您可以使用javap

获取正确的类型签名
> javap -s -classpath rt.jar java/io/StringReader
  ...
  public int read(char[], int, int) throws java.io.IOException;
    Signature: ([CII)I

但您使用的是(C[II)I而不是([CII)I ---您的[错位。

答案 1 :(得分:0)

读取功能的签名不是“(C [II] I”)。

我用c写的不是cpp。但我认为你只需要替换read方法的签名。

/*
* Class:     com_neohope_jni_test_LowerCaseTokenizer
* Method:    Initialize
* Signature: (Ljava/io/Reader;)V
*/
JNIEXPORT void JNICALL Java_com_neohope_jni_test_LowerCaseTokenizer_Initialize
(JNIEnv *env, jobject caller, jobject reader)
{
    getJniClassName(env, caller);
    getJniClassName(env, reader);

    jclass clazz = (*env)->GetObjectClass(env, reader);
    if (clazz == NULL)return;

    jmethodID midRead01 = (*env)->GetMethodID(env, clazz, "read", "()I");
    jmethodID midRead02 = (*env)->GetMethodID(env, clazz, "read", "([C)I");
    jmethodID midRead03 = (*env)->GetMethodID(env, clazz, "read", "([CII)I");

    //do your job here
    if (midRead01 == NULL)return;
    jint ret = (*env)->CallIntMethod(env, reader, midRead01);
    printf("%l", ret);
}