Pregunta

¿Hay una bonita API Java que pueda usar sobre JVMTI?

¿Fue útil?

Solución

Ok ... solo lo intenté ... parece funcionar como se esperaba ... en la vida real la devolución de llamada Vminit devolvería una instancia de una clase que implementó una interfaz que reflejó la interfaz C JVMTI ... Almacene esta instancia y llámelo cuando sea necesario en los eventos ... además antes de que Vminit Java devolviera, configuraría capacidades y devoluciones de llamada y registraría eventos, etc. Probablemente podría obtener aproximadamente 90% de cobertura de API JVMTI. ... Es solo un caso de escribirlo ... podría hacerlo en un fin de semana si tienes un caso fuerte :-)

El siguiente código produce esto:

C: VMinit, que se prepara para la devolución de llamada del método Java
Java: Jvmti Callback Class, VMinit ().
C: VMinit, método Java de devolución de llamada devuelto correctamente
Java: Y finalmente ... hola, soy el principal de 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");
    }

}

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

Otros consejos

JVMTI no fue construido para tener API Java en la parte superior. La definición JVM TI en sí misma dice:

La interfaz de herramienta JVM (JVM TI) es un La API nativa estándar que permite que las bibliotecas nativas capturen eventos y controlen una máquina virtual Java (JVM) para la plataforma Java.

Dado que fue construido para la API nativa para capturar eventos y controles, no creo que haya API además. ¿Puedes explicar lo que estás tratando de lograr?

No conozco ninguna API de Java en la parte superior de JVM TI.

Busqué y desafortunadamente no puedo encontrar ninguna biblioteca de API de Java sobre JVMTI. Parece que no tienes suerte.

Sin embargo, lo que puede hacer es llamar a una lib nativa desde su código Java. No soy muy bueno en C/C ++, pero desde JVMTI Docs, veo que es posible construir una pequeña biblioteca compartida desde encabezados proporcionados. Entonces puedes llamarlo usando JNA **. Te dará un buen envoltorio API alrededor de la biblioteca nativa.

Echa un vistazo a los ejemplos en Página de inicio de JNA

Esta página también enlaza a Jnaerator que puede generar todos los enlaces de Java necesarios para usted.

La desventaja de este enfoque es una necesidad de mantener esta delgada capa nativa para sus plataformas objetivo.


** JNA trata una sobrecarga de tiempo de ejecución en comparación con el JNI habitual, pero la facilidad de desarrollo sobrepesos los beneficios de rendimiento de la OMI. Cambie a JNI solo si tener a.

No funcionará. JVMTI tiene devoluciones de llamada sobre las que el código Java no tiene control directo (como ClassPrepare). Si estas devoluciones de llamada se implementan en Java, la ejecución puede liderar otras devoluciones de llamada que causan un punto muerto.

No sería difícil escribir ... solo Thunk las llamadas JVMTI para devolver una clase de Java sobre JNI ... Probablemente enfrentarías un par de problemas ... en primer lugar el agente_onload ... esta función inicial de "registro" también ocurre Al principio del ciclo de vida del JVM para que llame a su Java ... En segundo lugar, hay posibles problemas de circularidad y la probabilidad de que el JVM fuera escrito esperando que haga algo así en ...

Intentaré escribir un ejemplo ... de vuelta en unos minutos ...

JDI es una interfaz de nivel superior escrita en Java, que utiliza JVMTI como la API de backend.este enlace darle información detallada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top