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