CallObjectMethod / CallObjectMethodV中的JNI错误:不合格的接收器

时间:2015-03-27 18:47:59

标签: java c linux java-native-interface

我有一个通过JNI调用接口调用Java模块的C例程。我在使用C模块和JNI时对Java方法的调用返回NULL字符串的问题,但是当我在命令行使用Java时,Java模块返回错误和默认值值。

这是我绕过C代码并在命令行中通过Java调用Method

时返回的数据
  

$ java ClassName" This" "是" "我" "测试" "串"
  SomethingElse.Method上的异常:[Function:DifferentMethod] ExceptionClassException:ExceptionClassExceptionException:[Function:CFBDynamicMessage :: getCodePage] codePageBytes为NULL,UTF-8

     

返回字符串 - 我试图获得数据   0.0 | | 0.0 | | 0.0 || | 0.0 | 0 | | 0.0 | | || 0.0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 ||

我需要获取返回的字符串,即使在java端出现错误也是如此。为了试着看看C和JNI中发生了什么,我调高了JNI的调试级别:

options[1].optionString = "-Xdebug"; /* print JNI-related messages */
options[2].optionString = "-Xlog:all";
// this next line allows us to continue processing after the Java
// error.  Unfortunately the code then SegFaults further on.
options[3].optionString = "-Xcheck:jni:nonfatal";
options[4].optionString = "-verbose:jni";

JNI启动JVM,找到类和方法并构建我需要传递给方法的Java字符串,但是当我尝试执行该方法时,我收到以下错误:

  

JVMJNCK048E CallObjectMethod / CallObjectMethodV中的JNI错误:不合格的接收者   JVMJNCK080E在连接线程的最外层帧中检测到错误   JVMJNCK023E检测到JNI错误。继续...   分段错误(核心转储)

这是C代码(为简洁起见,我正在删除一些错误检查和空格):

res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
cls = (*env)->FindClass(env, "GenericClassName");
mid = (*env)->GetMethodID(env, cls, "execute", "(Ljava/lang/Object;)Ljava/lang/Object;");
jstr = (*env)->NewStringUTF( env, "This|is|my|test|string|");

// This next line is the one that throws the ineligible receiver error
jstring resultStr = (*env)->CallObjectMethod(env, cls, mid, jstr);

// ExceptionOccurred(env) is false; no errors are displayed
if ((*env)->ExceptionOccurred(env)) {
  (*env)->ExceptionDescribe(env);
  (*env)->ExceptionClear(env);
}

const char *nativeString = (*env)->GetStringUTFChars(env, resultStr, JNI_FALSE);

// This next line calls the SegFault
fprintf(stdout, "%s\n", *nativeString);

我已经使用gdb来查看SegFault创建的核心转储,以下是我认为的相关结果:

  

print nativeString
  $ 1 = 0x8dfaa80" [Ljava.lang.Class; @ 34ca34ca"
   print * nativeString
  $ 2 = 91' ['

这是我调用的java方法的定义:

public Object execute (Object args) throws Exception { ... }

我们将非常感谢您对此问题提供的任何帮助或见解。当我尝试使用谷歌获取不合格的接收器错误时,我得到了一堆关于足球的链接,但在JNI或Java中没有任何内容。我花了最近几天在Stack Overflow网站上搜索,尽管有一些很有希望的问题,但它们都与Android有关,并没有为解决我的问题提供任何额外帮助。

作为最后两个笔记,即使您无法提供帮助,也要感谢您阅读此内容,我的环境是64位RHEL服务器,但C代码和JVM都作为32位应用程序运行。

TL; DR-C通过JNI调用Java方法,我得到一个错误代码(CallObjectMethod / CallObjectMethodV中的JNI错误:不合格的接收者),这导致Google告诉我所有关于我能做的所有运动的信息。因为我正在研究这个问题。

1 个答案:

答案 0 :(得分:1)

你提供的是一个类而不是一个对象。所以你试图调用Class<GenericClassName>.execute(Object arg).你需要一个类的实例。