我可以在JVMTI顶部使用一个不错的Java API吗?

有帮助吗?

解决方案

好的...只是尝试了...似乎正常工作。...在现实生活中,vminit回调将返回一个实现镜像c jvmti接口的界面的类的实例。...c代理将存储此实例并在事件上需要在需要时致电。...此外,在vminit java返回之前,它将设置功能,回调和注册事件等。...您可能可以获得约90%的JVMTI API覆盖范围。 ...这只是打入它的情况。...如果您有强烈的案例,我可以在周末做:-)

以下代码产生以下方式:

C:Vminit,准备回调Java方法
Java:JVMTI回调类,vminit()。
C:vminit,回调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;
}

其他提示

JVMTI并不是因为将Java API在顶部而建。 JVM TI定义本身说:

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

由于它是为本机API构建的,用于捕获事件和控件,因此我认为没有API。您可以解释您要实现的目标吗?

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

我四处搜索,不幸的是在JVMTI顶部找不到任何Java API库。好像你不幸。

但是,您可以做的是从Java代码中调用本地LIB。我不是很擅长C/C ++,但是从JVMTI文档中,我发现可以从中构建一个小的共享库 提供标题. 。然后,您可以使用JNA **调用它。它将为您提供本机库周围的不错的API包装。

看看例子 JNA入门页面

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

这种方法的缺点是必须为目标平台维护这个薄的天然层。


**与通常的JNI相比,JNA的运行时间间接费用,但易于开发超重性能益处IMO。仅在您的情况下切换到JNI 至。

不起作用。 JVMTI的回调是Java代码没有直接控制(例如ClassPrepare)。如果这些回调是在Java中实现的,则执行可能会引起其他回调,导致僵局。

写作并不难。...只需用jni调用jvmti调用JNI的java类。.您可能会遇到几个问题...首先是Agent_onload ..此初始“注册”功能也发生了在JVM的生命周期初期,它可以回到您的Java ....其次存在潜在的循环问题,以及JVM的概率期望您在...

我尝试写一个例子。...在几分钟内回到...

JDI是用Java编写的顶级接口,它使用JVMTI作为后端API。这个链接 给您详细的信息。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top