Frage

Gibt es eine schöne Java -API, die ich über JVMTI verwenden kann?

War es hilfreich?

Lösung

Ok ... habe es gerade versucht ... scheint wie erwartet zu funktionieren ... im wirklichen Leben würde der Vminit -Rückruf eine Instanz einer Klasse zurückgeben, die eine Schnittstelle implementiert hat Speichern Sie diese Instanz und rufen Sie sie bei Bedarf auf Ereignisse an .... Zusätzlich, bevor die Vminit Java zurückgegeben hat, würde es Funktionen und Rückrufe einrichten und Ereignisse registrieren usw. Sie könnten wahrscheinlich etwa 90% JVMTI -API -Berichterstattung erhalten. ... Es ist nur ein Fall, es einzugeben ... ich könnte es an einem Wochenende tun, wenn Sie einen starken Fall haben :-)

Der folgende Code erzeugt Folgendes:

C: Vminit, Vorbereitung auf die Rückruf -Java -Methode
Java: Jvmti Callback -Klasse, vminit ().
C: Vminit, Callback Java -Methode erfolgreich zurückgegeben
Java: Und schließlich ... Hallo, ich bin die Java -Main


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

}

und die 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;
}

Andere Tipps

JVMTI wurde nicht dafür gebaut, Java -API oben zu haben. Die JVM Ti Definition selbst sagt:

Die JVM -Werkzeugschnittstelle (JVM Ti) ist a Standard native API, die native Bibliotheken ermöglicht, Ereignisse zu erfassen und eine Java Virtual Machine (JVM) für die Java -Plattform zu steuern.

Da es für native API gebaut wurde, um Ereignisse und Steuerelemente zu erfassen, glaube ich nicht, dass es API gibt. Mögen Sie erklären, was Sie erreichen möchten?

Mir ist keine Java -API über JVM Ti bekannt.

Ich habe herum gesucht und leider keine Java -API -Bibliothek auf JVMTI finden. Scheint, als wären Sie kein Glück.

Was Sie jedoch tun können, ist, einen nativen LIB aus Ihrem Java -Code auszurufen. Ich bin nicht sehr gut in C/C ++, aber von JVMTI -Dokumenten sehe ich, dass es möglich ist, eine kleine gemeinsame Bibliothek aus zu erstellen Bereitstellung von Kopfzeilen. Dann können Sie es mit JNA ** anrufen. Es gibt Ihnen einen schönen API -Wrapper in der nativen Bibliothek.

Schauen Sie sich Beispiele bei JNA Erste Schritte Seite

Diese Seite verlinkt auch zu Jnaerator Dies kann alle notwendigen Java -Bindungen für Sie erzeugen.

Der Nachteil dieses Ansatzes ist eine Notwendigkeit, diese dünne native Schicht für Ihre Zielplattformen aufrechtzuerhalten.


** JNA setzt im Vergleich zu üblichen JNI einen Laufzeitaufwand aus, aber die Leistungsguthaben von Leichtigkeiten übergewichtige Leistungen von IMO. Wechseln Sie nur dann zu JNI, wenn Sie haben zu.

Es wird nicht funktionieren. JVMTI hat Rückrufe, über die der Java -Code keine direkte Kontrolle hat (wie ClassPrepare). Wenn diese Rückrufe in Java implementiert sind, kann die Ausführung andere Rückrufe führen, die Deadlock verursachen.

Es wäre nicht schwierig zu schreiben ... nur die JVMTI -Anrufe zum Rückruf einer Java -Klasse über JNI. Sie würden wahrscheinlich ein paar Probleme haben ... zuerst die Agent_onload .. diese erste "Registrierung" -Funktion passiert auch Zu Beginn des Lebenszyklus des JVM, damit es Ihre Java zurückruft. Zweitens gibt es potenzielle Zirkularitätsprobleme und die Wahrscheinlichkeit, dass die JVM geschrieben wurde, und erwartete, dass Sie so etwas tun, dies bei ...

Ich versuche ein Beispiel zu schreiben ... wieder in ein paar Minuten ...

JDI ist eine in Java geschriebene oberste Schnittstelle, die JVMTI als Backend -API verwendet.dieser Link Geben Sie detaillierte Informationen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top