blob: 24a6bc1cff1cdcc779754a38203361e3c1c52664 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.management;
27
28import java.lang.management.*;
29import java.util.logging.LogManager;
30
31import javax.management.DynamicMBean;
32import javax.management.MBeanServer;
33import javax.management.MBeanServerFactory;
34import javax.management.MBeanInfo;
35import javax.management.NotificationEmitter;
36import javax.management.ObjectName;
37import javax.management.ObjectInstance;
38import javax.management.InstanceAlreadyExistsException;
39import javax.management.InstanceNotFoundException;
40import javax.management.MBeanRegistrationException;
41import javax.management.NotCompliantMBeanException;
42import javax.management.MalformedObjectNameException;
43import javax.management.RuntimeOperationsException;
44import javax.management.StandardEmitterMBean;
45import javax.management.StandardMBean;
46import java.security.AccessController;
47import java.security.Permission;
48import java.security.PrivilegedActionException;
49import java.security.PrivilegedExceptionAction;
50import sun.security.action.LoadLibraryAction;
51
52import java.util.ArrayList;
53import java.util.List;
54import java.util.HashMap;
55import java.util.Map;
56import java.util.Set;
57import java.util.Iterator;
58import java.util.ListIterator;
59import com.sun.management.OSMBeanFactory;
60import com.sun.management.HotSpotDiagnosticMXBean;
61
62import static java.lang.management.ManagementFactory.*;
63
64/**
65 * ManagementFactory provides static factory methods to create
66 * instances of the management interface.
67 */
68public class ManagementFactory {
69 private ManagementFactory() {};
70
71 private static VMManagement jvm;
72
73 private static boolean mbeansCreated = false;
74 private static ClassLoadingImpl classMBean = null;
75 private static MemoryImpl memoryMBean = null;
76 private static ThreadImpl threadMBean = null;
77 private static RuntimeImpl runtimeMBean = null;
78 private static CompilationImpl compileMBean = null;
79 private static OperatingSystemImpl osMBean = null;
80
81 public static synchronized ClassLoadingMXBean getClassLoadingMXBean() {
82 if (classMBean == null) {
83 classMBean = new ClassLoadingImpl(jvm);
84 }
85 return classMBean;
86 }
87
88 public static synchronized MemoryMXBean getMemoryMXBean() {
89 if (memoryMBean == null) {
90 memoryMBean = new MemoryImpl(jvm);
91 }
92 return memoryMBean;
93 }
94
95 public static synchronized ThreadMXBean getThreadMXBean() {
96 if (threadMBean == null) {
97 threadMBean = new ThreadImpl(jvm);
98 }
99 return threadMBean;
100 }
101
102 public static synchronized RuntimeMXBean getRuntimeMXBean() {
103 if (runtimeMBean == null) {
104 runtimeMBean = new RuntimeImpl(jvm);
105 }
106 return runtimeMBean;
107 }
108
109 public static synchronized CompilationMXBean getCompilationMXBean() {
110 if (compileMBean == null && jvm.getCompilerName() != null) {
111 compileMBean = new CompilationImpl(jvm);
112 }
113 return compileMBean;
114 }
115
116 public static synchronized OperatingSystemMXBean getOperatingSystemMXBean() {
117 if (osMBean == null) {
118 osMBean = (OperatingSystemImpl)
119 OSMBeanFactory.getOperatingSystemMXBean(jvm);
120 }
121 return osMBean;
122 }
123
124 public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
125 MemoryPoolMXBean[] pools = MemoryImpl.getMemoryPools();
126 List<MemoryPoolMXBean> list = new ArrayList<MemoryPoolMXBean>(pools.length);
127 for (int i = 0; i < pools.length; i++) {
128 MemoryPoolMXBean p = pools[i];
129 list.add(p);
130 }
131 return list;
132 }
133
134 public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
135 MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
136 List<MemoryManagerMXBean> result = new ArrayList<MemoryManagerMXBean>(mgrs.length);
137 for (int i = 0; i < mgrs.length; i++) {
138 MemoryManagerMXBean m = mgrs[i];
139 result.add(m);
140 }
141 return result;
142 }
143
144 public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
145 MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
146 List<GarbageCollectorMXBean> result = new ArrayList<GarbageCollectorMXBean>(mgrs.length);
147 for (int i = 0; i < mgrs.length; i++) {
148 if (mgrs[i] instanceof GarbageCollectorMXBean) {
149 GarbageCollectorMXBean gc = (GarbageCollectorMXBean) mgrs[i];
150 result.add(gc);
151 }
152 }
153 return result;
154 }
155
156 private static HotSpotDiagnostic hsDiagMBean = null;
157 private static HotspotRuntime hsRuntimeMBean = null;
158 private static HotspotClassLoading hsClassMBean = null;
159 private static HotspotThread hsThreadMBean = null;
160 private static HotspotCompilation hsCompileMBean = null;
161 private static HotspotMemory hsMemoryMBean = null;
162
163 public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
164 if (hsDiagMBean == null) {
165 hsDiagMBean = new HotSpotDiagnostic();
166 }
167 return hsDiagMBean;
168 }
169
170 /**
171
172 /**
173 * This method is for testing only.
174 */
175 public static synchronized HotspotRuntimeMBean getHotspotRuntimeMBean() {
176 if (hsRuntimeMBean == null) {
177 hsRuntimeMBean = new HotspotRuntime(jvm);
178 }
179 return hsRuntimeMBean;
180 }
181
182 /**
183 * This method is for testing only.
184 */
185 public static synchronized HotspotClassLoadingMBean getHotspotClassLoadingMBean() {
186 if (hsClassMBean == null) {
187 hsClassMBean = new HotspotClassLoading(jvm);
188 }
189 return hsClassMBean;
190 }
191
192 /**
193 * This method is for testing only.
194 */
195 public static synchronized HotspotThreadMBean getHotspotThreadMBean() {
196 if (hsThreadMBean == null) {
197 hsThreadMBean = new HotspotThread(jvm);
198 }
199 return hsThreadMBean;
200 }
201
202 /**
203 * This method is for testing only.
204 */
205 public static synchronized HotspotMemoryMBean getHotspotMemoryMBean() {
206 if (hsMemoryMBean == null) {
207 hsMemoryMBean = new HotspotMemory(jvm);
208 }
209 return hsMemoryMBean;
210 }
211
212 /**
213 * This method is for testing only.
214 */
215 public static synchronized HotspotCompilationMBean getHotspotCompilationMBean() {
216 if (hsCompileMBean == null) {
217 hsCompileMBean = new HotspotCompilation(jvm);
218 }
219 return hsCompileMBean;
220 }
221
222 private static Permission monitorPermission =
223 new ManagementPermission("monitor");
224 private static Permission controlPermission =
225 new ManagementPermission("control");
226
227 /**
228 * Check that the current context is trusted to perform monitoring
229 * or management.
230 * <p>
231 * If the check fails we throw a SecurityException, otherwise
232 * we return normally.
233 *
234 * @exception SecurityException if a security manager exists and if
235 * the caller does not have ManagementPermission("control").
236 */
237 static void checkAccess(Permission p)
238 throws SecurityException {
239 SecurityManager sm = System.getSecurityManager();
240 if (sm != null) {
241 sm.checkPermission(p);
242 }
243 }
244
245 static void checkMonitorAccess() throws SecurityException {
246 checkAccess(monitorPermission);
247 }
248 static void checkControlAccess() throws SecurityException {
249 checkAccess(controlPermission);
250 }
251
252 /**
253 * Registers an MXBean and throws exception if an instance with the same
254 * name exists.
255 *
256 * This method makes a DynamicMBean out of an MXBean by wrapping it with a
257 * StandardMBean (StandardEmitterMBean if the supplied emitter is not null),
258 * so it can be registered in an MBeanServer which does not have support for
259 * MXBeans.
260 */
261 private static void addMXBean(MBeanServer mbs, Object mbean,
262 String mbeanName, NotificationEmitter emitter) {
263 // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
264 //
265 final DynamicMBean dmbean;
266 if (emitter == null) {
267 dmbean = new StandardMBean(mbean, null, true);
268 } else {
269 dmbean = new StandardEmitterMBean(mbean, null, true, emitter);
270 }
271 addMBean(mbs, dmbean, mbeanName, false);
272 }
273
274 /**
275 * Registers a Standard MBean or a Dynamic MBean and throws
276 * exception if an instance with the same name exists.
277 */
278 private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) {
279 addMBean(mbs, mbean, mbeanName, false);
280 }
281
282 private static void addMBean(MBeanServer mbs, Object mbean,
283 String mbeanName, boolean ignoreConflicts) {
284 try {
285 final ObjectName objName = new ObjectName(mbeanName);
286
287 // inner class requires these fields to be final
288 final MBeanServer mbs0 = mbs;
289 final Object mbean0 = mbean;
290 final boolean ignore = ignoreConflicts;
291 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
292 public Object run() throws InstanceAlreadyExistsException,
293 MBeanRegistrationException,
294 NotCompliantMBeanException {
295 try {
296 ObjectInstance o = mbs0.registerMBean(mbean0,
297 objName);
298 return null;
299 } catch (InstanceAlreadyExistsException e) {
300 // if an instance with the object name exists in
301 // the MBeanServer ignore the exception
302 // if ignoreConflicts is true;
303 // otherwise, throws exception.
304 if (!ignore) {
305 throw e;
306 }
307 }
308 return null;
309 }
310 });
311 } catch (PrivilegedActionException e) {
312 throw Util.newException(e.getException());
313 } catch (MalformedObjectNameException e) {
314 // should not reach here
315 throw Util.newException(e);
316 }
317 }
318
319 public static MBeanServer createPlatformMBeanServer() {
320 MBeanServer mbs = MBeanServerFactory.createMBeanServer();
321 // Register all the platform MBeans to this MBeanServer
322 addMXBean(mbs, getClassLoadingMXBean(),
323 CLASS_LOADING_MXBEAN_NAME, null);
324 addMXBean(mbs, getMemoryMXBean(),
325 MEMORY_MXBEAN_NAME, (NotificationEmitter) getMemoryMXBean());
326 addMXBean(mbs, getOperatingSystemMXBean(),
327 OPERATING_SYSTEM_MXBEAN_NAME, null);
328 addMXBean(mbs, getRuntimeMXBean(),
329 RUNTIME_MXBEAN_NAME, null);
330 addMXBean(mbs, getThreadMXBean(),
331 THREAD_MXBEAN_NAME, null);
332 addMXBean(mbs, getDiagnosticMXBean(),
333 HOTSPOT_DIAGNOSTIC_MXBEAN_NAME, null);
334
335 // CompilationMBean may not exist
336 if (getCompilationMXBean() != null) {
337 addMXBean(mbs, getCompilationMXBean(),
338 COMPILATION_MXBEAN_NAME, null);
339 }
340
341 // Register MBeans for memory pools and memory managers
342 addMemoryManagers(mbs);
343 addMemoryPools(mbs);
344
345 // Register platform extension
346 addMXBean(mbs, LogManager.getLoggingMXBean(),
347 LogManager.LOGGING_MXBEAN_NAME, null);
348
349 return mbs;
350 }
351
352 private final static String HOTSPOT_DIAGNOSTIC_MXBEAN_NAME =
353 "com.sun.management:type=HotSpotDiagnostic";
354
355 private final static String HOTSPOT_CLASS_LOADING_MBEAN_NAME =
356 "sun.management:type=HotspotClassLoading";
357
358 private final static String HOTSPOT_COMPILATION_MBEAN_NAME =
359 "sun.management:type=HotspotCompilation";
360
361 private final static String HOTSPOT_MEMORY_MBEAN_NAME =
362 "sun.management:type=HotspotMemory";
363
364 private static final String HOTSPOT_RUNTIME_MBEAN_NAME =
365 "sun.management:type=HotspotRuntime";
366
367 private final static String HOTSPOT_THREAD_MBEAN_NAME =
368 "sun.management:type=HotspotThreading";
369
370 private final static String HOTSPOT_INTERNAL_MBEAN_NAME =
371 "sun.management:type=HotspotInternal";
372
373 private static ObjectName hsInternalObjName = null;
374 static synchronized ObjectName getHotspotInternalObjectName() {
375 if (hsInternalObjName == null) {
376 try {
377 hsInternalObjName = new ObjectName(HOTSPOT_INTERNAL_MBEAN_NAME);
378 } catch (MalformedObjectNameException e) {
379 // should not reach here
380 throw Util.newException(e);
381 }
382 }
383 return hsInternalObjName;
384 }
385
386 static void registerInternalMBeans(MBeanServer mbs) {
387 // register all internal MBeans if not registered
388 // No exception is thrown if a MBean with that object name
389 // already registered (i.e. ignore if name conflicts).
390 addMBean(mbs, getHotspotClassLoadingMBean(),
391 HOTSPOT_CLASS_LOADING_MBEAN_NAME, true);
392 addMBean(mbs, getHotspotMemoryMBean(),
393 HOTSPOT_MEMORY_MBEAN_NAME, true);
394 addMBean(mbs, getHotspotRuntimeMBean(),
395 HOTSPOT_RUNTIME_MBEAN_NAME, true);
396 addMBean(mbs, getHotspotThreadMBean(),
397 HOTSPOT_THREAD_MBEAN_NAME, true);
398
399 // CompilationMBean may not exist
400 if (getCompilationMXBean() != null) {
401 addMBean(mbs, getHotspotCompilationMBean(),
402 HOTSPOT_COMPILATION_MBEAN_NAME, true);
403 }
404 }
405
406 private static void unregisterMBean(MBeanServer mbs, String mbeanName) {
407 try {
408 final ObjectName objName = new ObjectName(mbeanName);
409
410 // inner class requires these fields to be final
411 final MBeanServer mbs0 = mbs;
412 AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
413 public Object run() throws MBeanRegistrationException,
414 RuntimeOperationsException {
415 try {
416 mbs0.unregisterMBean(objName);
417 } catch (InstanceNotFoundException e) {
418 // ignore exception if not found
419 }
420 return null;
421 }
422 });
423 } catch (PrivilegedActionException e) {
424 throw Util.newException(e.getException());
425 } catch (MalformedObjectNameException e) {
426 // should not reach here
427 throw Util.newException(e);
428 }
429 }
430
431 static void unregisterInternalMBeans(MBeanServer mbs) {
432 // unregister all internal MBeans
433 unregisterMBean(mbs, HOTSPOT_CLASS_LOADING_MBEAN_NAME);
434 unregisterMBean(mbs, HOTSPOT_MEMORY_MBEAN_NAME);
435 unregisterMBean(mbs, HOTSPOT_RUNTIME_MBEAN_NAME);
436 unregisterMBean(mbs, HOTSPOT_THREAD_MBEAN_NAME);
437
438 // CompilationMBean may not exist
439 if (getCompilationMXBean() != null) {
440 unregisterMBean(mbs, HOTSPOT_COMPILATION_MBEAN_NAME);
441 }
442 }
443
444 private static synchronized void addMemoryPools(MBeanServer mbs) {
445
446 // Get a list of memory pools
447 MemoryPoolMXBean[] newPools = MemoryImpl.getMemoryPools();
448
449 for (int i = 0; i < newPools.length; i++) {
450 String poolObjNameString = Util.getMBeanObjectName(newPools[i]);
451 addMXBean(mbs, newPools[i], poolObjNameString, null);
452 }
453 }
454
455 // Register all memory managers with the MBeanServer;
456 private static synchronized void addMemoryManagers(MBeanServer mbs) {
457
458 // Get a list of memory managers
459 MemoryManagerMXBean[] newMgrs = MemoryImpl.getMemoryManagers();
460
461 for (int i = 0; i < newMgrs.length; i++) {
462 String mgrObjNameString = Util.getMBeanObjectName(newMgrs[i]);
463 addMXBean(mbs, newMgrs[i], mgrObjNameString, null);
464 }
465 }
466
467 // Invoked by the VM
468 private static MemoryPoolMXBean createMemoryPool
469 (String name, boolean isHeap, long uThreshold, long gcThreshold) {
470 return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold);
471 }
472
473 private static MemoryManagerMXBean createMemoryManager(String name) {
474 return new MemoryManagerImpl(name);
475 }
476
477 private static GarbageCollectorMXBean
478 createGarbageCollector(String name, String type) {
479
480 // ignore type parameter which is for future extension
481 return new GarbageCollectorImpl(name);
482 }
483
484 static {
485 AccessController.doPrivileged(new LoadLibraryAction("management"));
486 jvm = new VMManagementImpl();
487 }
488
489 public static boolean isThreadSuspended(int state) {
490 return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0);
491 }
492
493 public static boolean isThreadRunningNative(int state) {
494 return ((state & JMM_THREAD_STATE_FLAG_NATIVE) != 0);
495 }
496
497 public static Thread.State toThreadState(int state) {
498 // suspended and native bits may be set in state
499 int threadStatus = state & ~JMM_THREAD_STATE_FLAG_MASK;
500 return sun.misc.VM.toThreadState(threadStatus);
501 }
502
503 // These values are defined in jmm.h
504 private static final int JMM_THREAD_STATE_FLAG_MASK = 0xFFF00000;
505 private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000;
506 private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000;
507
508}