Ablaufverfolgung eines Java-Programmes

gravitex

Grünschnabel
Hallo.
Ich versuche ein komplexes Java-Projekt zu verstehen.
Sehr schön wäre ein Tool, welches einem beim
Laufenlassen des Programmes ausgeben kann, welche Funktionen
betreten und verlassen werden (am besten mit Parameterwerten),
ohne das man jetzt in alle Fkt. Breakpunkte setzt.
Sowas muß ja über die Debugger-Schnittstelle möglich sein.
Habe mal gegoogelt, gibt ja einige externe Java-Debugger.
Weiß jemand, ob einer von diesen sowas kann ?
Gruß,
Stefan

Ich stelle mir in etwa so eine Ausgabe vor
(damit ihr versteht, was ich meine):

--->main()
------>ClassIrgndwas.func1()
--------->ClassABC.funcX()
---------<ClassABC.funcX()
--------->ClassABC.funcY()
----------->ClassDEF.funcZ()
-----------<ClassDEF.funcZ()
---------<ClassABC.funcY()
------<ClassIrgndwas.func1()
<---main()
 
Hallo,
Wenn du eclipse als IDE verwendest kannst du bequem von Funktion zu Funktion springen wenn du im Debug-Modus bist.Allerdings bekommst du dabei keine Ausgabe, das müsstest du dann selber noch notieren.
gruss munuel
 
Hallo!

hier mal ein Beispiel wie man mit AspectJ per Load Time Weaving eine Anwendung Tracen kann:

Unser TracingAspect:
Java:
/**
 * 
 */
package de.tutorials.aop;

import java.util.Arrays;
import java.util.Set;
import java.util.TreeSet;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/**
 * @author Tom
 * 
 */
@Aspect
public class TracingAspect {

	static Set<MethodCall> methodCalls = new TreeSet<MethodCall>();

	static {
		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				for (MethodCall methodCall : methodCalls) {
					System.out.println(methodCall);
				}
			}
		});
	}

	@Pointcut("call(* de.tutorials..*(..)) && !within(de.tutorials.aop..*)")
	public void anyMethodCall() {
	}

	@Around("anyMethodCall()")
	public Object traceMethodCall(ProceedingJoinPoint proceedingJoinPoint) {

		String currentThreadName = Thread.currentThread().getName();
		String calledMethodSignature = proceedingJoinPoint.getSignature()
				.toLongString();
		String arguments = Arrays.toString(proceedingJoinPoint.getArgs());
		String resultAsString = null;

		long timeStamp = System.nanoTime();

		Object result = null;

		MethodCall methodCall = new MethodCall(currentThreadName,
				calledMethodSignature, arguments, timeStamp);

		methodCalls.add(methodCall);

		try {
			result = proceedingJoinPoint.proceed();
			resultAsString = String.valueOf(result);
		} catch (Throwable e) {
			e.printStackTrace();
			result = null;
			resultAsString = "Invocation of " + calledMethodSignature
					+ " produced Exception: " + e;
		}

		methodCall.setResult(resultAsString);

		return result;
	}
}

Unsere MethodCall Abstraktion:
Java:
/**
 * 
 */
package de.tutorials.aop;

import java.text.MessageFormat;

class MethodCall implements Comparable<MethodCall>{
	
	long timeStamp;
	
	String currentThreadName;

	String calledMethodSignature;

	String arguments;

	String result;

	static final MessageFormat MESSAGE_FROMAT = new MessageFormat(
			"[{0}] called Method {1} with arguments:({2}) and got result:({3})");

	public MethodCall(String currentThreadName,
			String calledMethodSignature, String arguments,  long timeStamp) {
		super();
		this.currentThreadName = currentThreadName;
		this.calledMethodSignature = calledMethodSignature;
		this.arguments = arguments;
		this.timeStamp = timeStamp;
	}

	/**
	 * @return the arguments
	 */
	public String getArguments() {
		return arguments;
	}

