2009-04-28 27 views
3

我想檢索一個錯誤消息,解釋爲什麼jvm加載失敗。從這裏提供的例子:無法通過JNI加載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或標準錯誤。我相信我需要捕獲stdout和stderr來獲得我正在尋找的錯誤(除非有更簡單的方法)。我使用C++進行編碼,所以如果有人能夠展示一種方法將錯誤捕獲到字符串流中,那將是理想的。

感謝, 蘭迪

回答

4

我能得到什麼,我需要通過這裏所描述的「vfprintf」選項:

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(); 

同樣有趣的是,我不能爲我的生活捕獲stdout或stderr正確與任何freopen函數或DUP2花樣。我可以加載我的自己的 DLL並正確重定向,但不是JVM。無論如何,這是更好的方式,因爲我想在內存中的錯誤,而不是在文件中。

+0

到sun.java.com的鏈接不再有效,並且在代碼片段中沒有聲明函數`setError()`。任何有關在哪裏可以找到它的提示? – mgd 2013-01-09 15:24:40

0

當我寫這個代碼我也將獲得通過標準輸出/標準錯誤的錯誤。

在您的過程中重定向stdout/stderr的最佳方式是使用freopen。這裏有一個專門關於該主題的StackOverflow question

然而,一旦調用傳遞,您將有一個JNIEnv,以及所有的錯誤檢查可以並且應該通過調用JNIEnv::ExceptionOccurred(),這將可能會返回一個Throwable對象,然後就可以用你的JNI代碼詢問來完成。

0

在獲取stdout和stderr之後,無論如何需要將-Xcheck:jni添加到您的jvm命令行以從jvm獲取額外的jni相關警告。

相關問題