2009-04-28 13 views
3

jvmのロードに失敗した理由を説明するエラーメッセージを取得したいとします。ここで提供される例から:私はvm_argsで無効な引数を提供していると私はに乗るものを見ることを期待する私の特定のケースでJNI経由でJVMをロードできないときにエラーメッセージを受け取るにはどうすればよいですか?

/* 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); 
} 

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

私はこの例を抽出しましたコマンドライン: "認識できないオプション:-foo = bar"

さらにテストすると、jvmが標準出力または標準エラー出力にしたいメッセージを表示しているようです。私は、私が探しているエラーを得るためにstdoutとstderrをキャプチャする必要があると信じています(もちろん単純な方法はありません)。私はC++でコーディングしているので、もし誰かがエラーをキャプチャして理想的な文字列にすることができたら、

おかげで、 ランディ

答えて

4

私は「また、vfprintf」オプションを使用して、必要なものを得ることができたが、ここで説明:

http://java.sun.com/products/jdk/faq/jnifaq-old.html

を私はJDK 1.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のトリックのいずれかで正しく標準出力や標準エラー出力をキャプチャすることができなかったということであった:このコードスニペットは、私の解決策をまとめました。私は自身の dllを読み込み、正しくリダイレ​​クトできますが、jvmはリダイレクトできませんでした。とにかく、私はファイル内ではなくメモリ内のエラーを欲しかったので、この方がいいです。

+0

sun.java.comへのリンクは機能しなくなり、 'setError()'関数はスニペットで宣言されていません。それを見つけるためのヒント? – mgd

+0

[old-faq](http://192.9.162.55/products/jdk/faq/jnifaq-old.html)という長い時間が経ちましたが、これは同じリンクに見えます。 setErrorメソッドは私たちが定義したちょうどヘルパーメソッドでした。 jniErrors文字列には、その時点のエラーメッセージが含まれます。 – randy909

+0

ポインタありがとう。回答のリンクを更新する必要がありますか? – mgd

0

私はこのコードを書いたとき、私はまた、標準出力/標準エラー出力を経由してエラーになるだろう。

stdout/stderrをプロセスにリダイレクトする最良の方法は、freopenを使用することです。その件について具体的にはStackOverflow questionです。そのコールが渡された後

はしかし、あなたがしてJNIEnvを持つことになりますし、すべてのさらなるエラーチェックは、あなたが、あなたのJNIコードを調べることができますThrowableオブジェクトを返すことがありますこれは、JNIEnv::ExceptionOccurred()を呼び出すことによって行われるべきであることができます。

0

とにかく必要なstdoutとstderrを取得したら、jvmコマンドラインに-Xcheck:jniを追加して、jvmから追加のjni関連の警告を取得します。

関連する問題