	/**
	 * @param arguments
	 *            the arguments to set
	 */
	public void setArguments(String arguments) {
		this.arguments = arguments;
	}

	/**
	 * @return the calledMethodSignature
	 */
	public String getCalledMethodSignature() {
		return calledMethodSignature;
	}

	/**
	 * @param calledMethodSignature
	 *            the calledMethodSignature to set
	 */
	public void setCalledMethodSignature(String calledMethodSignature) {
		this.calledMethodSignature = calledMethodSignature;
	}

	/**
	 * @return the currentThreadName
	 */
	public String getCurrentThreadName() {
		return currentThreadName;
	}

	/**
	 * @param currentThreadName
	 *            the currentThreadName to set
	 */
	public void setCurrentThreadName(String currentThreadName) {
		this.currentThreadName = currentThreadName;
	}

	/**
	 * @return the result
	 */
	public String getResult() {
		return result;
	}

	/**
	 * @param result
	 *            the result to set
	 */
	public void setResult(String result) {
		this.result = result;
	}

	public String toString() {
		return MESSAGE_FROMAT.format(new Object[] { this.currentThreadName,
				this.calledMethodSignature, this.arguments, this.result });
	}

	public int compareTo(MethodCall otherMethodCall) {
		return (int)Math.signum( this.timeStamp - otherMethodCall.timeStamp);
	}
}

Das passende aop.xml:
XML:
<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <aspects>
        <aspect name="de.tutorials.aop.TracingAspect" />
    </aspects>
    
    <weaver options="-XlazyTjp">
        <include within="de.tutorials..*"/>
    </weaver>
</aspectj>

Unsere MiniAnwendung die wir Tracen wollen:
Java:
/**
 * 
 */
package de.tutorials;

/**
 * @author Tom
 * 
 */
public class TracingExample {
    public static void main(String[] args) {
        String a = "W";

        System.out.println(operation1(a));

    }

    private static Object operation1(String a) {
        String b = "X";
        return operation2(a, b);
    }

    private static Object operation2(String a, String b) {
        String c = "Y";
        return operation3(a, b, c);
    }

    private static Object operation3(String a, String b, String c) {

        return a + b + c + "Z";
    }
}

Ausgabe ohne Tracing:
Code:
E:\eclipse\3.2\eclipse\workspace\de.tutorials.training>java -cp bin de.tutorials.TracingExample
WXYZ

Ausgabe mit Tracing:
Code:
E:\eclipse\3.2\eclipse\workspace\de.tutorials.training>java -Daj.weaving.verbose=true  -javaagent:c:/aspectjweaver.jar  -cp c:/aspectjrt.jar;c:/de.tutorials.aop.tracing.jar;bin de.tutorials.TracingExample
info AspectJ Weaver Version 1.5.1a built on Monday Apr 10, 2006 at 10:52:04 GMT
info register classloader sun.misc.Launcher$AppClassLoader@10469011
info using file:/C:/de.tutorials.aop.tracing.jar!/META-INF/aop.xml
info register aspect de.tutorials.aop.TracingAspect
info weaving 'de/tutorials/TracingExample'
info generating class 'de.tutorials.TracingExample$AjcClosure1'
info generating class 'de.tutorials.TracingExample$AjcClosure3'
info generating class 'de.tutorials.TracingExample$AjcClosure5'
info weaving 'de/tutorials/aop/TracingAspect'
info processing reweavable type de.tutorials.aop.TracingAspect: de\tutorials\aop\TracingAspect.java
info successfully verified type de.tutorials.aop.TracingAspect exists.  Originates from de\tutorials\aop\TracingAspect.java
info weaving 'de/tutorials/aop/TracingAspect$1'
info weaving 'de/tutorials/aop/MethodCall'
WXYZ
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation1(java.lang.String) with arguments:([W]) and got result:(WXYZ)
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation2(java.lang.String, java.lang.String) with arguments:([W, X]) and got result:(WXYZ)
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation3(java.lang.String, java.lang.String, java.lang.String) with arguments:([W, X, Y]) and got result:(WXYZ)

