java - CallObjectMethod/CallObjectMethodV : Ineligible receiver 中的 JNI 错误

标签 java c linux java-native-interface

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

下面是我绕过C代码,在命令行通过Java调用Method返回的数据

$ java ClassName "This" "is" "my" "test" "string"
Exception on SomethingElse.Method: [Function: DifferentMethod]ExceptionClassException: ExceptionClassExceptionException: [Function: CFBDynamicMessage::getCodePage]codePageBytes is NULL, for UTF-8

Returned String -- data I'm trying to get
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 JNI error in CallObjectMethod/CallObjectMethodV: Ineligible receiver JVMJNCK080E Error detected in the outermost frame of an attached thread JVMJNCK023E JNI error detected. Continuing... Segmentation fault (core dumped)

这是 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 告诉我所有我无法观看的体育赛事因为我正在处理这个问题。

最佳答案

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

关于java - CallObjectMethod/CallObjectMethodV : Ineligible receiver 中的 JNI 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29308068/

相关文章:

java - Android A* 寻路无限循环?

java - 从java对象获取WEKA实例

c - 为什么 travis-ci.org 总是显示 [ build : failing ] badge?

Linux TCP 在重负载下奇怪地没有响应

linux - 如何将 linux 链接器中的 -lXi 标志转换为适当的库?

javascript - 使用 AJAX 验证 JSP 页面中的验证码

java - 写入包中的 .txt 文件

c - 如何将函数下的多个相同类型循环映射到LLVM IR中生成的基本 block ?

c - 为什么当我试图找到结构指针的差异时会出现垃圾值?

linux - 使用 "aws s3"实用程序在 S3 中获取从现在起 1 个月前的文件列表