habe ein kleines Problem. Ich habe ein Servlet geschrieben, welches
unter WebLogic alle Thread ausgibt, die in diesem Prozess laufen. Zu
jedem Thread möchte ich ausserdem dumpStack aufrufen.
t.dumpStack();
Leider führt das zu folgender Ausgabe:
2002-01-04 11:54:39,178 DEBUG - [com.firma.icafe.ThreadsViewerServlet]
- generatePage() call dumpStack() for HighPriority TimeEventGenerator
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java)
at
com.firma.icafe.ThreadsViewerServlet.generatePage(ThreadsViewerServlet.java:117)
at
com.firma.icafe.ThreadsViewerServlet.doGet(ThreadsViewerServlet.java:59)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at
com.firma.icafe.LogFilesHttpServlet.executeService(LogFilesHttpServlet.java)
at
com.firma.icafe.LogFilesHttpServlet.service(LogFilesHttpServlet.java)
at com.firma.icafe.S2GHttpServlet.service(S2GHttpServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:865)
at
weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:123)
at
weblogic.servlet.internal.ServletContextImpl.invokeServlet(ServletContextImpl.java:761)
at
weblogic.servlet.internal.ServletContextImpl.invokeServlet(ServletContextImpl.java:708)
at
weblogic.servlet.internal.ServletContextManager.invokeServlet(ServletContextManager.java:252)
at
weblogic.socket.MuxableSocketHTTP.invokeServlet(MuxableSocketHTTP.java:346)
at
weblogic.socket.MuxableSocketHTTP.execute(MuxableSocketHTTP.java:246)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:135)
Das bekomme ich mit JDK 1.1.8 und JDK 1.3.0 unter AIX. Muss ich noch was
beachten?
Schöne Grüße
Rafal Kedziorski
> t.dumpStack();
>
> Leider führt das zu folgender Ausgabe:
>
> 2002-01-04 11:54:39,178 DEBUG - [com.firma.icafe.ThreadsViewerServlet]
> - generatePage() call dumpStack() for HighPriority TimeEventGenerator
> java.lang.Exception: Stack trace
> at java.lang.Thread.dumpStack(Thread.java)
...
Kann es nicht sein, dass das genau das ist, was man von dumpStack erwartet?
Einen StackTrace ausdumpen?
(Lass Dich nicht von java.lang.Exeption täuschen. Das ist nur eine
Dummy-Exception)
Gruss: Martin.
Martin Erren wrote:
> Hallo Rafael!
>
> > t.dumpStack();
> >
> > Leider führt das zu folgender Ausgabe:
> >
> > 2002-01-04 11:54:39,178 DEBUG - [com.firma.icafe.ThreadsViewerServlet]
> > - generatePage() call dumpStack() for HighPriority TimeEventGenerator
> > java.lang.Exception: Stack trace
> > at java.lang.Thread.dumpStack(Thread.java)
>
> ...
>
> Kann es nicht sein, dass das genau das ist, was man von dumpStack erwartet?
Eher nicht.
> Einen StackTrace ausdumpen?
> (Lass Dich nicht von java.lang.Exeption täuschen. Das ist nur eine
> Dummy-Exception)
Aber ein dumpStack sollte doch zeigen, was ein Thread gerade tut. Und das sehe
ich nicht. Für alle Threads habe ich die gleiche Ausgabe.
Gruss
Rafal
Bist Du sicher dass es nicht immer der selbe ist, der Current Thread von
ThreadViewerServlet? Dazu bräuchte ich etwas Code. Oder versuchs mit
int ThreadGroup#enumerate(ThreadGroup[] list)
> Aber ein dumpStack sollte doch zeigen, was ein Thread gerade tut. Und das
> sehe ich nicht. Für alle Threads habe ich die gleiche Ausgabe.
Das liegt daran, dass Thread.dumpStack eine static-Methode ist, und sich
*immer* auf den ausführenden Thread bezieht. Es ist nicht möglich, einen
Stack-Dump eines anderen Threads zu bekommen - außer mit ganz anderen
Mitteln (Debugger-Interface).
Matthias
--
Matthias Ernst - SoftwareIngenieur
CoreMedia AG - http://www.coremedia.com - 0700-COREMEDIA
Wie man in der Doku von java.lang.Thread sehen kann,
ist die Methode dumpThread static, also eine
Klassenmethode.
Du solltest also statt
t.dumpThread()
lieber
Thread.dumpStack()
schreiben, das ist klarer.
Und nun siehst du auch, dass das nichts mit
den einzelnen Threads zu tun haben kann.
Wie weiter in der Doku steht, bezieht sich
dumpThread immer auf den Thread, _von_ dem
es aufgerufen wurde.
Damit _muss_ immer das selbe Ergebnis
herauskommen.
Du brauchst wohl einen echten Debugger,
um an die anderen Threads heanzukommen.
HTH
Paul
Martin Erren wrote:
ich mache folgendes:
Thread[] thread = findAllThreads();
int columnCount = 6;
Object[][] cell = new Object[thread.length][columnCount];
for (int i = 0; i < thread.length; i++) {
Thread t = thread[i];
try {
Debug.debug(this, "generatePage() call dumpStack() for " +
t.getName());
t.dumpStack();
}
catch (RuntimeException re) {
}
Object[] rowCell = cell[i];
rowCell[0] = new Integer(t.getPriority());
rowCell[1] = new Boolean(t.isAlive());
rowCell[2] = new Boolean(t.isDaemon());
rowCell[3] = new Boolean(t.isInterrupted());
rowCell[4] = t.getThreadGroup().getName();
rowCell[5] = t.getName();
// html content
out.println("<tr>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + (i + 1) + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[4] + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[5] + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[0] + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[1] + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[2] + "</font></center></td>");
out.println("<td><center><font size=\"2\"
face=\"verdana,arial,helvetica\">" + rowCell[3] + "</font></center></td>");
out.println("</tr>");
}
...
private Thread[] findAllThreads() {
ThreadGroup group = Thread.currentThread().getThreadGroup();
ThreadGroup topGroup = group;
while (group != null) {
topGroup = group;
group = group.getParent();
}
int estimatedSize = topGroup.activeCount() * 2;
Thread[] slackList = new Thread[estimatedSize];
int actualSize = topGroup.enumerate(slackList);
Thread[] list = new Thread[actualSize];
System.arraycopy(slackList, 0, list, 0, actualSize);
return list;
}
Paul Ebermann wrote:
Das mit static habe ich übersehen. Gibt es eine andere Methode an den Dump eines
Threads zu kommen? kill -3 liefert da was, aber man hat ja nicht immer die Chance
das aufzurufen.
Gruss
Rafal