2009-06-02 9 views
0

Ich suche nach einem einfachen Weg (z. B. ein einzelnes Skript/Batch-Datei oder ein einfaches Programm), um eine Reihe von Java-Quelldateien zu instrumentieren, so dass jeder Methode eine System.out.println-Anweisung beim Ein- und Ausstieg hinzugefügt wird.Instrument-Java-Quelldateien mit System.out.println-Anweisungen?

Ich konnte ein solches Dienstprogramm nicht finden. Der Grund, warum ich diese benötigen (und warum es auf Quelldateien arbeiten muss und nicht die Dateien .class) ist, dass das Zielsystem ist ein Embedded-Java-System ..

Vielen Dank im Voraus, pd

Antwort

1

Sie wahrscheinlich didn finde nicht viel, weil die Verwendung von System.out eine ziemlich schreckliche Art wäre, eine Anwendung zu instrumentieren.

Was versuchen Sie zu tun - Analyse der Leistung, Code-Abdeckung, etc? Wenn ja, gibt es viele Werkzeuge für beides.

+0

ich erste Stufe Analyse eines kniffligen Fehler zu tun versuchen - erste Abdeckung Informationen erhalten, dann noch einige Ausdrucke in relevanten Stellen hinzufügen, um zu sehen, was man geht. Ich hätte erwähnen sollen, dass ich einen Debugger nicht verwenden kann, um den Code im Moment durchzugehen (die Debugging-Unterstützung des Systems ist vorerst unterbrochen) und muss daher auf Ausdrucke angewiesen sein. Ich bin mir bewusst, dass dies eine schreckliche Art ist, dies zu tun, aber nichtsdestotrotz etwas, das ich versuchen möchte. –

+0

In diesem Fall können Sie möglicherweise eine Art AOP verwenden, um bei jedem Methodenaufruf eine Anweisung zu interweave, um eine Anweisung vorher/nachher zu drucken? Nicht sicher, ob dies eine Option mit einem eingebetteten Gerät ist. –

+0

Es ist immer noch der Fall, dass Sie log4j statt System.out.println() betrachten sollten. Es wird Ihnen nicht helfen, die Einfügung zu automatisieren, aber Sie bekommen viel mehr Kontrolle, sobald diese Zeilen vorhanden sind. – PanCrit

6

Dies ist ein ausgezeichneter Anwendungsfall für Aspect Oriented Programming.

+1

.. zusammen mit Protokollierung (log4j) anstelle von 'System.out.println' –

0

Ich habe es schon einmal gemacht, wenn ich in einer Situation stecke, in der nichts mehr funktioniert. Ich bin tatsächlich hineingegangen und habe nach jeder anderen Zeile eine Systemroutine eingefügt, nachdem ich die richtige Methode gewählt hatte.

(Zum Beispiel, ich arbeitete gerade an einer JVM, wo RMI-Aufrufe, die eine Ausnahme war, still gegessen wurden und der aufrufende Thread einfach auf unbestimmte Zeit gehängt wurde! Oh, und natürlich konnten wir keinen Debugger verwenden. Wie sonst Sie finden das ??)

Wie auch immer, nur ein Programm, das Debug-Ausgabe fügt EVERYWHERE wird nicht helfen. Sie werden die Seiten der Ausgabe analysieren. Versuchen Sie stattdessen, das Problem zu umreißen und geben Sie dort manuell Zeilen ein.

Wenn dein Thread in einer Zeile "verschwindet" oder eine unerwartete Wendung nimmt, brich diese Zeile in ihre minimal ausführbaren Teile auf, finde heraus, welches Stück versagt, dann tauche hinein und wiederhole - nicht viel anderes zu tun .

Übrigens, ein weiteres hilfreiches Werkzeug - sogar auf einer sehr alten JVM, zu jedem Zeitpunkt können Sie ein "(neue Ausnahme()) werfen. PrintStackTrace();" um den Stapel auszugeben, ohne den Programmfluss zu beeinträchtigen. Wenn Sie sich an einem Ort befinden und nicht wissen, wie Sie dorthin gekommen sind, kann das helfen.

Schließlich, wenn Sie wirklich faul sein wollen, können Sie eine einzige statische Methode verwenden, um alle Ihre Debug-Ausgabe (eine, die nur an System.out.println delegiert), und fügen Sie ein paar Zeilen, um einen Stack-Trace, Greifen Sie nur auf die "Calling" -Zeile/Methode und drucken Sie sie aus, bevor die Debug-Anweisung Ihnen das Protokollierungs-Dienstprogramm eines armen Mannes gibt.

Nur einige manuelle Debugging-Tricks, die ich von Jahren des Durcheinander mit alten Versionen von Java auf eingebetteten Plattformen gelernt habe.

0

Ich stimme mit Kees überein, Sie sollten Aspect Oriented Programming verwenden, um die Protokollierung automatisch zu jeder Funktion hinzuzufügen. Ich tue etwas ähnliches für die Zeitmessung mit dem folgenden Code:

Dies ist so ziemlich die einfachste Art von Aspekt, die Sie hinzufügen können.Die Schlüsselkomponenten sind die Pointcut-Annotation, die erklärt, dass dieser Aspekt auf jede öffentliche Methode jeder öffentlichen Klasse in jedem Paket angewendet werden soll, unabhängig von seinem Rückgabetyp oder Eingabeparameter. Sie möchten das wahrscheinlich genauer machen. Die @Around-Annotation bezieht sich auf den Pointcut und gibt eine Menge Code an, der um die Funktion herum ausgeführt werden soll. In Ihrem Fall, wenn Sie nur eine aufgerufene Funktion anmelden möchten, können Sie @Around durch @Before oder @AfterReturning ersetzen, je nachdem, wo Sie die Protokollierung wünschen. Wenn Sie das gesamte Erstellen der Anwendung durchführen, sollten Sie versuchen, die Zeit für das Kompilieren der Zeit im Gegensatz zur Ladezeit zu berechnen. Es reduziert die Laufzeitanforderungen Ihrer Anwendung.

0

Ich habe eine Erweiterung für slf4j geschrieben, die die Funktionalität bietet, die Sie suchen (außer als Logger-Aufruf anstelle von System.out, aber es ist einfach, Logger-Aufrufe an System.out zu senden).

Werfen Sie einen Blick auf http://www.slf4j.org/extensions.html#javaagent