1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/org/glassfish/external/amx/AMXGlassfish.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,318 @@ 1.4 +/* 1.5 + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 + 1.30 +package com.sun.org.glassfish.external.amx; 1.31 + 1.32 +import javax.management.ObjectName; 1.33 +import javax.management.MBeanServer; 1.34 +import javax.management.MBeanServerConnection; 1.35 + 1.36 +import java.io.IOException; 1.37 + 1.38 + 1.39 +/** 1.40 + * AMX behavior specific to Glassfish V3. 1.41 + */ 1.42 +public final class AMXGlassfish 1.43 +{ 1.44 + public static final String DEFAULT_JMX_DOMAIN = "amx"; 1.45 + 1.46 + /** Default domain support */ 1.47 + public static final AMXGlassfish DEFAULT = new AMXGlassfish(DEFAULT_JMX_DOMAIN); 1.48 + 1.49 + private final String mJMXDomain; 1.50 + private final ObjectName mDomainRoot; 1.51 + 1.52 + /** Anything other than {@link #DEFAULT} is not supported in Glassfish V3 */ 1.53 + public AMXGlassfish(final String jmxDomain) 1.54 + { 1.55 + mJMXDomain = jmxDomain; 1.56 + mDomainRoot = newObjectName("", "domain-root", null); 1.57 + } 1.58 + 1.59 + /** Return a version string, or null if not running in Glassfish */ 1.60 + public static String getGlassfishVersion() 1.61 + { 1.62 + // must all exist as a check to verify that it's Glassfish V3 1.63 + final String version = System.getProperty( "glassfish.version" ); 1.64 + return version; 1.65 + } 1.66 + 1.67 + 1.68 + /** JMX domain used by AMX MBeans. 1.69 + * <p> 1.70 + * All MBeans in this domain must be AMX-compliant, see http://tinyurl.com/nryoqp = 1.71 + https://glassfish.dev.java.net/nonav/v3/admin/planning/V3Changes/V3_AMX_SPI.html 1.72 + */ 1.73 + public String amxJMXDomain() 1.74 + { 1.75 + return mJMXDomain; 1.76 + } 1.77 + 1.78 + /** JMX domain used by AMX support MBeans. Private use only */ 1.79 + public String amxSupportDomain() 1.80 + { 1.81 + return amxJMXDomain() + "-support"; 1.82 + } 1.83 + 1.84 + /** name of the Domain Admin Server (DAS) as found in an ObjectName */ 1.85 + public String dasName() 1.86 + { 1.87 + return "server"; 1.88 + } 1.89 + 1.90 + /** name of the Domain Admin Server (DAS) <config> */ 1.91 + public String dasConfig() 1.92 + { 1.93 + return dasName() + "-config"; 1.94 + } 1.95 + 1.96 + /** return the ObjectName of the AMX DomainRoot MBean */ 1.97 + public ObjectName domainRoot() 1.98 + { 1.99 + return mDomainRoot; 1.100 + } 1.101 + 1.102 + /** ObjectName for top-level monitoring MBean (parent of those for each server) */ 1.103 + public ObjectName monitoringRoot() 1.104 + { 1.105 + return newObjectName("/", "mon", null); 1.106 + } 1.107 + 1.108 + /** ObjectName for top-level monitoring MBean for specified server */ 1.109 + public ObjectName serverMon(final String serverName) 1.110 + { 1.111 + return newObjectName("/mon", "server-mon", serverName); 1.112 + } 1.113 + 1.114 + /** ObjectName for top-level monitoring MBean for the DAS. */ 1.115 + public ObjectName serverMonForDAS() { 1.116 + return serverMon( "server" ) ; 1.117 + } 1.118 + 1.119 + /** Make a new AMX ObjectName with unchecked exception. 1.120 + * name must be null to create a singleton ObjectName. 1.121 + * Note that the arguments must not contain the characters 1.122 + * @param pp The parent part 1.123 + * @param type The ObjectName type 1.124 + * @param name The ObjectName name 1.125 + * @return The objectname with pp, type, and (optionally) name. 1.126 + */ 1.127 + public ObjectName newObjectName( 1.128 + final String pp, 1.129 + final String type, 1.130 + final String name) 1.131 + { 1.132 + String props = prop(AMX.PARENT_PATH_KEY, pp) + "," + prop(AMX.TYPE_KEY, type); 1.133 + if (name != null) { 1.134 + props = props + "," + prop(AMX.NAME_KEY, name); 1.135 + } 1.136 + 1.137 + return newObjectName( props); 1.138 + } 1.139 + 1.140 + /** Make a new ObjectName for AMX domain with unchecked exception */ 1.141 + public ObjectName newObjectName(final String s) 1.142 + { 1.143 + String name = s; 1.144 + if ( ! name.startsWith( amxJMXDomain() ) ) { 1.145 + name = amxJMXDomain() + ":" + name; 1.146 + } 1.147 + 1.148 + return AMXUtil.newObjectName( name ); 1.149 + } 1.150 + 1.151 + private static String prop(final String key, final String value) 1.152 + { 1.153 + return key + "=" + value; 1.154 + } 1.155 + 1.156 + /** 1.157 + ObjectName for {@link BootAMXMBean} 1.158 + */ 1.159 + public ObjectName getBootAMXMBeanObjectName() 1.160 + { 1.161 + return AMXUtil.newObjectName( amxSupportDomain() + ":type=boot-amx" ); 1.162 + } 1.163 + 1.164 + /** 1.165 + Invoke the bootAMX() method on {@link BootAMXMBean}. Upon return, 1.166 + AMX continues to load. 1.167 + A cilent should call {@link invokeWaitAMXReady} prior to use. 1.168 + */ 1.169 + public void invokeBootAMX(final MBeanServerConnection conn) 1.170 + { 1.171 + // start AMX and wait for it to be ready 1.172 + try 1.173 + { 1.174 + conn.invoke( getBootAMXMBeanObjectName(), BootAMXMBean.BOOT_AMX_OPERATION_NAME, null, null); 1.175 + } 1.176 + catch (final Exception e) 1.177 + { 1.178 + e.printStackTrace(); 1.179 + throw new RuntimeException(e); 1.180 + } 1.181 + } 1.182 + 1.183 + /** 1.184 + Invoke the waitAMXReady() method on the DomainRoot MBean, which must already be loaded. 1.185 + */ 1.186 + private static void invokeWaitAMXReady(final MBeanServerConnection conn, final ObjectName objectName) 1.187 + { 1.188 + try 1.189 + { 1.190 + conn.invoke( objectName, "waitAMXReady", null, null ); 1.191 + } 1.192 + catch( final Exception e ) 1.193 + { 1.194 + throw new RuntimeException(e); 1.195 + } 1.196 + } 1.197 + 1.198 + /** 1.199 + Listen for the registration of AMX DomainRoot 1.200 + Listening starts automatically. 1.201 + */ 1.202 + public <T extends MBeanListener.Callback> MBeanListener<T> listenForDomainRoot( 1.203 + final MBeanServerConnection server, 1.204 + final T callback) 1.205 + { 1.206 + final MBeanListener<T> listener = new MBeanListener<T>( server, domainRoot(), callback); 1.207 + listener.startListening(); 1.208 + return listener; 1.209 + } 1.210 + 1.211 + private static final class WaitForDomainRootListenerCallback extends MBeanListener.CallbackImpl { 1.212 + private final MBeanServerConnection mConn; 1.213 + 1.214 + public WaitForDomainRootListenerCallback( final MBeanServerConnection conn ) { 1.215 + mConn = conn; 1.216 + } 1.217 + 1.218 + @Override 1.219 + public void mbeanRegistered(final ObjectName objectName, final MBeanListener listener) { 1.220 + super.mbeanRegistered(objectName,listener); 1.221 + invokeWaitAMXReady(mConn, objectName); 1.222 + mLatch.countDown(); 1.223 + } 1.224 + } 1.225 + 1.226 + /** 1.227 + Wait until AMX has loaded and is ready for use. 1.228 + <p> 1.229 + This will <em>not</em> cause AMX to load; it will block forever until AMX is ready. In other words, 1.230 + don't call this method unless it's a convenient thread that can wait forever. 1.231 + */ 1.232 + public ObjectName waitAMXReady( final MBeanServerConnection server) 1.233 + { 1.234 + final WaitForDomainRootListenerCallback callback = new WaitForDomainRootListenerCallback(server); 1.235 + listenForDomainRoot( server, callback ); 1.236 + callback.await(); 1.237 + return callback.getRegistered(); 1.238 + } 1.239 + 1.240 + /** 1.241 + Listen for the registration of the {@link BootAMXMBean}. 1.242 + Listening starts automatically. See {@link AMXBooter#BootAMXCallback}. 1.243 + */ 1.244 + public <T extends MBeanListener.Callback> MBeanListener<T> listenForBootAMX( 1.245 + final MBeanServerConnection server, 1.246 + final T callback) 1.247 + { 1.248 + final MBeanListener<T> listener = new MBeanListener<T>( server, getBootAMXMBeanObjectName(), callback); 1.249 + listener.startListening(); 1.250 + return listener; 1.251 + } 1.252 + 1.253 + /** 1.254 + Callback for {@link MBeanListener} that waits for the BootAMXMBean to appear; 1.255 + it always will load early in server startup. Once it has loaded, AMX can be booted 1.256 + via {@link #bootAMX}. A client should normally just call {@link #bootAMX}, but 1.257 + this callback may be suclassed if desired, and used as a trigger to 1.258 + boot AMX and then take other dependent actions. 1.259 + */ 1.260 + public static class BootAMXCallback extends MBeanListener.CallbackImpl 1.261 + { 1.262 + private final MBeanServerConnection mConn; 1.263 + public BootAMXCallback(final MBeanServerConnection conn) 1.264 + { 1.265 + mConn = conn; 1.266 + } 1.267 + 1.268 + @Override 1.269 + public void mbeanRegistered(final ObjectName objectName, final MBeanListener listener) 1.270 + { 1.271 + super.mbeanRegistered(objectName, listener); 1.272 + mLatch.countDown(); 1.273 + } 1.274 + } 1.275 + 1.276 + /** 1.277 + Ensure that AMX is loaded and ready to use. This method returns only when all 1.278 + AMX subsystems have been loaded. 1.279 + It can be called more than once without ill effect, subsequent calls are ignored. 1.280 + @param conn connection to the MBeanServer 1.281 + @return the ObjectName of the domain-root MBean 1.282 + */ 1.283 + public ObjectName bootAMX(final MBeanServerConnection conn) 1.284 + throws IOException 1.285 + { 1.286 + final ObjectName domainRoot = domainRoot(); 1.287 + 1.288 + if ( !conn.isRegistered( domainRoot ) ) 1.289 + { 1.290 + // wait for the BootAMXMBean to be available (loads at startup) 1.291 + final BootAMXCallback callback = new BootAMXCallback(conn); 1.292 + listenForBootAMX(conn, callback); 1.293 + callback.await(); // block until the MBean appears 1.294 + 1.295 + invokeBootAMX(conn); 1.296 + 1.297 + final WaitForDomainRootListenerCallback drCallback = new WaitForDomainRootListenerCallback(conn); 1.298 + listenForDomainRoot(conn, drCallback); 1.299 + drCallback.await(); 1.300 + 1.301 + invokeWaitAMXReady(conn, domainRoot); 1.302 + } 1.303 + else 1.304 + { 1.305 + invokeWaitAMXReady(conn, domainRoot ); 1.306 + } 1.307 + return domainRoot; 1.308 + } 1.309 + 1.310 + public ObjectName bootAMX(final MBeanServer server) 1.311 + { 1.312 + try 1.313 + { 1.314 + return bootAMX( (MBeanServerConnection)server); 1.315 + } 1.316 + catch( final IOException e ) 1.317 + { 1.318 + throw new RuntimeException(e); 1.319 + } 1.320 + } 1.321 +}