View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
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   * The Class ListSunThreadsController.
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    * Contains.
103    *
104    * @param haystack the haystack
105    * @param needle the needle
106    *
107    * @return true, if successful
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 }