Java API поверх JVMTI?

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

6 ответов

Решение

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

следующий код производит это:

C: VMInit, готовится к обратному вызову Java-метода
Java: класс обратного вызова JVMTI, VMInit ().
C: VMInit, метод обратного вызова Java возвращен успешно
Java: И наконец... Здравствуйте, я главный Java


package com.stackru;

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

}

и С

#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/stackru/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 (JVM) для платформы Java.

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

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

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

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

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

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

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


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

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

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

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

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

Другие вопросы по тегам