Domanda

Vorrei accedere in qualche modo ogni volta Thread.interrupt() si chiama, la registrazione quale thread ha rilasciato la chiamata (e il suo stack corrente), così come le informazioni di identificazione di cui discussione viene interrotta.

C'è un modo per fare questo? La ricerca di informazioni, ho visto qualcuno riferimento alla possibilità di implementare un gestore della sicurezza. E 'questo qualcosa che può essere fatto in fase di esecuzione (ad esempio, in un applet o Web client Start), o avete bisogno di strumento JVM installato per fare questo?

O c'è un modo migliore per fare questo?

È stato utile?

Soluzione

Come un trucco veloce, questo era un molto più facile da fare che ho pensato che sarebbe stato. Poiché questo è un trucco veloce, non ho fatto cose del genere in modo che la traccia dello stack è abbastanza profondo prima dereferenziazione la matrice, ecc ho inserito il seguente nel mio costruttore di Applet firmato:

log.info("Old security manager = " + System.getSecurityManager());
System.setSecurityManager(new SecurityManager() {
      @Override
      public void checkAccess(final Thread t) {
        StackTraceElement[] list = Thread.currentThread().getStackTrace();
        StackTraceElement element = list[3];
        if (element.getMethodName().equals("interrupt")) {
          log.info("CheckAccess to interrupt(Thread = " + t.getName() + ") - "
                   + element.getMethodName());
          dumpThreadStack(Thread.currentThread());
        }
        super.checkAccess(t);
      }
    });

e il metodo dumpThreadStack è il seguente:

public static void dumpThreadStack(final Thread thread) {
  StringBuilder builder = new StringBuilder('\n');
  try {
    for (StackTraceElement element : thread.getStackTrace()) {
      builder.append(element.toString()).append('\n');
    }
  } catch (SecurityException e) { /* ignore */ }
  log.info(builder.toString());
}

Non potrei mai, ovviamente, lasciare questo nel codice di produzione, ma è sufficiente a dirmi esattamente quale thread stava causando un interrupt() che non mi aspettavo. Vale a dire, con questo codice a posto, ho un dump dello stack per ogni chiamata a Thread.interrupt().

Altri suggerimenti

Prima di provare qualcosa di troppo selvaggia, avete considerato utilizzando il Java debug API ? Mi piacerebbe pensare che cattura MethodEntryEvents su Thread.interrupt () lo farebbero.

Eeek, che è la vecchia interfaccia, si dovrebbe anche controllare oout la nuova JVM Strumento Interface .

Vorrei guardare AspectJ e le sue capacità di avvolgere le chiamate di metodo. esecuzione pointcut intorno il metodo interrupt() dovrebbe aiutare qui.

Si noti che dal momento che stai cercando di intercettare un metodo di sistema di chiamata Java (al contrario di codice dell'applicazione), quanto sopra possono non essere adatto. Questo thread sembra suggerire che è possibile, ma è da notare che lui è creato un tessuto rt.jar.

Come altri hanno detto ... Se si tratta di una cosa di una volta JVMTI è probabilmente il modo più hardcore andare. Tuttavia, altrettanto divertente potrebbe essere quella di utilizzare la libreria ASM e le API di strumentazione per creare un agente che inserisce una chiamata ad un metodo statico che hai creato poco prima della chiamata Thread.interrupt () (o forse altera il Thread.interrupt ( ) metodo per fare lo stesso, credo che si può fare).

Sia vuole del tempo per imparare, ma è abbastanza divertente lavorare con e una volta che si ottiene il possesso di esso si possono usare per tutti i tipi di cose divertenti in futuro :-) Io in realtà non ho alcun bene frammenti per incollare qui adesso, ma se google in giro per ASM e forse guardo il JIP per qualche uso creativo di ASM penso che troverete l'ispirazione.

JIP: Java Interactive Profiler

scroll top