Java API поверх JVMTI?

Есть ли хороший Java API, который я могу использовать поверх JVMTI?

Ответы

Ответ 1

ok... просто попробовал... кажется, работает так, как ожидалось.... в реальной жизни обратный вызов VMInit вернет экземпляр класса, который реализовал интерфейс, который отразил интерфейс C JVMTI.... C агент будет хранить этот экземпляр и вызывать его, когда это требуется на событиях.... дополнительно до того, как вернувшаяся VMInit Java вернет ему возможности, обратные вызовы и события регистрации и т.д.... вы, вероятно, сможете получить около 90% API JVMTI охват..... это просто случай ввода его в... Я мог бы сделать это в выходные, если у вас есть сильный случай: -)

приведен следующий код:

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

JVMTI не был создан для использования Java API. Само определение JVM TI говорит:

Интерфейс инструмента JVM (JVM TI) является стандартным встроенным API , который позволяет встроенным библиотекам захватывать события и управлять виртуальной машиной Java (JVM) для платформы Java.

Поскольку он был создан для встроенного API для захвата событий и элементов управления, я не думаю, что на нем есть API. Можете ли вы объяснить, что вы пытаетесь достичь?

Я не знаю ни одного Java API поверх JVM TI.

Ответ 3

Я искал вокруг и, к сожалению, не могу найти какую-либо библиотеку Java API поверх JVMTI. Похоже, вам не повезло.

Что вы можете сделать, это вызвать собственный lib из вашего Java-кода. Я не очень хорошо разбираюсь в C/С++, но из документов JVMTI я вижу, что можно создать небольшую общую библиотеку из предоставленных заголовков. Затем вы можете вызвать его с помощью JNA **. Это даст вам хороший API-оболочку вокруг собственной библиотеки.

Взгляните на примеры на странице JNA Getting Started

Эта страница также ссылается на JNAerator, которая может генерировать для вас все необходимые привязки Java.

Недостатком этого подхода является необходимость поддерживать этот тонкий собственный слой для ваших целевых платформ.


** JNA имеет накладные расходы во время выполнения по сравнению с обычным JNI, но простота в развитии превышения производительности. Переключитесь на JNI, только если вам нужно.

Ответ 4

Это не сработает. JVMTI имеет обратные вызовы, которые Java-код не имеет прямого контроля (например, ClassPrepare). Если эти обратные вызовы реализованы на Java, выполнение может привести к другим обратным вызовам, вызывающим тупик.

Ответ 5

не составит труда написать... просто вызовите вызовы JVMTI для вызова класса Java над JNI.. вы, вероятно, столкнетесь с несколькими проблемами... во-первых, Agent_onLoad.. эта начальная "регистрация" функция происходит слишком рано в жизненном цикле JVM, чтобы она могла откликнуться на вашу java.... во-вторых, есть потенциальные проблемы с круговым выражением и вероятность того, что JVM была написана, ожидая, что вы сделаете что-нибудь подобное этому...

Я попытаюсь написать пример... через несколько минут...

Ответ 6

JDI - это интерфейс верхнего уровня, написанный на Java, который использует JVMTI в качестве backend api. эта ссылка дает вам подробную информацию.