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