Question

Je voudrais vous connecter en quelque sorte tous les temps Thread.interrupt() est appelé, l'enregistrement qui a émis l'appel fil (et sa pile en cours) ainsi que des informations d'identification sur laquelle cette discussion est interrompue.

Est-il possible de le faire? La recherche d'informations, j'ai vu quelqu'un référence la possibilité de mettre en œuvre un gestionnaire de sécurité. Est-ce quelque chose qui peut être fait à l'exécution (par exemple, dans un Applet ou client Web Start), ou cela avez besoin d'outil de la machine virtuelle Java installé, vous?

Ou est-il une meilleure façon de le faire?

Était-ce utile?

La solution

En tant que hack, ce fut un beaucoup plus facile à faire que ce que je pensais que ce serait. Depuis c'est un hack rapide, je ne fais pas les choses comme faire en sorte que la trace de la pile est assez profond avant déréférencement du tableau, etc. J'inséré ce qui suit dans mon signé constructeur de Applet:

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

et la méthode de dumpThreadStack est la suivante:

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

Je ne pourrais jamais, bien sûr, laisser cela dans le code de production, mais il suffisait de me dire exactement quel fil était à l'origine d'une interrupt() que je ne m'y attendais pas. C'est, avec ce code en place, je reçois une décharge de la pile pour chaque appel à Thread.interrupt().

Autres conseils

Avant d'essayer quoi que ce soit trop sauvage, avez-vous pensé à utiliser le Java débogage API ? Je pense que la capture MethodEntryEvents sur Thread.interrupt () le feraient.

Eeek, qui est l'ancienne interface, vous devriez également vérifier oout nouveau href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/enhancements.html" rel="nofollow noreferrer"> Interface .

Je regardais AspectJ et ses capacités pour envelopper les appels de méthode. exécution pointcut autour la méthode interrupt() devrait aider.

Notez que puisque vous êtes à la recherche d'intercepter un appel de méthode du système Java (par opposition à votre code d'application), ci-dessus peut ne pas être approprié. Ce fil semble suggérer qu'il est possible, mais notez qu'il est créé un tissé rt.jar.

Comme d'autres l'ont dit ... S'il est une chose unique JVMTI est probablement la façon la plus hardcore aller. Cependant, tout aussi amusant pourrait être d'utiliser la bibliothèque asm et les API d'instrumentation pour créer un agent qui insère un appel à une méthode statique que vous avez créé juste avant l'appel Thread.interrupt () (ou modifie peut-être le Thread.interrupt ( ) méthode pour faire la même chose, je pense que vous pouvez le faire).

Les deux prend un certain temps pour apprendre, mais il est assez amusant de travailler avec et une fois que vous obtenez l'emprise de celui-ci vous pouvez les utiliser pour toutes sortes de choses drôles à l'avenir :-) Je n'ai pas vraiment de bons extraits à coller ici maintenant, mais si vous Google autour de l'ASM et peut-être regarder au JIP pour une utilisation créative de l'ASM, je pense que vous trouverez l'inspiration.

JIP: Java Interactive Profiler

Vous pouvez également essayer avec JMX:

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)

ThreadInfo objet que vous pouvez ouvrir une session:

  • la trace de pile du fil
  • Informations générales Userful comme le nom, l'état, etc
  • etc

EDIT

getAllThreadIds utilisation () afin d'obtenir la liste des identificateurs de fil en direct:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top