简体   繁体   English

JVMTI之上的Java API?

[英]Java API on top of JVMTI?

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

JVMTI was not built for having Java API on top. JVMTI不是为了拥有Java API而构建的。 The JVM TI definition itself says: JVM TI定义本身说:

The JVM tool interface (JVM TI) is a standard native API that allows for native libraries to capture events and control a Java Virtual Machine (JVM) for the Java platform. JVM工具接口(JVM TI)是一种标准本机API,允许本机库捕获事件并控制Java平台的Java虚拟机(JVM)。

Since it was built for native API to capture events & controls, I don't think there are API on top of it. 由于它是为本机API构建的,用于捕获事件和控件,因此我认为不存在API。 May you can explain what you are trying to achieve? 你可以解释一下你想要实现的目标吗?

I am not aware of any Java API on top of JVM TI. 我不知道JVM TI之上的任何Java API。

ok... just tried it... seems to work as expected.... in real life the VMInit callback would return an instance of a class that implemented an interface that mirrored the C JVMTI interface.... the C agent would store this instance and call it when required on events .... additionally before the VMInit Java returned it would set up capabilities and callbacks and register events etc.... you would probably be able to get about 90% JVMTI API coverage..... it's just a case of typing it in .... I could do it in a weekend if you have a strong case :-) 好吧......刚尝试过......似乎按预期工作......在现实生活中,VMInit回调会返回一个类的实例,该类实现了一个镜像C JVMTI接口的接口.... C代理将存储此实例并在事件需要时调用它....此外,在VMInit Java返回之前,它将设置功能和回调以及注册事件等....您可能能够获得大约90%的JVMTI API覆盖率。 ......这只是一个打字的例子....如果你有一个强有力的案例,我可以在周末做这件事:-)

the following code produces this: 以下代码生成此:

C: VMInit, preparing to callback Java method C:VMInit,准备回调Java方法
Java: JVMTI callback class, VMInit(). Java:JVMTI回调类,VMInit()。
C: VMInit, callback Java method returned successfully C:VMInit,回调Java方法成功返回
Java: And Finally... Hello, I'm the Java main 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");
    }

}

and the C 和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;
}

I searched around and unfortunately can't find any Java API library on top of JVMTI. 我四处搜索,遗憾的是在JVMTI之上找不到任何Java API库。 Seems like you're out of luck. 好像你运气不好。

What you can do though is to call a native lib from your Java code. 您可以做的是从Java代码中调用本机库。 I'm not very good at C/C++ but from JVMTI docs I see that it's possible to build a small shared library from provided headers . 我不是很擅长C / C ++但是从JVMTI docs我看到可以从提供的头文件中构建一个小的共享库。 Then you can call it using JNA**. 然后你可以使用JNA **来调用它。 It will give you a nice API wrapper around native library. 它将为您提供一个围绕本机库的漂亮的API包装器。

Take a look at examples at JNA Getting Started page 看看JNA入门页面上的示例

This page also links to JNAerator which can generate all necessary Java bindings for you. 此页面还链接到JNAerator ,它可以为您生成所有必需的Java绑定。

The downside of this approach is a necessity of maintaining this thin native layer for your target platforms. 这种方法的缺点是必须为目标平台维护这个瘦的本机层。


** JNA deals a runtime overhead compared to usual JNI but ease of development overweights performance benefits IMO. **与通常的JNI相比,JNA处理运行时开销,但是易于开发的权重超过了IMO的性能优势。 Switch to JNI only if you have to. 只有在必要时才切换到JNI。

It will not work. 不起作用。 JVMTI has callbacks that the Java code has no direct control over (like ClassPrepare). JVMTI具有Java代码无法直接控制的回调(如ClassPrepare)。 If these callbacks are implemented in Java, the execution can lead other callbacks causing deadlock. 如果这些回调是用Java实现的,那么执行会导致其他回调导致死锁。

it wouldn't be difficult to write.... just thunk the JVMTI calls to callback a Java class over JNI.. you would probably face a couple of issues... firstly the Agent_onLoad.. this initial "registering" function happens too early on in the lifecycle of the JVM for it to callback your java.... secondly there are potential circularity issues and the probability that the JVM was written expecting you to do anything like this this at... 写起来并不困难....只是将JVMTI调用通过JNI回调Java类...你可能会面临一些问题......首先是Agent_onLoad ..这个初始的“注册”功能也发生了在JVM的生命周期的早期,它要回调你的java ....其次有潜在的循环问题和JVM编写的概率,期望你做这样的事情......

Iĺl try to write an example.... back in a few mins... 我试着写一个例子......回来几分钟......

JDI is a TOP level interface written in Java, which uses JVMTI as the backend api. JDI是一个用Java编写的TOP级接口,它使用JVMTI作为后端api。 this link give you detailed info. 此链接为您提供详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM