java - 当无法通过 JNI 加载 JVM 时如何获得错误消息?

标签 java c++ jvm java-native-interface jvm-arguments

我想检索解释 jvm 加载失败原因的错误消息。来自此处提供的示例:

http://java.sun.com/docs/books/jni/html/invoke.html

我提取了这个例子:

 /* Create the Java VM */
 res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

 if (res < 0) {
     // retrieve verbose error here?
     fprintf(stderr, "Can't create Java VM\n");
     exit(1);
 }

在我的具体情况下,我在 vm_args 中提供了无效的参数,并希望看到我在命令行上得到的内容:“无法识别的选项:-foo=bar”

在进一步测试中,jvm 似乎正在将我想要的消息放入 stdout 或 stderr。我相信我需要捕获 stdout 和 stderr 才能得到我正在寻找的错误(当然除非有更简单的方法)。我正在用 C++ 编码,所以如果有人可以展示一种将错误捕获到字符串流中的方法,那将是理想的。

谢谢, 兰迪

最佳答案

通过使用此处描述的“vfprintf”选项,我能够得到我需要的东西:

https://web.archive.org/web/20111229234347/http://java.sun.com/products/jdk/faq/jnifaq-old.html

虽然我用的是jdk1.2选项。此代码片段总结了我的解决方案:

static string jniErrors;

static jint JNICALL my_vfprintf(FILE *fp, const char *format, va_list args)
{
    char buf[1024];
    vsnprintf(buf, sizeof(buf), format, args);
    jniErrors += buf;
    return 0;
}

...

JavaVMOption options[1];
options[0].optionString = "vfprintf";
options[0].extraInfo = my_vfprintf;

JavaVMInitArgs vm_args;
memset(&vm_args, 0, sizeof(vm_args));
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.version = JNI_VERSION_1_4;
vm_args.ignoreUnrecognized = JNI_FALSE;

JNIEnv env;
JavaVM jvm;

jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

if (res != JNI_OK)
    setError(jniErrors);

jniErrors.clear();

同样有趣的是,我终生无法使用任何 freopen 或 dup2 技巧正确捕获 stdout 或 stderr。我可以加载我的自己的 dll 并正确重定向,但不能加载 jvm。无论如何,这样更好,因为我想要内存中的错误而不是文件中的错误。

关于java - 当无法通过 JNI 加载 JVM 时如何获得错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/798876/

相关文章:

java - 从文本域中读取值

java - 如何使用 JDBC 和 PostgreSQL 获取大数据

java - 用于自定义文件类型的 Android Intent Filter

c++ - 允许 QGraphicsView 移出场景

c++ - chrono::high_resolution_clock 延迟不一致

matlab - 用于在 JVM 上进行富有表现力的、功能丰富的数值计算的工具

c# - 为什么 Sun 不做 C# 到 Java 字节码编译器?

java - 打印HashMaps : Map. Entry或java8的HashMap

python - 如何使用 python 调用 c++ 函数

Java Plug-In 启动更改以应对最近的安全漏洞