Die Ausagbe ohne das verbose-Flag schaut so aus:
Code:
E:\eclipse\3.2\eclipse\workspace\de.tutorials.training>java -javaagent:c:/aspectjweaver.jar  -cp c:/aspectjrt.jar;c:/de.tutorials.aop.tracing.jar;bin de.tutorials.TracingExample
WXYZ
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation1(java.lang.String) with arguments:([W]) and got result:(WXYZ)
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation2(java.lang.String, java.lang.String) with arguments:([W, X]) and got result:(WXYZ)
[main] called Method private static java.lang.Object de.tutorials.TracingExample.operation3(java.lang.String, java.lang.String, java.lang.String) with arguments:([W, X, Y]) and got result:(WXYZ)

Die AspectJ Bibliotheken findet man dann bei der AspectJ Distribution oder im lib Verzeichnis des Springframeworks.

Das Ausgeben/Aufsammeln von TraceStatements wird insbesondere in Multithreaded Umgebungen recht mühsam. Hier könnte man beispielsweise das Tracing in eine Textdatei vornehmen die man mit TimeStamps versieht und dann in einem späteren Schritt die darin mitgeschriebenen Statements anhand der Threadkennung und Timestamp- angaben wieder in die richtige Reihenfolge bringen.

Gruß Tom
 

Anhänge

  • 25991attachment.zip
    5 KB · Aufrufe: 44
  • 25992attachment.zip
    7 KB · Aufrufe: 45
Zuletzt bearbeitet von einem Moderator:
Hallo.
So richtig komem ich nicht klar...
also ich hab folgendes getan :
Ich habe mir ein AJDT-Plugin für Eclipse geladen und installiert,
auch, kann auch jetzt sagen : Runs As...--> AspectJ/Java Application
Desweiteren habe ich das von Dir mitgelieferte ZIP-File in ein Java-Eclipse-Projekt eingebunden. Darin sind ja die Dateien MethodCall.class, TracingAspect.class sowie die XML-Datei.

Sieht dann aus wie angefügt (Project.jpg):

Ich verwende folgenden Aufruf (in der LaunchConfiguration unter "Arguments") :

-Daj.weaving.verbose=true -javaagent:c:/aspectjweaver.jar -cp c:/aspectjrt.jar;de.tutorials.aop.tracing.jar;bin de.tutorials.TracingExample

Habe auch die Dateien aspectjweaver.jar und aspectjrt.jar brav auf C: abgelegt.

de.tutorials.aop.tracing.jar hab ich ja eingebunden
und das Package wo die TracingExample-Datei drin ist hat ja auch den richtigen Namen.

Nun sage ich "Run", aber er kommt nur die Ausgabe "WXYZ" (wie ohen Tracing).

Was mach ich denn noch falsch ?

Danke,
Stefan
 

Anhänge

  • 25996attachment.jpg
    25996attachment.jpg
    18,8 KB · Aufrufe: 27
Also meine LaunchConfig sieht nun aus wie angefügt, allerdings kommt dann
beim Starten eine (ebenfalls angefügte Fehlermeldung) mit der Begründung :

Code:
Unrecognized option: -javaagent:c:/aspectjweaver.jar

Wenn ich

Code:
-javaagent:c:/aspectjweaver.jar

weglasse, dann kommt wieder die Ausgabe

WXYZ.

Stefan
 

Anhänge

  • 25998attachment.jpg
    25998attachment.jpg
    68,3 KB · Aufrufe: 28
  • 25999attachment.jpg
    25999attachment.jpg
    6,9 KB · Aufrufe: 172
Zuletzt bearbeitet:

Neue Beiträge

Zurück