質問
JVMTIの上で使用できる素敵なJava APIはありますか?
解決
OK ...試してみました...期待どおりに機能するようです....実際の生活では、VMINITコールバックは、C JVMTIインターフェイスを反映したインターフェイスを実装するクラスのインスタンスを返します。このインスタンスを保存して、イベントで必要に応じて電話をかけます....さらに、VMINIT Javaが返される前に、機能とコールバックと登録イベントなどをセットアップします。 ...それはただそれを入力するだけのケースです....あなたが強いケースがあるならば、私は週末にそれをすることができました:-)
次のコードはこれを生成します:
C:vminit、Javaメソッドをコールバックする準備をしています
Java:jvmtiコールバッククラス、vminit()。
C:vminit、コールバックJavaメソッドは正常に返されました
Java:そして最後に...こんにちは、私はJava Mainです
package com.stackoverflow;
public class JVMTICallback {
public static void VMInit() {
System.out.println("Java:\tJVMTI callback class, VMInit().");
}
public static void main(String[] args) {
// This main is only here to give us something to run for the test
System.out.println("Java:\tAnd Finally... Hello, I'm the Java main");
}
}
とc
#include <stdlib.h>
#include "jvmti.h"
jvmtiEnv *globalJVMTIInterface;
void JNICALL
vmInit(jvmtiEnv * jvmti_env, JNIEnv * jni_env, jthread thread)
{
printf("C:\tVMInit, preparing to callback Java method\n");
char *className = "com/stackoverflow/JVMTICallback";
char *methodName = "VMInit";
char *descriptor = "()V";
jclass callbackClass = (*jni_env)->FindClass(jni_env, className);
if (!callbackClass) {
fprintf(stderr,"C:\tUnable to locate callback class.\n");
return;
}
jmethodID callbackMethodID = (*jni_env)->GetStaticMethodID(jni_env, callbackClass, methodName, descriptor);
if (!callbackMethodID)
{
fprintf(stderr, "C:\tUnable to locate callback VMInit method\n");
return;
}
(*jni_env)->CallStaticVoidMethodV(jni_env, callbackClass, callbackMethodID, NULL);
printf("C:\tVMInit, callback Java method returned successfully\n");
}
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM * jvm, char *options, void *reserved)
{
jint returnCode = (*jvm)->GetEnv(jvm, (void **) &globalJVMTIInterface,
JVMTI_VERSION_1_0);
if (returnCode != JNI_OK)
{
fprintf(stderr,
"The version of JVMTI requested (1.0) is not supported by this JVM.\n");
return JVMTI_ERROR_UNSUPPORTED_VERSION;
}
jvmtiEventCallbacks *eventCallbacks;
eventCallbacks = calloc(1, sizeof(jvmtiEventCallbacks));
if (!eventCallbacks)
{
fprintf(stderr, "Unable to allocate memory\n");
return JVMTI_ERROR_OUT_OF_MEMORY;
}
eventCallbacks->VMInit = &vmInit;
returnCode = (*globalJVMTIInterface)->SetEventCallbacks(globalJVMTIInterface,
eventCallbacks, (jint) sizeof(*eventCallbacks));
if (returnCode != JNI_OK)
{
fprintf(stderr, "C:\tJVM does not have the required capabilities (%d)\n",
returnCode);
exit(-1);
}
returnCode = (*globalJVMTIInterface)->SetEventNotificationMode(
globalJVMTIInterface, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, (jthread) NULL);
if (returnCode != JNI_OK)
{
fprintf(
stderr,
"C:\tJVM does not have the required capabilities, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT (%d)\n",
returnCode);
exit(-1);
}
return JVMTI_ERROR_NONE;
}
他のヒント
JVMTIは、Java APIを上に置くために構築されていません。 JVM Tiの定義自体は次のように述べています。
JVMツールインターフェイス(JVM TI)は ネイティブライブラリがイベントをキャプチャし、Javaプラットフォーム用のJava仮想マシン(JVM)を制御できるようにする標準のネイティブAPI。
ネイティブAPIがイベントとコントロールをキャプチャするために構築されたため、その上にAPIがあるとは思いません。あなたが達成しようとしていることを説明してもらえますか?
JVM Tiの上にあるJava APIを知りません。
私は周りを検索しましたが、残念ながらJVMTIの上にJava APIライブラリが見つかりませんでした。あなたは運が悪いようです。
しかし、あなたができることは、JavaコードからネイティブLibを呼び出すことです。私はC/C ++があまり得意ではありませんが、JVMTIドキュメントからは、から小さな共有ライブラリを構築することが可能であることがわかります ヘッダーを提供. 。その後、JNA **を使用して呼び出すことができます。ネイティブライブラリの周りに素敵なAPIラッパーを提供します。
で例を見てください JNAはページを開始します
このページもリンクします jnaerator 必要なすべてのJavaバインディングを生成できます。
このアプローチの欠点は、ターゲットプラットフォームにこの薄いネイティブ層を維持する必要性です。
** JNAは、通常のJNIと比較してランタイムオーバーヘッドを扱いますが、開発の太りすぎのパフォーマンスにはIMOが容易になります。あなたの場合にのみJNIに切り替えます 持ってる に。
効果がないでしょう。 JVMTIには、Javaコードが直接制御できないというコールバック(classprepareなど)があります。これらのコールバックがJavaで実装されている場合、実行は他のコールバックをリードしてデッドロックを引き起こす可能性があります。
書くのは難しいことではありません.... JVMTIコールを撮影するだけで、JNIを介してJavaクラスをコールバックします。おそらくいくつかの問題に直面するでしょう...まずAgent_Onload ..この最初の「登録」機能も発生しますJVMのライフサイクルの早い段階で、Javaをコールバックするために....第二に、潜在的な循環性の問題と、JVMがこのようなことを期待して書かれた確率があります...
私は例を書いてみてください....数分で戻ってきます...
JDIは、JVMTIをバックエンドAPIとして使用するJavaで書かれたトップレベルのインターフェイスです。このリンク 詳細情報を提供してください。