15

JVMTIの上で使用できる優れたJavaAPIはありますか?

4

6 に答える 6

12

JVMTIは、JavaAPIを最上位にするために構築されたものではありません。JVMTI定義自体は次のように述べています。

JVMツールインターフェイス(JVM TI)は、ネイティブライブラリがイベントをキャプチャしてJavaプラットフォームのJava仮想マシン(JVM)を制御できるようにする標準のネイティブAPIです。

イベントとコントロールをキャプチャするためのネイティブAPI用に構築されているため、その上にAPIはないと思います。あなたが達成しようとしていることを説明できますか?

JVMTIに加えてJavaAPIを認識していません。

于 2011-01-31T05:41:03.230 に答える
5

わかりました...試してみました...期待どおりに機能しているようです...実際には、VMInitコールバックは、CJVMTIインターフェイスをミラーリングしたインターフェイスを実装したクラスのインスタンスを返します...Cエージェントはこのインスタンスを保存し、必要に応じてイベントで呼び出します。さらに、VMInit Javaが返される前に、機能とコールバックを設定し、イベントなどを登録します。おそらく、約90%のJVMTIAPIカバレッジを取得できます。 ...それはそれをタイプするだけの場合です....あなたが強いケースを持っているなら私は週末にそれをすることができます:-)

次のコードはこれを生成します:

C:VMInit、Javaメソッド
Javaをコールバックする準備をしています:JVMTIコールバッククラス、VMInit()。
C:VMInit、コールバックJavaメソッドが正常に返されました
Java:そして最後に...こんにちは、私はJavaメインです


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;
}
于 2011-02-07T18:59:26.487 に答える
3

周りを検索しましたが、残念ながら、JVMTIの上にJavaAPIライブラリが見つかりませんでした。運が悪いようです。

ただし、できることは、Javaコードからネイティブlibを呼び出すことです。私はC/C ++があまり得意ではありませんが、JVMTIのドキュメントから、提供されたヘッダーから小さな共有ライブラリを構築できることがわかりました。次に、JNA**を使用して呼び出すことができます。ネイティブライブラリの周りに素晴らしいAPIラッパーを提供します。

JNA入門ページで例を見てください

このページは、必要なすべてのJavaバインディングを生成できるJNAeratorにもリンクしています。

このアプローチの欠点は、ターゲットプラットフォーム用にこの薄いネイティブレイヤーを維持する必要があることです。


** JNAは、通常のJNIと比較して実行時のオーバーヘッドを処理しますが、開発の容易さがIMOのパフォーマンスの利点を上回ります。必要な場合にのみJNIに切り替えてください

于 2011-02-04T11:24:17.103 に答える
2

うまくいかないだろう。JVMTIには、Javaコードが直接制御できないコールバックがあります(ClassPrepareなど)。これらのコールバックがJavaで実装されている場合、実行によって他のコールバックが発生し、デッドロックが発生する可能性があります。

于 2014-08-04T15:41:35.783 に答える
1

書くのは難しいことではありません....JVMTI呼び出しをサンクしてJNIを介してJavaクラスをコールバックするだけです..おそらくいくつかの問題に直面するでしょう...最初にAgent_onLoad..この最初の「登録」関数も発生しますJVMのライフサイクルの早い段階で、Javaをコールバックします。次に、潜在的な循環性の問題があり、JVMがこのようなことを期待して作成された可能性があります。

私は例を書いてみます....数分後に戻って...

于 2011-02-07T18:23:40.513 に答える
1

JDIは、Javaで記述されたTOPレベルのインターフェースであり、バックエンドAPIとしてJVMTIを使用します。 このリンクはあなたに詳細な情報を提供します。

于 2014-09-14T13:37:49.243 に答える