GNU Classpath (0.95) | |
Frames | No Frames |
1: /* MBeanServerFactory.java -- Manages server instances. 2: Copyright (C) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package javax.management; 39: 40: import gnu.classpath.SystemProperties; 41: 42: import java.util.ArrayList; 43: import java.util.HashMap; 44: import java.util.Iterator; 45: import java.util.Map; 46: 47: import javax.management.loading.ClassLoaderRepository; 48: 49: /** 50: * <p> 51: * Creates and maintains a set of {@link MBeanServer} instances. 52: * Server instances, as of JMX 1.2, are created using a subclass 53: * of {@link MBeanServerBuilder}. The exact class used is controlled 54: * by the property <code>javax.management.builder.initial</code>, 55: * and allows the instances created by {@link MBeanServerBuilder} 56: * to be wrapped, thus providing additional functionality. 57: * </p> 58: * <p> 59: * The property is used as follows: 60: * </p> 61: * <ol> 62: * <li>If the property has no value, then an instance of 63: * {@link MBeanServerBuilder} is used.</li> 64: * <li>If a value is given, then: 65: * <ol> 66: * <li>The class is loaded using 67: * <code>Thread.currentThread().getContextClassLoader()</code>, or, 68: * if this is <code>null</code>, by <code>Class.forName()</code>.</li> 69: * <li><code>Class.newInstance()</code> is used to create an instance 70: * of the class. The class must be public and have a public empty 71: * constructor. If an exception is thrown, it is propogated as 72: * a {@link JMRuntimeException} and no new server instances may be 73: * created until the property is set to a valid value.</li> 74: * </ol></li> 75: * <li>The value is checked on each successive request for a server. 76: * If it differs from the class of the existing instance of 77: * {@link MBeanServerBuilder}, then the value is used to create 78: * a new instance.</li> 79: * </ol> 80: */ 81: public class MBeanServerFactory 82: { 83: 84: /** 85: * The last builder instance. 86: */ 87: private static MBeanServerBuilder builder; 88: 89: /** 90: * The map of registered servers (identifiers to servers). 91: */ 92: private static final Map<Object,MBeanServer> servers = new HashMap(); 93: 94: /** 95: * Private constructor to prevent instance creation. 96: */ 97: private MBeanServerFactory() {} 98: 99: /** 100: * Returns a server implementation using the default domain name 101: * of <code>"DefaultDomain"</code>. The default domain name is 102: * used when the domain name specified by the user is <code>null</code. 103: * A reference to the created server is retained, so that it can 104: * be retrieved at a later date using {@link #findMBeanServer}. 105: * Calling this method is equivalent to calling 106: * {@link createMBeanServer(String)} with a <code>null</code> value. 107: * 108: * @return a new {@link MBeanServer} instance. 109: * @throws SecurityException if a security manager exists and the 110: * caller's permissions don't imply {@link 111: * MBeanServerPermission(String)}("createMBeanServer") 112: * @throws JMRuntimeException if the property 113: * <code>javax.management.builder.initial</code> 114: * exists but names a class which either can not be 115: * instantiated or provides an implementation that returns 116: * <code>null</code> from either 117: * {@link MBeanServerBuilder#newMBeanServerDelegate()} 118: * or {@link MBeanServerBuilder#newMBeanServer()} 119: * @throws ClassCastException if the property 120: * <code>javax.management.builder.initial</code> 121: * exists but names a class which is not a subclass 122: * of {@link MBeanServerBuilder}. 123: * @see #createMBeanServer(String) 124: */ 125: public static MBeanServer createMBeanServer() 126: { 127: return createMBeanServer(null); 128: } 129: 130: /** 131: * Returns a server implementation using the default domain name 132: * given, or <code>"DefaultDomain"</code> if this is <code>null</code>. 133: * The default domain name is used when the domain name specified by 134: * the user is <code>null</code. A reference to the created server is 135: * retained, so that it can be retrieved at a later date using 136: * {@link #findMBeanServer}. 137: * 138: * @param domain the default domain name of the server. 139: * @return a new {@link MBeanServer} instance. 140: * @throws SecurityException if a security manager exists and the 141: * caller's permissions don't imply {@link 142: * MBeanServerPermission(String)}("createMBeanServer") 143: * @throws JMRuntimeException if the property 144: * <code>javax.management.builder.initial</code> 145: * exists but names a class which either can not be 146: * instantiated or provides an implementation that returns 147: * <code>null</code> from either 148: * {@link MBeanServerBuilder#newMBeanServerDelegate()} 149: * or {@link MBeanServerBuilder#newMBeanServer()} 150: * @throws ClassCastException if the property 151: * <code>javax.management.builder.initial</code> 152: * exists but names a class which is not a subclass 153: * of {@link MBeanServerBuilder}. 154: */ 155: public static MBeanServer createMBeanServer(String domain) 156: { 157: SecurityManager sm = System.getSecurityManager(); 158: if (sm != null) 159: sm.checkPermission(new MBeanServerPermission("createMBeanServer")); 160: MBeanServer server = createServer(domain); 161: try 162: { 163: ObjectName dn = new 164: ObjectName("JMImplementation:type=MBeanServerDelegate"); 165: servers.put(server.getAttribute(dn, "MBeanServerId"), server); 166: } 167: catch (MalformedObjectNameException e) 168: { 169: throw (Error) 170: (new InternalError("Malformed delegate bean name.").initCause(e)); 171: } 172: catch (MBeanException e) 173: { 174: throw (Error) 175: (new InternalError("Exception in getMBeanServerId().").initCause(e)); 176: } 177: catch (AttributeNotFoundException e) 178: { 179: throw (Error) 180: (new InternalError("Could not find MBeanServerId attribute.").initCause(e)); 181: } 182: catch (InstanceNotFoundException e) 183: { 184: throw (Error) 185: (new InternalError("Could not find the delegate bean.").initCause(e)); 186: } 187: catch (ReflectionException e) 188: { 189: throw (Error) 190: (new InternalError("Could not call getMBeanServerId().").initCause(e)); 191: } 192: return server; 193: } 194: 195: /** 196: * Returns the specified server, or, if <code>id</code> is <code>null</code>, 197: * a list of all registered servers. A registered server is one that 198: * was created using {@link #createMBeanServer()} or 199: * {@link #createMBeanServer(String)} and has not yet been released 200: * using {@link releaseMBeanServer(MBeanServer)}. 201: * 202: * @param id the id of the server to retrieve, or <code>null</code> 203: * to return all servers. 204: * @return a list of {@link MBeanServer}s. 205: * @throws SecurityException if a security manager exists and the 206: * caller's permissions don't imply {@link 207: * MBeanServerPermission(String)}("findMBeanServer") 208: */ 209: public static ArrayList<MBeanServer> findMBeanServer(String id) 210: { 211: SecurityManager sm = System.getSecurityManager(); 212: if (sm != null) 213: sm.checkPermission(new MBeanServerPermission("findMBeanServer")); 214: if (id == null) 215: return new ArrayList(servers.values()); 216: ArrayList<MBeanServer> list = new ArrayList<MBeanServer>(); 217: MBeanServer server = servers.get(id); 218: if (server != null) 219: list.add(servers.get(id)); 220: return list; 221: } 222: 223: /** 224: * Returns the class loader repository used by the specified server. 225: * This is equivalent to calling {@link MBeanServer#getClassLoaderRepository()} 226: * on the given server. 227: * 228: * @param server the server whose class loader repository should be 229: * retrieved. 230: * @throws NullPointerException if <code>server</code> is <code>null</code>. 231: * @throws SecurityException if a security manager exists and the 232: * caller's permissions don't imply {@link 233: * MBeanPermission(String,String,ObjectName,String) 234: * <code>MBeanPermission(null, null, null, 235: * "getClassLoaderRepository")</code> 236: */ 237: public static ClassLoaderRepository getClassLoaderRepository(MBeanServer server) 238: { 239: return server.getClassLoaderRepository(); 240: } 241: 242: /** 243: * Returns a server implementation using the default domain name 244: * of <code>"DefaultDomain"</code>. The default domain name is 245: * used when the domain name specified by the user is <code>null</code. 246: * No reference to the created server is retained, so the server is 247: * garbage collected when it is no longer used, but it can not be 248: * retrieved at a later date using {@link #findMBeanServer}. 249: * Calling this method is equivalent to calling 250: * {@link newMBeanServer(String)} with a <code>null</code> value. 251: * 252: * @return a new {@link MBeanServer} instance. 253: * @throws SecurityException if a security manager exists and the 254: * caller's permissions don't imply {@link 255: * MBeanServerPermission(String)}("newMBeanServer") 256: * @throws JMRuntimeException if the property 257: * <code>javax.management.builder.initial</code> 258: * exists but names a class which either can not be 259: * instantiated or provides an implementation that returns 260: * <code>null</code> from either 261: * {@link MBeanServerBuilder#newMBeanServerDelegate()} 262: * or {@link MBeanServerBuilder#newMBeanServer()} 263: * @throws ClassCastException if the property 264: * <code>javax.management.builder.initial</code> 265: * exists but names a class which is not a subclass 266: * of {@link MBeanServerBuilder}. 267: * @see #newMBeanServer(String) 268: */ 269: public static MBeanServer newMBeanServer() 270: { 271: return newMBeanServer(null); 272: } 273: 274: /** 275: * Returns a server implementation using the default domain name 276: * given, or <code>"DefaultDomain"</code> if this is <code>null</code>. 277: * The default domain name is used when the domain name specified by 278: * the user is <code>null</code. No reference to the created server is 279: * retained, so the server is garbage collected when it is no longer 280: * used, but it can not be retrieved at a later date using 281: * {@link #findMBeanServer}. 282: * 283: * @param domain the default domain name of the server. 284: * @return a new {@link MBeanServer} instance. 285: * @throws SecurityException if a security manager exists and the 286: * caller's permissions don't imply {@link 287: * MBeanServerPermission(String)}("newMBeanServer") 288: * @throws JMRuntimeException if the property 289: * <code>javax.management.builder.initial</code> 290: * exists but names a class which either can not be 291: * instantiated or provides an implementation that returns 292: * <code>null</code> from either 293: * {@link MBeanServerBuilder#newMBeanServerDelegate()} 294: * or {@link MBeanServerBuilder#newMBeanServer()} 295: * @throws ClassCastException if the property 296: * <code>javax.management.builder.initial</code> 297: * exists but names a class which is not a subclass 298: * of {@link MBeanServerBuilder}. 299: */ 300: public static MBeanServer newMBeanServer(String domain) 301: { 302: SecurityManager sm = System.getSecurityManager(); 303: if (sm != null) 304: sm.checkPermission(new MBeanServerPermission("newMBeanServer")); 305: return createServer(domain); 306: } 307: 308: /** 309: * Common method to create a server for the {@link #createMBeanServer(String)} 310: * and {@link #newMBeanServer(String)} methods above. 311: * 312: * @param domain the default domain name of the server. 313: * @throws JMRuntimeException if the property 314: * <code>javax.management.builder.initial</code> 315: * exists but names a class which either can not be 316: * instantiated or provides an implementation that returns 317: * <code>null</code> from either 318: * {@link MBeanServerBuilder#newMBeanServerDelegate()} 319: * or {@link MBeanServerBuilder#newMBeanServer()} 320: * @throws ClassCastException if the property 321: * <code>javax.management.builder.initial</code> 322: * exists but names a class which is not a subclass 323: * of {@link MBeanServerBuilder}. 324: */ 325: private static MBeanServer createServer(String domain) 326: { 327: if (domain == null) 328: domain = "DefaultDomain"; 329: String builderClass = 330: SystemProperties.getProperty("javax.management.builder.initial"); 331: if (builderClass == null) 332: { 333: if (builder == null || 334: builder.getClass() != MBeanServerBuilder.class) 335: builder = new MBeanServerBuilder(); 336: } 337: else if (!(builder != null && 338: builderClass.equals(builder.getClass().getName()))) 339: { 340: ClassLoader cl = Thread.currentThread().getContextClassLoader(); 341: if (cl == null) 342: cl = MBeanServerFactory.class.getClassLoader(); 343: try 344: { 345: Class bClass = Class.forName(builderClass, true, cl); 346: builder = (MBeanServerBuilder) bClass.newInstance(); 347: } 348: catch (ClassNotFoundException e) 349: { 350: throw (JMRuntimeException) (new JMRuntimeException("The builder class, " 351: + builderClass + 352: ", could not be found.")) 353: .initCause(e); 354: } 355: catch (InstantiationException e) 356: { 357: throw (JMRuntimeException) (new JMRuntimeException("The builder class, " 358: + builderClass + 359: ", could not be instantiated.")) 360: .initCause(e); 361: } 362: catch (IllegalAccessException e) 363: { 364: throw (JMRuntimeException) (new JMRuntimeException("The builder class, " 365: + builderClass + 366: ", could not be accessed.")) 367: .initCause(e); 368: } 369: } 370: MBeanServerDelegate delegate = builder.newMBeanServerDelegate(); 371: if (delegate == null) 372: throw new JMRuntimeException("A delegate could not be created."); 373: MBeanServer server = builder.newMBeanServer(domain, null, delegate); 374: if (server == null) 375: throw new JMRuntimeException("A server could not be created."); 376: return server; 377: } 378: 379: /** 380: * Removes the reference to the specified server, thus allowing it to 381: * be garbage collected. 382: * 383: * @param server the server to remove. 384: * @throws IllegalArgumentException if a reference to the server is not 385: * held (i.e. it wasn't created by 386: * {@link #createMBeanServer(String)} 387: * or this method has already been called 388: * on it. 389: * @throws SecurityException if a security manager exists and the 390: * caller's permissions don't imply {@link 391: * MBeanServerPermission(String)}("releaseMBeanServer") 392: */ 393: public static void releaseMBeanServer(MBeanServer server) 394: { 395: SecurityManager sm = System.getSecurityManager(); 396: if (sm != null) 397: sm.checkPermission(new MBeanServerPermission("releaseMBeanServer")); 398: Iterator<MBeanServer> i = servers.values().iterator(); 399: while (i.hasNext()) 400: { 401: MBeanServer s = i.next(); 402: if (server == s) 403: { 404: i.remove(); 405: return; 406: } 407: } 408: throw new IllegalArgumentException("The server given is not referenced."); 409: } 410: 411: 412: }
GNU Classpath (0.95) |