1/* 2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.management; 27 28import java.lang.System.Logger.Level; 29import com.sun.jmx.defaults.JmxProperties; 30import com.sun.jmx.defaults.ServiceName; 31import com.sun.jmx.mbeanserver.Util; 32 33/** 34 * Represents the MBean server from the management point of view. 35 * The MBeanServerDelegate MBean emits the MBeanServerNotifications when 36 * an MBean is registered/unregistered in the MBean server. 37 * 38 * @since 1.5 39 */ 40public class MBeanServerDelegate implements MBeanServerDelegateMBean, 41 NotificationEmitter { 42 43 /** The MBean server agent identification.*/ 44 private String mbeanServerId ; 45 46 /** The NotificationBroadcasterSupport object that sends the 47 notifications */ 48 private final NotificationBroadcasterSupport broadcaster; 49 50 private static long oldStamp = 0; 51 private final long stamp; 52 private long sequenceNumber = 1; 53 54 private static final MBeanNotificationInfo[] notifsInfo; 55 56 static { 57 final String[] types = { 58 MBeanServerNotification.UNREGISTRATION_NOTIFICATION, 59 MBeanServerNotification.REGISTRATION_NOTIFICATION 60 }; 61 notifsInfo = new MBeanNotificationInfo[1]; 62 notifsInfo[0] = 63 new MBeanNotificationInfo(types, 64 "javax.management.MBeanServerNotification", 65 "Notifications sent by the MBeanServerDelegate MBean"); 66 } 67 68 /** 69 * Create a MBeanServerDelegate object. 70 */ 71 public MBeanServerDelegate () { 72 stamp = getStamp(); 73 broadcaster = new NotificationBroadcasterSupport() ; 74 } 75 76 77 /** 78 * Returns the MBean server agent identity. 79 * 80 * @return the identity. 81 */ 82 public synchronized String getMBeanServerId() { 83 if (mbeanServerId == null) { 84 String localHost; 85 try { 86 localHost = java.net.InetAddress.getLocalHost().getHostName(); 87 } catch (java.net.UnknownHostException e) { 88 JmxProperties.MISC_LOGGER.log(Level.TRACE, 89 "Can't get local host name, " + 90 "using \"localhost\" instead. Cause is: "+e); 91 localHost = "localhost"; 92 } 93 mbeanServerId = localHost + "_" + stamp; 94 } 95 return mbeanServerId; 96 } 97 98 /** 99 * Returns the full name of the JMX specification implemented 100 * by this product. 101 * 102 * @return the specification name. 103 */ 104 public String getSpecificationName() { 105 return ServiceName.JMX_SPEC_NAME; 106 } 107 108 /** 109 * Returns the version of the JMX specification implemented 110 * by this product. 111 * 112 * @return the specification version. 113 */ 114 public String getSpecificationVersion() { 115 return ServiceName.JMX_SPEC_VERSION; 116 } 117 118 /** 119 * Returns the vendor of the JMX specification implemented 120 * by this product. 121 * 122 * @return the specification vendor. 123 */ 124 public String getSpecificationVendor() { 125 return ServiceName.JMX_SPEC_VENDOR; 126 } 127 128 /** 129 * Returns the JMX implementation name (the name of this product). 130 * 131 * @return the implementation name. 132 */ 133 public String getImplementationName() { 134 return ServiceName.JMX_IMPL_NAME; 135 } 136 137 /** 138 * Returns the JMX implementation version (the version of this product). 139 * 140 * @return the implementation version. 141 */ 142 public String getImplementationVersion() { 143 try { 144 return System.getProperty("java.runtime.version"); 145 } catch (SecurityException e) { 146 return ""; 147 } 148 } 149 150 /** 151 * Returns the JMX implementation vendor (the vendor of this product). 152 * 153 * @return the implementation vendor. 154 */ 155 public String getImplementationVendor() { 156 return ServiceName.JMX_IMPL_VENDOR; 157 } 158 159 // From NotificationEmitter extends NotificationBroacaster 160 // 161 public MBeanNotificationInfo[] getNotificationInfo() { 162 final int len = MBeanServerDelegate.notifsInfo.length; 163 final MBeanNotificationInfo[] infos = 164 new MBeanNotificationInfo[len]; 165 System.arraycopy(MBeanServerDelegate.notifsInfo,0,infos,0,len); 166 return infos; 167 } 168 169 // From NotificationEmitter extends NotificationBroacaster 170 // 171 public synchronized 172 void addNotificationListener(NotificationListener listener, 173 NotificationFilter filter, 174 Object handback) 175 throws IllegalArgumentException { 176 broadcaster.addNotificationListener(listener,filter,handback) ; 177 } 178 179 // From NotificationEmitter extends NotificationBroacaster 180 // 181 public synchronized 182 void removeNotificationListener(NotificationListener listener, 183 NotificationFilter filter, 184 Object handback) 185 throws ListenerNotFoundException { 186 broadcaster.removeNotificationListener(listener,filter,handback) ; 187 } 188 189 // From NotificationEmitter extends NotificationBroacaster 190 // 191 public synchronized 192 void removeNotificationListener(NotificationListener listener) 193 throws ListenerNotFoundException { 194 broadcaster.removeNotificationListener(listener) ; 195 } 196 197 /** 198 * Enables the MBean server to send a notification. 199 * If the passed <var>notification</var> has a sequence number lesser 200 * or equal to 0, then replace it with the delegate's own sequence 201 * number. 202 * @param notification The notification to send. 203 * 204 */ 205 public void sendNotification(Notification notification) { 206 if (notification.getSequenceNumber() < 1) { 207 synchronized (this) { 208 notification.setSequenceNumber(this.sequenceNumber++); 209 } 210 } 211 broadcaster.sendNotification(notification); 212 } 213 214 /** 215 * Defines the default ObjectName of the MBeanServerDelegate. 216 * 217 * @since 1.6 218 */ 219 public static final ObjectName DELEGATE_NAME = 220 Util.newObjectName("JMImplementation:type=MBeanServerDelegate"); 221 222 /* Return a timestamp that is monotonically increasing even if 223 System.currentTimeMillis() isn't (for example, if you call this 224 constructor more than once in the same millisecond, or if the 225 clock always returns the same value). This means that the ids 226 for a given JVM will always be distinact, though there is no 227 such guarantee for two different JVMs. */ 228 private static synchronized long getStamp() { 229 long s = System.currentTimeMillis(); 230 if (oldStamp >= s) { 231 s = oldStamp + 1; 232 } 233 oldStamp = s; 234 return s; 235 } 236} 237