1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers.threads;
12
13 import java.lang.management.ManagementFactory;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import javax.management.MBeanServer;
18 import javax.management.MalformedObjectNameException;
19 import javax.management.ObjectName;
20 import javax.management.openmbean.CompositeData;
21 import javax.servlet.http.HttpServletRequest;
22 import javax.servlet.http.HttpServletResponse;
23
24 import org.springframework.beans.factory.annotation.Value;
25 import org.springframework.stereotype.Controller;
26 import org.springframework.web.bind.annotation.RequestMapping;
27 import org.springframework.web.servlet.ModelAndView;
28 import org.springframework.web.servlet.mvc.ParameterizableViewController;
29
30 import psiprobe.model.SunThread;
31 import psiprobe.model.ThreadStackElement;
32 import psiprobe.tools.JmxTools;
33
34
35
36
37 @Controller
38 public class ListSunThreadsController extends ParameterizableViewController {
39
40 @RequestMapping(path = "/th_impl2.htm")
41 @Override
42 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
43 throws Exception {
44 return super.handleRequest(request, response);
45 }
46
47 @Override
48 protected ModelAndView handleRequestInternal(HttpServletRequest request,
49 HttpServletResponse response) throws MalformedObjectNameException {
50
51 List<SunThread> threads = null;
52 int executionStackDepth = 1;
53
54 MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
55 ObjectName objectNameThreading = new ObjectName("java.lang:type=Threading");
56
57 long[] deadlockedIds = (long[]) JmxTools.invoke(mbeanServer, objectNameThreading,
58 "findMonitorDeadlockedThreads", null, null);
59 long[] allIds =
60 (long[]) JmxTools.getAttribute(mbeanServer, objectNameThreading, "AllThreadIds");
61
62 if (allIds != null) {
63 threads = new ArrayList<>(allIds.length);
64
65 for (long id : allIds) {
66 CompositeData cd = (CompositeData) JmxTools.invoke(mbeanServer, objectNameThreading,
67 "getThreadInfo", new Object[] {id, executionStackDepth}, new String[] {"long", "int"});
68
69 if (cd != null) {
70 SunThread st = new SunThread();
71 st.setId(JmxTools.getLongAttr(cd, "threadId"));
72 st.setName(JmxTools.getStringAttr(cd, "threadName"));
73 st.setState(JmxTools.getStringAttr(cd, "threadState"));
74 st.setSuspended(JmxTools.getBooleanAttr(cd, "suspended"));
75 st.setInNative(JmxTools.getBooleanAttr(cd, "inNative"));
76 st.setLockName(JmxTools.getStringAttr(cd, "lockName"));
77 st.setLockOwnerName(JmxTools.getStringAttr(cd, "lockOwnerName"));
78 st.setWaitedCount(JmxTools.getLongAttr(cd, "waitedCount"));
79 st.setBlockedCount(JmxTools.getLongAttr(cd, "blockedCount"));
80 st.setDeadlocked(contains(deadlockedIds, st.getId()));
81
82 CompositeData[] stack = (CompositeData[]) cd.get("stackTrace");
83 if (stack.length > 0) {
84 CompositeData cd2 = stack[0];
85 ThreadStackElement tse = new ThreadStackElement();
86 tse.setClassName(JmxTools.getStringAttr(cd2, "className"));
87 tse.setFileName(JmxTools.getStringAttr(cd2, "fileName"));
88 tse.setMethodName(JmxTools.getStringAttr(cd2, "methodName"));
89 tse.setLineNumber(JmxTools.getIntAttr(cd2, "lineNumber", -1));
90 tse.setNativeMethod(JmxTools.getBooleanAttr(cd2, "nativeMethod"));
91 st.setExecutionPoint(tse);
92 }
93
94 threads.add(st);
95 }
96 }
97 }
98 return new ModelAndView(getViewName(), "threads", threads);
99 }
100
101
102
103
104
105
106
107
108
109 private static boolean contains(long[] haystack, long needle) {
110 if (haystack != null) {
111 for (long hay : haystack) {
112 if (hay == needle) {
113 return true;
114 }
115 }
116 }
117 return false;
118 }
119
120 @Value("threads_sun")
121 @Override
122 public void setViewName(String viewName) {
123 super.setViewName(viewName);
124 }
125
126 }