Coverage Report - sk.baka.webvm.ThreadDump
 
Classes in this File Line Coverage Branch Coverage Complexity
ThreadDump
55%
20/36
25%
3/12
2.333
ThreadDump$1
N/A
N/A
2.333
ThreadDump$ThreadListModel
0%
0/8
0%
0/4
2.333
ThreadDump$ThreadListView
0%
0/6
N/A
2.333
 
 1  
 /**
 2  
  * Copyright 2009 Martin Vysny.
 3  
  *
 4  
  * This file is part of WebVM.
 5  
  *
 6  
  * WebVM is free software: you can redistribute it and/or modify
 7  
  * it under the terms of the GNU General Public License as published by
 8  
  * the Free Software Foundation, either version 3 of the License, or
 9  
  * (at your option) any later version.
 10  
  *
 11  
  * WebVM is distributed in the hope that it will be useful,
 12  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  
  * GNU General Public License for more details.
 15  
  *
 16  
  * You should have received a copy of the GNU General Public License
 17  
  * along with WebVM.  If not, see <http://www.gnu.org/licenses/>.
 18  
  */
 19  
 package sk.baka.webvm;
 20  
 
 21  
 import java.lang.management.ManagementFactory;
 22  
 import java.lang.management.ThreadInfo;
 23  
 import java.lang.management.ThreadMXBean;
 24  
 import java.util.ArrayList;
 25  
 import java.util.List;
 26  
 import org.apache.wicket.markup.html.basic.Label;
 27  
 import org.apache.wicket.markup.html.list.ListItem;
 28  
 import org.apache.wicket.markup.html.list.ListView;
 29  
 import org.apache.wicket.model.IModel;
 30  
 import org.apache.wicket.model.LoadableDetachableModel;
 31  
 
 32  
 /**
 33  
  * Performs and displays a full thread dump.
 34  
  * @author vyzivus
 35  
  */
 36  
 public final class ThreadDump extends WebVMPage {
 37  
 
 38  
     private static final long serialVersionUID = 1L;
 39  
 
 40  
     /**
 41  
      * Constructor.
 42  
      */
 43  0
     public ThreadDump() {
 44  0
         border.add(new ThreadListView("threadList", new ThreadListModel()));
 45  0
     }
 46  
 
 47  
     /**
 48  
      * Provides a list of all VM threads.
 49  
      */
 50  0
     private static class ThreadListModel extends LoadableDetachableModel<List<ThreadInfo>> {
 51  
 
 52  
         private static final long serialVersionUID = 1L;
 53  
 
 54  
         @Override
 55  
         protected List<ThreadInfo> load() {
 56  0
             final ThreadMXBean bean = ManagementFactory.getThreadMXBean();
 57  0
             final ThreadInfo[] info = bean.getThreadInfo(bean.getAllThreadIds(), Integer.MAX_VALUE);
 58  0
             final List<ThreadInfo> result = new ArrayList<ThreadInfo>(info.length);
 59  0
             for (final ThreadInfo i : info) {
 60  0
                 if (i != null) {
 61  0
                     result.add(i);
 62  
                 }
 63  
             }
 64  0
             return result;
 65  
         }
 66  
     }
 67  
 
 68  
     /**
 69  
      * Wicket ListView which displays a thread list.
 70  
      */
 71  
     private static class ThreadListView extends ListView<ThreadInfo> {
 72  
 
 73  
         public ThreadListView(String id, IModel<? extends List<? extends ThreadInfo>> model) {
 74  0
             super(id, model);
 75  0
         }
 76  
         private static final long serialVersionUID = 1L;
 77  
 
 78  
         @Override
 79  
         protected void populateItem(final ListItem<ThreadInfo> item) {
 80  0
             final ThreadInfo info = item.getModelObject();
 81  0
             item.add(new Label("threadName", getThreadMetadata(info)));
 82  0
             item.add(new Label("threadStacktrace", getThreadStacktrace(info)));
 83  0
         }
 84  
     }
 85  
 
 86  
     /**
 87  
      * Shows a basic thread info: thread ID, whether the thread is native, suspended, etc.
 88  
      * @param info the thread info.
 89  
      * @return pretty-printed thread info.
 90  
      */
 91  
     public static String getThreadMetadata(final ThreadInfo info) {
 92  12
         final StringBuilder sb = new StringBuilder();
 93  12
         sb.append("0x");
 94  12
         sb.append(Long.toHexString(info.getThreadId()));
 95  12
         sb.append(" [");
 96  12
         sb.append(info.getThreadName());
 97  12
         sb.append("] ");
 98  12
         sb.append(info.getThreadState().toString());
 99  12
         if (info.isInNative()) {
 100  0
             sb.append(", in native");
 101  
         }
 102  12
         if (info.isSuspended()) {
 103  0
             sb.append(", suspended");
 104  
         }
 105  12
         final String lockName = info.getLockName();
 106  12
         if (lockName != null) {
 107  12
             sb.append(", locked on [");
 108  12
             sb.append(lockName);
 109  12
             sb.append("]");
 110  12
             sb.append(" owned by thread ");
 111  12
             sb.append(info.getLockOwnerId());
 112  12
             sb.append(" [");
 113  12
             sb.append(info.getLockOwnerName());
 114  12
             sb.append("]");
 115  
         }
 116  12
         return sb.toString();
 117  
     }
 118  
 
 119  
     /**
 120  
      * Pretty-prints a thread stacktrace, similar to {@link Throwable#printStackTrace()} except that it handles nulls correctly.
 121  
      * @param info
 122  
      * @return string representation of the stacktrace.
 123  
      */
 124  
     public static String getThreadStacktrace(final ThreadInfo info) {
 125  0
         final StringBuilder sb = new StringBuilder();
 126  0
         final StackTraceElement[] stack = info.getStackTrace();
 127  0
         if (stack == null) {
 128  0
             sb.append("  stack trace not available");
 129  0
         } else if (stack.length == 0) {
 130  0
             sb.append("  stack trace is empty");
 131  
         } else {
 132  0
             for (final StackTraceElement ste : stack) {
 133  0
                 sb.append("  at ");
 134  0
                 sb.append(ste.toString());
 135  0
                 sb.append('\n');
 136  
             }
 137  
         }
 138  0
         return sb.toString();
 139  
     }
 140  
 }