2 Stimmen

Überprüfen Sie, ob aspectjweaver (oder ein beliebiger Java-Agent) geladen ist

Gibt es einen (bevorzugt tragbaren) Weg zu überprüfen, ob die JVM mit einem bestimmten -javaagent gestartet wurde?

Insbesondere möchte ich wissen, ob der AspectJ Load Time Weaver geladen wurde oder nicht. (Ich versuche eine hilfreiche Fehlermeldung im Falle eines falschen Starts bereitzustellen).

10voto

kriegaex Punkte 56700

Der folgende Code zeigt

  • eine Möglichkeit, jegliche -javaagent:... JVM-Argumente zu bestimmen,
  • eine Möglichkeit zu überprüfen, ob die Einstiegsklasse des AspectJ-Weaving-Agents (diejenige, die im Manifest-Eintrag Premain-Class: von aspectjweaver.jar erwähnt wird) geladen wird.

Das Erstere beweist nur, dass das Argument über die Befehlszeile übergeben wurde, nicht dass der Agent tatsächlich gefunden und gestartet wurde.

Das Letztere beweist nur, dass der Weaver auf dem Klassenpfad verfügbar ist, nicht dass er tatsächlich als Agent gestartet wurde. Die Kombination aus beiden sollte Ihnen ziemlich sicher zeigen, dass der Agent tatsächlich aktiv ist.

package de.scrum_master.app;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.util.List;

public class Application {
    public static void main(String[] args) {
        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
        List arguments = runtimeMxBean.getInputArguments();
        for (String argument : arguments) {
            if (argument.startsWith("-javaagent:"))
                System.out.println(argument);
        }
        try {
            Class.forName("org.aspectj.weaver.loadtime.Agent");
        } catch (ClassNotFoundException e) {
            System.err.println("WARNUNG: AspectJ-Weaving-Agent nicht geladen");
        }
    }
}

Sie finden möglicherweise auch die Frage Starting a Java agent after program start und einige ihrer Antworten hilfreich.


Aktualisierung:

OK, hier ist eine Kombination meiner eigenen Lösung und Ihrer, aber eine, die tatsächlich funktioniert, auch wenn der Weaver nicht verfügbar ist, was wichtig ist, weil dies das ist, was Sie zunächst überprüfen möchten:

public static boolean isAspectJAgentLoaded() {
    try {
        Class agentClass = Class.forName("org.aspectj.weaver.loadtime.Agent");
        Method method = agentClass.getMethod("getInstrumentation");
        method.invoke(null);
    } catch (Exception e) {
        //System.out.println(e);
        return false;
    }
    return true;
}

Aktualisierung 2:

Nach einiger Diskussion mit dem OP bacar habe ich mich entschieden, eine Lösung anzubieten, die keine Reflektion verwendet, sondern stattdessen NoClassDefError abfängt:

public static boolean isAspectJAgentLoaded() {
    try {
        org.aspectj.weaver.loadtime.Agent.getInstrumentation();
    } catch (NoClassDefFoundError | UnsupportedOperationException e) {
        System.out.println(e);
        return false;
    }
    return true;
}

Jetzt werden beide Hauptfehlerarten

  • Weaving-Agent ist auf dem Klassenpfad verfügbar, aber die Instrumentierung wurde nicht durchgeführt, weil aspectjweaver.jar nicht als Java-Agent gestartet wurde,
  • Agent aspectjweaver.jar ist überhaupt nicht auf dem Klassenpfad und die Klasse org.aspectj.weaver.loadtime.Agent ist daher nicht verfügbar

werden ordentlich behandelt, indem false zurückgegeben wird nachdem Warnmeldungen (in diesem einfachen Beispiel nur die Ausnahmen, die deutlich sagen, was falsch ist) auf der Konsole ausgegeben wurden.

Mögliche Konsolenausgaben für die beiden Fälle sind:

  • java.lang.UnsupportedOperationException: Java 5 wurde nicht mit preMain -javaagent für AspectJ gestartet
  • java.lang.NoClassDefFoundError: org/aspectj/weaver/loadtime/Agent

0voto

bacar Punkte 9371

Ich habe die folgenden Arbeiten gefunden (getestet gegen 1.8.4), obwohl es sich auf nicht dokumentierte AspectJ-Weaver-Funktionen verlässt, so dass es möglicherweise nicht über Versionen hinweg funktioniert.

public static boolean isAspectJAgentLoaded() {
    try {
        org.aspectj.weaver.loadtime.Agent.getInstrumentation();
        return true;
    } catch (UnsupportedOperationException e) { 
        return false;
    }
}

Erklärung: Wenn aspectj als Agent geladen wird, wird die statische Methode org.aspectj.weaver.loadtime.Agent.premain(...) vom JVM aufgerufen. Dies hat eine Seiteneffekt, den wir testen können. Der Aufruf von getInstrumentation löst entweder eine UnsupportedOperationException aus (wenn es nicht als Agent initialisiert wurde) oder gibt erfolgreich zurück, wenn es so initialisiert wurde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X