📄 jmxwrapper.java
字号:
/*------------------------------------------------------------------------------Name: JmxWrapper.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE file------------------------------------------------------------------------------*/package org.xmlBlaster.util.admin.extern;import java.util.logging.Logger;import java.util.logging.Level;import org.xmlBlaster.util.StringPairTokenizer;import org.xmlBlaster.util.XmlBlasterException;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.context.ContextNode;import org.xmlBlaster.util.def.ErrorCode;import org.xmlBlaster.util.XmlBlasterSecurityManager;import com.sun.jdmk.comm.AuthInfo;import com.sun.jdmk.comm.HtmlAdaptorServer;import javax.management.Attribute;import javax.management.MalformedObjectNameException;import javax.management.ObjectName;import javax.management.ObjectInstance;import javax.management.QueryExp;import javax.management.MBeanServer;import javax.management.MBeanServerFactory;//since JDK 1.5 or with additional jmxremote.jar//import javax.management.remote.JMXServiceURL;//import javax.management.remote.JMXConnectorServerFactory;//import javax.management.remote.JMXConnectorServer;//import javax.management.remote.JMXPrincipal;import java.rmi.RemoteException;import java.rmi.Naming;import javax.security.auth.Subject;import java.util.ArrayList;import java.util.Map;import java.util.TreeMap;import java.util.HashMap;import java.util.Set;import java.util.HashSet;import java.util.Collections;import java.util.Iterator;// since JDK 1.5 (instead of javax.management.MBeanServerFactory from separate jmxri.jar from http://java.sun.com/products/JavaManagement/download.html)//import java.lang.management.ManagementFactory;/** * JmxWrapper wraps the MBeanServer instance. * Current supported adaptors are a HTTPAdaptor, the XmlBlasterAdaptor and the JDK1.5 jconsole adaptor. * <table> * <tr> * <td>1.</td> * <td>xmlBlaster/jmx/HtmlAdaptor</td> * <td>true: Start the adaptor for html-browser access</td> * </tr> * <tr> * <td>2.</td> * <td>xmlBlaster/jmx/XmlBlasterAdaptor</td> * <td>true</td> * </tr> * <tr> * <td>3a.</td> * <td>java -Dcom.sun.management.jmxremote ...</td> * <td>Start the JDK 1.5 jconsole adaptor by the java virtual machine</td> * </tr> * <tr> * <td>3b.</td> * <td>xmlBlaster/jmx/rmi</td> * <td>true: Start the JDK 1.5 jconsole adaptor by our own coding</td> * </tr> * </table> * <p /> * Note for 3b.:<br /> * A rmiregistry server is created automatically. If there is running already one, that is used.<br /> * You can specify another port or host to create/use a rmiregistry server: * <pre> * -xmlBlaster/jmx/rmiregistry/port Specify a port number where rmiregistry listens. * Default is port 1099 * -xmlBlaster/jmx/rmiregistry/hostname Specify a hostname where rmiregistry runs. * Default is the dns name of the running host. * </pre> * @see http://java.sun.com/developer/technicalArticles/J2SE/jmx.html * @see org.xmlBlaster.util.XmlBlasterSecurityManager * @see <a href="http://www.xmlBlaster.org/xmlBlaster/doc/requirements/admin.jmx.html">The admin.jmx requirement</a> */public class JmxWrapper{ private final Global glob; private static Logger log = Logger.getLogger(JmxWrapper.class.getName()); private final String ME; private MBeanServer mbeanServer; private HtmlAdaptorServer html; private int useJmx; /** * We hold an own map for mbeans registered to support renaming. * The key is the objectName.toString() and the value is the JmxMBeanHandle instance. */ private Map mbeanMap = new HashMap(); /** Export Global.getProperty() to JMX */ private JmxProperties jmxProperties; private JmxMBeanHandle jmxPropertiesHandle; private JmxLogLevel jmxLogLevel; private JmxMBeanHandle jmxLogLevelHandle; /** XmlBlaster RMI registry listen port is 1099, to access for bootstrapping */ public static final int DEFAULT_REGISTRY_PORT = 1099; private static JmxWrapper theJmxWrapper; private boolean createSecurityManager = true; /** * Singleton to avoid that different Global instances create more than one JmxWrapper. */ public static JmxWrapper getInstance(Global glob) throws XmlBlasterException { if (theJmxWrapper == null) { synchronized (JmxWrapper.class) { if (theJmxWrapper == null) { theJmxWrapper = new JmxWrapper(glob); } } } return theJmxWrapper; } /** * Constructs an initial JmxWrapper object. */ public JmxWrapper(Global glob) throws XmlBlasterException { this.glob = glob; this.ME = "JmxWrapper" + this.glob.getLogPrefixDashed(); /* If having an embedded jboss EJB3 plugin you have two options: 1. Switch off our JMX support java org.xmlBlaster.Main -xmlBlaster/jmx/support false 2. or initialize jboss directly in main() (you need to edit and recompile xmlBlaster) try { // JMX conflict with embedded jboss workaround ... EJB3StandaloneBootstrap.scanClasspath("myproject/build"); // this creates the conflict ... } catch (Exception e) { e.printStackTrace(); } and then start with: java org.xmlBlaster.Main -xmlBlaster/jmx/rmi true -xmlBlaster/jmx/rmi/user joe -xmlBlaster/jmx/rmi/password xyz jconsole service:jmx:rmi:///jndi/rmi://127.0.0.2:1099/jmxrmi */ // Embedded jboss seems to has its own and if this is initialized first our XmlBlasterSecurityManager.createSecurityManager(glob); call fails because of xmlBlaster.policy problems this.createSecurityManager = glob.getProperty().get("xmlBlaster/jmx/createSecurityManager", this.createSecurityManager); boolean supportJmx = glob.getProperty().get("xmlBlaster/jmx/support", true); if (!supportJmx) { // Embedded jboss can't handle it if we initialize JMS ourself log.warning("Any JMX support is switched off with 'xmlBlaster/jmx/support=false'"); return; } getMBeanServer(); // Initialize this.mbeanServer init(); if (useJmx > 0) { // Export Global.getProperty() to JMX this.jmxProperties = new JmxProperties(this.glob); ContextNode propNode = new ContextNode(ContextNode.SYSPROP_MARKER_TAG, null, this.glob.getContextNode()); this.jmxPropertiesHandle = registerMBean(propNode, jmxProperties); // "sysprop" this.jmxLogLevel = new JmxLogLevel(this.glob); ContextNode logNode = new ContextNode(ContextNode.LOGGING_MARKER_TAG, null, this.glob.getContextNode()); this.jmxLogLevelHandle = registerMBean(logNode, jmxLogLevel); // "logging" } if (useJmx > 0 && this.mbeanServer != null) { // display some statistics ... try { // javap com.sun.management.UnixOperatingSystem ObjectName name = new ObjectName("java.lang:type=OperatingSystem"); Object obj = this.mbeanServer.getAttribute(name, "TotalPhysicalMemorySize"); Global.totalPhysicalMemorySize = (obj instanceof Long) ? ((Long)obj).longValue() : 0; obj = this.mbeanServer.getAttribute(name, "CommittedVirtualMemorySize"); //long committed = (obj instanceof Long) ? ((Long)obj).longValue() : 0; obj = this.mbeanServer.getAttribute(name, "MaxFileDescriptorCount"); Global.maxFileDescriptorCount = (obj instanceof Long) ? ((Long)obj).longValue() : 0; name = new ObjectName("java.lang:type=Memory"); obj = this.mbeanServer.getAttribute(name, "HeapMemoryUsage"); if (obj instanceof javax.management.openmbean.CompositeDataSupport) { //java.lang.management.MemoryUsage.getMax() javax.management.openmbean.CompositeDataSupport comp = (javax.management.openmbean.CompositeDataSupport)obj; Long max = (Long)comp.get("max"); Global.heapMemoryUsage = max.longValue(); } log.info("Physical RAM size is " + Global.byteString(Global.totalPhysicalMemorySize) + "," + " this JVM may use max " + Global.byteString(Global.heapMemoryUsage) + " and max " + Global.maxFileDescriptorCount + " file descriptors"); } catch (Exception e) { } } } /** * Check if JMX is activated. * @return true if JMX is in use */ public boolean isActivated() { return (this.mbeanServer != null) && (this.useJmx != 0); } /** * Create the unique MBeanServer instance. */ public MBeanServer getMBeanServer() { if (this.mbeanServer == null) { synchronized (this) { if (this.mbeanServer == null) { try { Class clazz = java.lang.Class.forName("java.lang.management.ManagementFactory"); if (clazz != null) { // this.mbeanServer = ManagementFactory.getPlatformMBeanServer(); // new for JDK 1.5 java.lang.reflect.Method method = clazz.getMethod("getPlatformMBeanServer", new Class[0]); this.mbeanServer = (javax.management.MBeanServer)method.invoke(clazz, (Object[])new Class[0]); } } catch (Exception e) { log.fine("java.lang.management.ManagementFactory is not available for JMX monitoring: " + e.toString()); } if (this.mbeanServer == null) { // For JDK < 1.5 fall back to // JMX Remote API 1.0.1_03 Reference Implementation // JMX 1.2.1 Reference Implementation // Download from http://java.sun.com/products/JavaManagement/download.html String hostname = glob.getProperty().get("xmlBlaster/jmx/hostname", glob.getLocalIP()); this.mbeanServer = MBeanServerFactory.createMBeanServer(hostname); } } } } return this.mbeanServer; } /** * JMX property values may not contain a comma ','. * Here we replace commas with an underscore. * Even if we use quoted ObjectName values the comma is not allowed. * <br /> * Additionally we replace '/' as these would break the admin telnet commands * syntax, it is nice to be able to use those interchangeable * @param value The value to verify * @return The beautified value to be usable as a value for JMX properties */ public static String validateJmxValue(String value) { if (value == null) return value; while (true) { int index = value.indexOf(","); if (index >= 0) value = value.substring(0,index) + "_" + value.substring(index+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -