JVMTI之上的Java API?

时间:2011-01-27 16:36:44

标签: java jvmti

我可以在JVMTI之上使用一个很好的Java API吗?

6 个答案:

答案 0 :(得分:11)

JVMTI不是为了拥有Java API而构建的。 JVM TI定义本身说:

  

JVM工具接口(JVM TI)是一种标准本机API,允许本机库捕获事件并控制Java平台的Java虚拟机(JVM)。

因为它是为本机API构建的,用于捕获事件和控件,我不认为它上面有API。你可以解释一下你想要实现的目标吗?

我不知道JVM TI之上的任何Java API。

答案 1 :(得分:4)

好吧......刚尝试过......似乎按预期工作......在现实生活中,VMInit回调会返回一个类的实例,该类实现了一个镜像C JVMTI接口的接口.... C代理将存储此实例并在事件需要时调用它....此外,在VMInit Java返回之前,它将设置功能和回调以及注册事件等....您可能能够获得大约90%的JVMTI API覆盖.....这只是一个打字的例子....如果你有一个强有力的案例我可以在周末做: - )

以下代码产生了这个:

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;
}

答案 2 :(得分:3)

我四处搜索,遗憾的是在JVMTI之上找不到任何Java API库。好像你运气不好。

您可以做的是从Java代码调用本机库。我不是很擅长C / C ++但是从JVMTI docs我看到可以从provided headers构建一个小的共享库。然后你可以使用JNA **来调用它。它将为您提供一个围绕本机库的漂亮API包装器。

查看JNA Getting Started page

上的示例

此页面还链接到JNAerator,它可以为您生成所有必需的Java绑定。

这种方法的缺点是必须为目标平台维护这个瘦的本机层。


**与通常的JNI相比,JNA处理运行时开销,但开发的轻松性使IMO的性能受益。仅当您 时才切换到JNI。

答案 3 :(得分:2)

它无效。 JVMTI具有Java代码无法直接控制的回调(如ClassPrepare)。如果这些回调是用Java实现的,那么执行会导致其他回调导致死锁。

答案 4 :(得分:1)

编写起来并不困难....只是将JVMTI调用通过JNI回调Java类...你可能会面临一些问题......首先是Agent_onLoad ..这个初始的“注册”函数在JVM的生命周期中发生得太早,因为它回调你的java ....其次有潜在的循环问题和JVM编写的概率,期望你做这样的事情......

我试着写一个例子....几分钟后......

答案 5 :(得分:0)

JDI是一个用Java编写的TOP级接口,它使用JVMTI作为后端api。 this link为您提供详细信息。