# Aus welcher Klasse wurde Methode aufgerufen



## Guest (2. Aug 2004)

Hallo!

Wenn ich in Methode X einen Aufruf von Methode Y habe, gibt es eine Möglichkeit, wie in Y festgestellt werden kann, aus welcher Methode/Klasse dieser Aufruf stattfand? 

Mit ist bewußt, daß in den Parametern this mitgegeben werden kann und mit getClass().getName() auf die Klasse zugegriffen werden kann, aber eben nur, wenn sie in den Paras übergeben wurde, oder? 
Gibts da noch eine andere Möglichkeit?

Bin für jede Anregung dankbar.


Gruss,
Krabat


----------



## Beni (2. Aug 2004)

Du könntest eine Exception (new Exception() ) bauen, und dann den Stacktrace (Exception#getStackTrace()) abfragen.

Es gibt irgendwo noch eine elegantere Methode, aber ich weiss nicht mehr wo  :?


----------



## Roar (2. Aug 2004)

hmm mit Java 5 ginge das so:

```
String name = Thread.currentThread().getStackTrace()[0].getMethodName();
```

was anderes fällt mir auch nicht ein...


----------



## Krabat (2. Aug 2004)

@Beni:
Wo könnte ich denn nach der eleganteren Methode anfangen zu suchen?

@Roar:
was ist Java 5? Java v1.5?
getStackTrace() kann er leider nicht finden beim return Wert von currentThread()...


----------



## Illuvatar (2. Aug 2004)

1. In der API.

2. Genau.http://java.sun.com/j2se/1.5.0/download.jsp


----------



## Roar (2. Aug 2004)

ich hab mal gesucht, ich finde wirklich keine andere möglichkeit. nichmal in den management extensions.. oder ich bin einfach nur blind :autsch:


----------



## thE_29 (2. Aug 2004)

ich habe eine gefunden! Nur leider weiß ich sie nicht auswendig, hab sie aber in der Firma verwendet!

Hab ziemlich lange im Internet gesucht, poste es dann morgen!


----------



## Grizzly (2. Aug 2004)

Mich würde interessieren, wofür Du das brauchst. Ich programmiere schon einige ziemlich lange Zeit, aber eine sinnvollen Einsatz fällt mir dazu nicht ein ???:L . Vielleicht kann man das Problem ja auch ganz anders lösen  .


----------



## meez (2. Aug 2004)

Grizzly hat gesagt.:
			
		

> Mich würde interessieren, wofür Du das brauchst. Ich programmiere schon einige ziemlich lange Zeit, aber eine sinnvollen Einsatz fällt mir dazu nicht ein ???:L . Vielleicht kann man das Problem ja auch ganz anders lösen  .



Frag ich mich auch...:bahnhof:


----------



## Krabat (2. Aug 2004)

ok, ich hoffe, das klingt jetzt nicht irgendwie hohl, aber ich habe ein log Fenster gebaut, an welches aktuelle Trace Meldungen geschickt werden. Das möchte ich zum debuggen und für info/status Meldungen nutzen und soll in einem seperaten Package bei jedem neuen Projekt das debuggen erleichtern. 

Dann hatte mich (ich glaube es war) Roar im Chat darauf aufmerksam gemacht, daß es bereits sowas in der Art in *java.util.loggin* gibt. Dabei ich die letzten beiden Tage damit verbracht die Log Klasse zusammen mit dem Fenster und dem Table(Model/Renderer) zu implementieren. Daher möchte ich es gerne fertigstellen.

Da es ein wenig umständlich ist, wenn bei jeder Meldung die aktuelle Klasse+Methode mitgeschickt wird, es aber sinnig ist, diese Informationen zu sehen, dachte ich mir, man könne es vielleicht automatisieren.


----------



## Guest (2. Aug 2004)

So spontan fällt mir sowas ein.

```
public static String invokedBy() {
    try {
      throw new Exception();
    }
    catch(Exception e) {
      try {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        sw.flush();
        sw.close();
        LineNumberReader r = new LineNumberReader(new StringReader(sw.getBuffer().toString()));
        r.readLine();
        r.readLine();
        r.readLine();
        String method = r.readLine().trim();
        r.close();
        return method.substring(3, method.indexOf('('));
      }
      catch(IOException ioe) {
        return null;
      }
    }
  }
```
Einfach diese Methode aufrufen und das Ergebnis ist die Methode,
die die aktuelle aufgerufen hat.


----------



## Roar (2. Aug 2004)

ich hab oben schon den code gepostet der dazu nötig ist. ist wohl etwas kürzer und weniger umständlicher (erst in datei schreiben dann wieder auslesen?)

es geht darum eine weniger schmutzige methode zu haben


----------



## Grizzly (2. Aug 2004)

Zum Loggen verwende ich bspw. das Jakarta Commons Logging. Das sieht dann im Code in etwa so aus (Hab' das aus einer meiner Quellcodes mal kurz rauskopiert):

```
public final class ColorTable {
	/** Das Logging-Objekt für diese Klasse. */
	private static Log log = LogFactory.getLog(ColorTable.class);
	
	/** Und so weiter und so fort. */
	
	/**
	 * Dies ist der Standard Konstruktor.
	 */
	private ColorTable() {
		super();
		final int maxColorNumber = 256;
		int red, green, blue;
		
		// Maximal: 32, Minimal: 4
		this.anzahl = maxColorNumber / colorDifference;
		
		log.debug("ColorTable()");
		log.trace("\tFarbabstand          = " + colorDifference);
		log.trace("\tFarbanzahl           = " + (this.anzahl + 1));
		log.trace("\tFarbanzahl insgesamt = " + ((this.anzahl + 1) * (this.anzahl + 1) * (this.anzahl + 1)));
		
		/** Und so weiter und so fort. */
		
	}
	
	/** Und so weiter und so fort. */
}
```
Und durch _LogFactory.getLog(ColorTable.class);_ weiss bspw. der Logger von welcher Klasse die Infos stammen. Eine Ausgabe der Meldung in bspw. einer JTextArea wäre natürlich auch möglich. Wobei man Logging-Meldungen ja eher in die Konsole oder eine Log-Datei ausgibt.


----------



## Krabat (2. Aug 2004)

Hi!

Danke Euch vielmals für Eure Ideen! 


Bin noch gespannt, ob _thE_29_ es anders gelöst hat ...
Gruss
Krabat


----------



## thE_29 (3. Aug 2004)

so, also hier ist meine Lösung



```
Throwable t = new Throwable();
      StackTraceElement[] ste = t.getStackTrace();
//bei mir war es einmal in ste[1].getClassName(); und 1mal in ste[3].getClassName();
//kommt darauf wie verschachtelt die Klasse ist, es steht dann das gesamte Package.Klasse drinnen
```

So gings bei mir und dann muss man auch nix werfen und ich hab das auch fürs loggen und für eine Klasse die von verschiedene Klassen aber mit verschiedenen Parameteren gebraucht wird (Klassenabhängig)!

beim Logger hatte ich ste[1] und beim anderen ste[3].getClassName()

Musst du schauen!


----------



## citizen_erased (3. Aug 2004)

eclipse biietet die funktion "open call hierarchy"


----------



## thE_29 (3. Aug 2004)

und was soll das bringen, wenn ein Editor die aufrufende Methode rausfindet?


----------



## Krabat (3. Aug 2004)

Roar hat gesagt.:
			
		

> hmm mit Java 5 ginge das so:
> 
> ```
> String name = Thread.currentThread().getStackTrace()[0].getMethodName();
> ...







			
				thE_29 hat gesagt.:
			
		

> so, also hier ist meine Lösung
> 
> ```
> Throwable t = new Throwable();
> ...





Habe beide Lösungen ausprobiert und *beide funktionieren super!* 
Frage mich nur noch, ob es einen größeren Unterschied zwischen diesen Möglichkeiten gibt?
Bei der Thread-Variante wird wahrscheinlich nur der aktuelle Thread betrachtet und wenn ich in meinem Programm keine neuen Threads anlege, handelt es sich wahrscheinlich nur um einen(?), wird also keine Probleme verursachen. Habe ich aber mehrere Threads, wird dann stets nur der eine, aktuelle Thread betrachtet? Müßte man dann pro Thread ein Log Objekt anlegen? (was schwierig wäre, wenn alle Ihre Ausgaben in dasselbe Fenster/Table schreiben sollen.

Wäre dann Throwable eine Lösung, um um die Thread-Grenzen hinweg das Logging zu aktivieren?


----------



## Illuvatar (3. Aug 2004)

Das mit den Threads ist egal, es wird die aufrufende Methode ausgegeben, ist doch egal, welcher Thread die Methode aufruft.

Im Allgemeinen finde ich Roars Lösung besser, denn:
1. sie ist kürzer
2. die Klasse Throwable wird auch irgendwie über diese Methode gehen
3. die Klasse Throwable ist für andere Dinge gedacht, die Klasse Thread passt besser.


----------



## Krabat (3. Aug 2004)

Illuvatar hat gesagt.:
			
		

> Das mit den Threads ist egal, es wird die aufrufende Methode ausgegeben, ist doch egal, welcher Thread die Methode aufruft.



hmm.... *grübel*
Wenn also Thread A mein Log aufruft. Mein Log läuft aber in Thread B, wird obwohl die Methode ...


```
ThreadB.currentThread()[x].getMethodName();
```

...in Thread B aufgerufen, trotzdem die aufrufende Methode in Thread A gefunden? Das wäre natürlich richtig fett! 




[edit] Formatierung ausgebessert.


----------



## bygones (3. Aug 2004)

mhm - ich glaub das versteh ich net so recht...
das mit dem loggen ist klar - wie rufst du denn in einem projekt denn den Logger auf ? warum kannst du nicht einfach in dem Aufruf des Loggers den Klassennamen / Methoden namen mitgeben ?
bzw. warum nicht einfach den SDK logger nehmen und als Handler ein Fenster nehmen ?!


----------



## Illuvatar (3. Aug 2004)

```
public class ThreadTest
{
  private Logger l;
  public static void main (String[] args)
  {
     new ThreadTest();
  }
  public ThreadTest()
  {
      l = new Logger();
      new T1().start();
      new T2().start();
  }
  void runt1(){
    l.log();  //Ausgabe: runt1
  }
  void runt2(){
    l.log();  //Ausgabe: runt2
  }
  class T1 extends Thread
  {
    public void run()
    {
      runt1();
    }
  }
  class T2 extends Thread
  {
    public void run()
    {
      runt2();
    }
  }
  class Logger
  {
    public void log()
    {
      String name = Thread.currentThread().getStackTrace()[3].getMethodName();  //0: dumpThreads, 1: getStackTrace(), 2: log()
      System.out.println(name);
    }
  }
}
```

Edit: Vielleicht hast du das falsch verstanden:
*currentThread() ist eine Klassenmethode von Thread*, und gibt den Thread, der diese Methode aufruft, zurück, und der Thread hat eben den gesuchten Stacktrace.


----------



## thE_29 (3. Aug 2004)

oder du nimmst meine Methode, weil ein Thread is sicherlich auch nicht für das gedacht 

SO


----------



## Illuvatar (3. Aug 2004)

Die Methode Thread#getStackTrace ist genau dafür gemacht, der Umweg über Exception ist von mir aus gerade noch ein Workaround vor 1.5. Ende der Diskussion.


----------



## Roar (3. Aug 2004)

deathbyaclown hat gesagt.:
			
		

> bzw. warum nicht einfach den SDK logger nehmen und als Handler ein Fenster nehmen ?!



er hat halt schon angefangen das selbst zu schrieben und wills dann auch benutzen. kann ich auch verstehn...


----------

