Domanda

C'è un bel API Java che posso utilizzare in cima JVMTI?

È stato utile?

Soluzione

ok ... appena provato ... sembra funzionare come previsto .... nella vita reale il callback VMInit sarebbe tornato un'istanza di una classe che ha implementato un'interfaccia che rispecchiava l'interfaccia C JVMTI .... la C agente avrebbe memorizzare questa istanza e lo chiamano quando richiesto su eventi .... inoltre prima della VMInit Java restituito avrebbe istituito capacità e callback e registrare gli eventi ecc .... si sarebbe probabilmente in grado di ottenere circa il 90% JVMTI API copertura ..... è solo un caso di digitazione in .... ho potuto farlo in un week-end se si dispone di un caso forte: -)

il seguente codice produce questo:

C: VMInit, preparandosi a richiamata Java metodo
Java:. JVMTI classe di callback, VMInit ()
C: VMInit, callback metodo Java è tornato con successo
Java: E infine ... Ciao, io sono il principale
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");
    }

}

e 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;
}

Altri suggerimenti

JVMTI non è stata costruita per avere API Java in cima. La definizione JVM TI stesso dice:

L'interfaccia strumento JVM (JVM TI) è un API native standard che consente di librerie native di eventi di cattura e controllare una Java Virtual Machine (JVM) per la piattaforma Java.

Da quando è stato costruito per API native di eventi e controlli di acquisizione, non credo che ci sono API su di esso. Possiate si può spiegare ciò che si sta cercando di raggiungere?

Non sono a conoscenza di alcun API Java in cima alla JVM TI.

Ho cercato in giro e, purtroppo, non riesce a trovare alcuna libreria API Java in cima JVMTI. Sembra che tu sei fuori di fortuna.

Cosa si può fare, però, è di chiamare un lib nativo dal codice Java. Io non sono molto bravo a C / C ++, ma da documenti JVMTI vedo che è possibile costruire una piccola libreria condivisa da intestazioni forniti . Poi si può chiamare usando JNA **. Vi darà un bel involucro API intorno libreria nativa.

Date un'occhiata a esempi al JNA Getting Started pagina

Questa pagina collega anche a JNAerator che può generare tutti i binding Java necessari per voi.

Lo svantaggio di questo approccio è una necessità di mantenere questo strato sottile nativo per le piattaforme di destinazione.


** JNA occupa un runtime in testa rispetto al solito JNI, ma la facilità di vantaggi prestazionali di sviluppo sovrappesi IMO. Passa a JNI solo se si sono a.

Non funzionerà. JVMTI ha callback che il codice Java non ha alcun controllo diretto su (come ClassPrepare). Se queste callback sono implementati in Java, l'esecuzione può portare altri callback causando stallo.

non sarebbe difficile scrivere .... solo thunk il JVMTI chiama a callback una classe Java su JNI .. si sarebbe probabilmente affrontare un paio di questioni ... in primo luogo l'Agent_onLoad .. questo iniziale "registrazione" funzione accade troppo presto nel ciclo di vita della JVM per poter callback vostra java .... secondo luogo ci sono potenziali problemi di circolarità e la probabilità che la JVM è stato scritto in attesa di fare qualcosa di simile a questo ...

Ill provare a scrivere un esempio .... di nuovo in pochi minuti ...

JDI è un'interfaccia di alto livello scritto in Java, che utilizza JVMTI come api backend. questo link darà Info dettagliate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top