Repository: tapestry-5 Updated Branches: refs/heads/master 5b311716e -> ce6e66ea3
Include a list of threads in the default exception report page Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/08807a12 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/08807a12 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/08807a12 Branch: refs/heads/master Commit: 08807a1266b49cc5d76ac38705ab7fe31e893b6e Parents: 5b31171 Author: Howard M. Lewis Ship <[email protected]> Authored: Fri May 30 16:05:33 2014 -0700 Committer: Howard M. Lewis Ship <[email protected]> Committed: Fri May 30 16:55:24 2014 -0700 ---------------------------------------------------------------------- 54_RELEASE_NOTES.md | 4 + .../corelib/pages/ExceptionReport.java | 100 ++++++++++++++++++- .../META-INF/assets/core/ExceptionReport.css | 13 +++ .../tapestry5/corelib/pages/ExceptionReport.tml | 21 ++++ 4 files changed, 135 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/54_RELEASE_NOTES.md ---------------------------------------------------------------------- diff --git a/54_RELEASE_NOTES.md b/54_RELEASE_NOTES.md index 8044c85..23fc912 100644 --- a/54_RELEASE_NOTES.md +++ b/54_RELEASE_NOTES.md @@ -155,6 +155,10 @@ The FormFragment component's visibleBound parameter is no longer supported; it w far up the DOM above the FormFragment's client-side element should be searched when determining visibility. This may resurface in the future as a CSS expression, but is currently not supported. +## ExceptionReport Page + +The default exception report page has been modified to display a list of threads. + ## Symbol tapestry.asset-path-prefix The definition of the symbol 'tapestry.asset-path-prefix' has changed; it no longer includes the leading and trailing http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java index e6db1ed..1ca7e25 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/ExceptionReport.java @@ -21,16 +21,20 @@ import org.apache.tapestry5.annotations.ContentType; import org.apache.tapestry5.annotations.Import; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.annotations.UnknownActivationContextCheck; +import org.apache.tapestry5.func.F; +import org.apache.tapestry5.func.Mapper; import org.apache.tapestry5.internal.InternalConstants; import org.apache.tapestry5.internal.services.PageActivationContextCollector; import org.apache.tapestry5.internal.services.ReloadHelper; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.annotations.Symbol; +import org.apache.tapestry5.ioc.internal.util.CollectionFactory; import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.services.*; import java.net.MalformedURLException; import java.net.URL; +import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; @@ -99,17 +103,42 @@ public class ExceptionReport implements ExceptionReporter @Inject private ReloadHelper reloadHelper; - + @Inject private URLEncoder urlEncoder; @Property private String rootURL; + @Property + private ThreadInfo thread; + + public class ThreadInfo implements Comparable<ThreadInfo> + { + public final String className, name, flags; + + public final ThreadGroup group; + + public ThreadInfo(String className, String name, String flags, ThreadGroup group) + { + this.className = className; + this.name = name; + this.flags = flags; + this.group = group; + } + + @Override + public int compareTo(ThreadInfo o) + { + return name.compareTo(o.name); + } + } + private final String pathSeparator = System.getProperty(PATH_SEPARATOR_PROPERTY); - public boolean isShowActions() { - return failurePage != null && ! request.isXHR(); + public boolean isShowActions() + { + return failurePage != null && !request.isXHR(); } public void reportException(Throwable exception) @@ -182,4 +211,69 @@ public class ExceptionReport implements ExceptionReporter return getPropertyValue().split(pathSeparator); } + + private Thread[] assembleThreads() + { + ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); + + while (true) + { + ThreadGroup parentGroup = rootGroup.getParent(); + if (parentGroup == null) + { + break; + } + rootGroup = parentGroup; + } + + Thread[] threads = new Thread[rootGroup.activeCount()]; + + while (true) + { + // A really ugly API. threads.length must be larger than + // the actual number of threads, just so we can determine + // if we're done. + int count = rootGroup.enumerate(threads, true); + if (count < threads.length) + { + return Arrays.copyOf(threads, count); + } + threads = new Thread[threads.length * 2]; + } + } + + public List<ThreadInfo> getThreads() + { + return F.flow(assembleThreads()).map(new Mapper<Thread, ThreadInfo>() + { + @Override + public ThreadInfo map(Thread t) + { + List<String> flags = CollectionFactory.newList(); + + if (t.isDaemon()) + { + flags.add("daemon"); + } + if (!t.isAlive()) + { + flags.add("NOT alive"); + } + if (t.isInterrupted()) + { + flags.add("interrupted"); + } + + if (t.getPriority() != Thread.NORM_PRIORITY) + { + flags.add("priority " + t.getPriority()); + } + + return new ThreadInfo(Thread.currentThread() == t ? "active-thread" : "", + t.getName(), + InternalUtils.join(flags), + t.getThreadGroup()); + } + }).sort().toList(); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css b/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css index e770da3..87fdab6 100644 --- a/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css +++ b/tapestry-core/src/main/resources/META-INF/assets/core/ExceptionReport.css @@ -1,3 +1,16 @@ body { padding-top: 55px; +} + +table.exception-report-threads td, table.exception-report-threads th { + text-align: right; +} + +table.exception-report-threads tr td:last-child, +table.exception-report-threads tr th:last-child { + text-align: left; +} + +table.exception-report-threads tr.active-thread { + font-weight: bold; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/08807a12/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml index c26ebf1..0190b80 100644 --- a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/ExceptionReport.tml @@ -94,6 +94,27 @@ </dl> </t:if> + <h3>Threads</h3> + + <table class="table table-compact table-striped exception-report-threads"> + <thread> + <tr> + <th>Thread Name</th> + <th>Group Name</th> + <th>Flags</th> + </tr> + </thread> + <tbody> + + <tr t:type="loop" source="threads" value="thread" class="${thread.className}"> + <td class="thread-name">${thread.name}</td> + <td>${thread.group?.name}</td> + <td>${thread.flags}</td> + </tr> + </tbody> + </table> + + <h3>System Properties</h3> <dl> <t:loop source="systemProperties" value="propertyName">
