/** * Creates a connector server at the given address. The resultant server is not started until its * {@link JMXConnectorServer#start() start} method is called. * * @param serviceURL the address of the new connector server. The actual address of the new * connector server, as returned by its {@link JMXConnectorServer#getAddress() getAddress} * method, will not necessarily be exactly the same. For example, it might include a port * number if the original address did not. * @param environment a set of attributes to control the new connector server's behavior. This * parameter can be null. Keys in this map must be Strings. The appropriate type of each * associated value depends on the attribute. The contents of <code>environment</code> are not * changed by this call. * @param mbeanServer the MBean server that this connector server is attached to. Null if this * connector server will be attached to an MBean server by being registered in it. * @return a <code>JMXConnectorServer</code> representing the new connector server. Each * successful call to this method produces a different object. * @exception NullPointerException if <code>serviceURL</code> is null. * @exception IOException if the connector server cannot be made because of a communication * problem. * @exception MalformedURLException if there is no provider for the protocol in <code>serviceURL * </code>. * @exception JMXProviderException if there is a provider for the protocol in <code>serviceURL * </code> but it cannot be used for some reason. */ public static JMXConnectorServer newJMXConnectorServer( JMXServiceURL serviceURL, Map<String, ?> environment, MBeanServer mbeanServer) throws IOException { if (environment == null) environment = new HashMap(); else { EnvHelp.checkAttributes(environment); environment = new HashMap(environment); } final Class targetInterface = JMXConnectorServerProvider.class; final ClassLoader loader = JMXConnectorFactory.resolveClassLoader(environment); final String protocol = serviceURL.getProtocol(); final String providerClassName = "ServerProvider"; JMXConnectorServerProvider provider = (JMXConnectorServerProvider) JMXConnectorFactory.getProvider( serviceURL, environment, providerClassName, targetInterface, loader); IOException exception = null; if (provider == null) { // Loader is null when context class loader is set to null // and no loader has been provided in map. // com.sun.jmx.remote.util.Service class extracted from j2se // provider search algorithm doesn't handle well null classloader. if (loader != null) { try { JMXConnectorServer connection = getConnectorServerAsService(loader, serviceURL, environment, mbeanServer); if (connection != null) return connection; } catch (JMXProviderException e) { throw e; } catch (IOException e) { exception = e; } } provider = (JMXConnectorServerProvider) JMXConnectorFactory.getProvider( protocol, PROTOCOL_PROVIDER_DEFAULT_PACKAGE, JMXConnectorFactory.class.getClassLoader(), providerClassName, targetInterface); } if (provider == null) { MalformedURLException e = new MalformedURLException("Unsupported protocol: " + protocol); if (exception == null) { throw e; } else { throw EnvHelp.initCause(e, exception); } } environment = Collections.unmodifiableMap(environment); return provider.newJMXConnectorServer(serviceURL, environment, mbeanServer); }
private static boolean test(String proto, MBeanServer mbs) throws Exception { System.out.println("Testing for proto " + proto); JMXConnectorServer cs; JMXServiceURL url = new JMXServiceURL(proto, null, 0); try { cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); } catch (MalformedURLException e) { System.out.println("System does not recognize URL: " + url + "; ignoring"); return true; } cs.start(); JMXServiceURL addr = cs.getAddress(); JMXServiceURL rmiurl = new JMXServiceURL("rmi", null, 0); JMXConnector client = JMXConnectorFactory.connect(addr); MBeanServerConnection mbsc = client.getMBeanServerConnection(); ObjectName on = new ObjectName("x:proto=" + proto + ",ok=yes"); mbsc.createMBean( RMIConnectorServer.class.getName(), on, mletName, new Object[] {rmiurl, null}, new String[] {JMXServiceURL.class.getName(), Map.class.getName()}); System.out.println("Successfully deserialized with " + proto); mbsc.unregisterMBean(on); client.close(); cs.stop(); return true; }
private static JMXConnectorServer getConnectorServerAsService( ClassLoader loader, JMXServiceURL url, Map map, MBeanServer mbs) throws IOException { Iterator providers = JMXConnectorFactory.getProviderIterator(JMXConnectorServerProvider.class, loader); JMXConnectorServerProvider provider = null; JMXConnectorServer connection = null; IOException exception = null; while (providers.hasNext()) { provider = (JMXConnectorServerProvider) providers.next(); try { connection = provider.newJMXConnectorServer(url, map, mbs); return connection; } catch (JMXProviderException e) { throw e; } catch (Exception e) { if (logger.traceOn()) logger.trace( "getConnectorAsService", "URL[" + url + "] Service provider exception: " + e); if (!(e instanceof MalformedURLException)) { if (exception == null) { if (exception instanceof IOException) { exception = (IOException) e; } else { exception = EnvHelp.initCause(new IOException(e.getMessage()), e); } } } continue; } } if (exception == null) return null; else throw exception; }
private static void test(String proto) throws Exception { System.out.println(">>> Test for protocol " + proto); JMXServiceURL u = null; JMXConnectorServer server = null; HashMap env = new HashMap(2); // server will close a client connection after 1 second env.put("jmx.remote.x.server.connection.timeout", "1000"); // disable the client ping env.put("jmx.remote.x.client.connection.check.period", "0"); try { u = new JMXServiceURL(proto, null, 0); server = JMXConnectorServerFactory.newJMXConnectorServer(u, env, mbs); } catch (MalformedURLException e) { System.out.println(">>> Skipping unsupported URL " + proto); } server.start(); JMXServiceURL addr = server.getAddress(); long st = 2000; MyListener myListener; // a cycle to make sure that we test the blocking problem. do { JMXConnector client = JMXConnectorFactory.connect(addr, env); MBeanServerConnection conn = client.getMBeanServerConnection(); myListener = new MyListener(conn); client.addConnectionNotificationListener(myListener, null, null); // wait the server to close the client connection Thread.sleep(st); // makes the listener to do a remote request via the connection // which should be closed by the server. conn.getDefaultDomain(); // allow the listner to have time to work Thread.sleep(100); // get a closed notif, should no block. client.close(); Thread.sleep(100); st += 2000; } while (!myListener.isDone()); server.stop(); }
/** Connect to a JMX agent of a given URL. */ private void connect(String urlPath) { try { JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); this.jmxc = JMXConnectorFactory.connect(url); this.server = jmxc.getMBeanServerConnection(); } catch (MalformedURLException e) { // should not reach here } catch (IOException e) { System.err.println("\nCommunication error: " + e.getMessage()); System.exit(1); } }
public static void main(String[] args) throws Exception { // TODO Auto-generated method stub if (args.length != 4) { System.err.println("Please provide process id zabbix-host zabbix-port host-guid"); System.exit(-1); } String processPid = args[0]; String zabbixHost = args[1]; String zabbixPort = args[2]; String hostGuid = args[3]; VirtualMachine vm = VirtualMachine.attach(processPid); String connectorAddr = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); if (connectorAddr == null) { String agent = vm.getSystemProperties().getProperty("java.home") + File.separator + "lib" + File.separator + "management-agent.jar"; vm.loadAgent(agent); connectorAddr = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); } JMXServiceURL serviceURL = new JMXServiceURL(connectorAddr); JMXConnector connector = JMXConnectorFactory.connect(serviceURL); MBeanServerConnection mbsc = connector.getMBeanServerConnection(); ObjectName objName = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME); Set<ObjectName> mbeans = mbsc.queryNames(objName, null); for (ObjectName name : mbeans) { ThreadMXBean threadBean; threadBean = ManagementFactory.newPlatformMXBeanProxy(mbsc, name.toString(), ThreadMXBean.class); long threadIds[] = threadBean.getAllThreadIds(); for (long threadId : threadIds) { ThreadInfo threadInfo = threadBean.getThreadInfo(threadId); System.out.println(threadInfo.getThreadName() + " / " + threadInfo.getThreadState()); } } }
public void use() { JMXConnector jmxc = null; try { JMXServiceURL serviceURL = new JMXServiceURL(this.serviceUrl); jmxc = JMXConnectorFactory.connect(serviceURL, null); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); ObjectName mbeanName = new ObjectName(MBeanName); StatusMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, StatusMBean.class, true); System.out.println(mbeanProxy.getName()); } catch (Exception e) { e.printStackTrace(); } finally { if (jmxc != null) { try { jmxc.close(); } catch (IOException e) { e.printStackTrace(); } } } }
/** * Lookup JMXConnectors in the LDAP directory. * * @param root A pointer to the LDAP directory, returned by {@link #getRootContext()}. * @param protocolType The protocol type of the JMX Connectors we want to retrieve. If * <var>protocolType</var> is null, then the jmxProtocolType attribute is ignored. Otherwise, * only those agents that have registered a matching jmxProtocolType attribute will be * returned. * @param name the AgentName of the JMXConnectors that should be returned. If <var>name</var> is * null, then the JMXConnectors for all agents are returned (null is an equivalent for a * wildcard). * @return The list of matching JMXConnectors retrieved from the LDAP directory. */ public static List lookup(DirContext root, String protocolType, String name) throws IOException, NamingException { final ArrayList list = new ArrayList(); // If protocolType is not null, include it in the filter. // String queryProtocol = (protocolType == null) ? "" : "(jmxProtocolType=" + protocolType + ")"; // Set the LDAPv3 query string // // Only those node that have the jmxConnector object class are // of interest to us, so we specify (objectClass=jmxConnector) // in the filter. // // We specify the jmxAgentName attribute in the filter so that the // query will return only those services for which the AgentName // attribute was registered. Since JSR 160 specifies that // the AgentName attribute is mandatory, this makes it possible // to filter out all the services that do not conform // to the spec. // If <name> is null, it is replaced by "*", so that all // services for which the AgentName attribute was specified match, // regardless of the value of that attribute. // Otherwise, only those services for which AgentName matches the // name or pattern specified by <name> will be returned. // // We also specify (jmxServiceURL=*) so that only those node // for which the jmxServiceURL attribute is present will be // returned. Thus, we filter out all those node corresponding // to agents that are not currently available. // String query = "(&" + "(objectClass=jmxConnector) " + "(jmxServiceURL=*) " + queryProtocol + "(jmxAgentName=" + ((name != null) ? name : "*") + "))"; System.out.println("Looking up JMX Agents with filter: " + query); SearchControls ctrls = new SearchControls(); // Want to get all jmxConnector objects, wherever they've been // registered. // ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Want to get only the jmxServiceUrl and jmxExpirationDate // (comment these lines and all attributes will be returned). // // ctrls.setReturningAttributes(new String[] { // "jmxServiceURL", // "jmxExpirationDate" // }); // Search... // final NamingEnumeration results = root.search("", query, ctrls); // Get the URL... // while (results.hasMore()) { // Get node... // final SearchResult r = (SearchResult) results.nextElement(); debug("Found node: " + r.getName()); // Get attributes // final Attributes attrs = r.getAttributes(); // Get jmxServiceURL attribute // final Attribute attr = attrs.get("jmxServiceURL"); if (attr == null) continue; // Get jmxExpirationDate // final Attribute exp = attrs.get("jmxExpirationDate"); // Check that URL has not expired. // if ((exp != null) && hasExpired((String) exp.get())) { System.out.print(r.getName() + ": "); System.out.println("URL expired since: " + exp.get()); continue; } // Get the URL string // final String urlStr = (String) attr.get(); if (urlStr.length() == 0) continue; debug("Found URL: " + urlStr); // Create a JMXServiceURL // final JMXServiceURL url = new JMXServiceURL(urlStr); // Create a JMXConnector // final JMXConnector conn = JMXConnectorFactory.newJMXConnector(url, null); // Add the connector to the result list // list.add(conn); if (debug) listAttributes(root, r.getName()); } return list; }
private void tryConnect(boolean requireRemoteSSL) throws IOException { if (jmxUrl == null && "localhost".equals(hostName) && port == 0) { // Monitor self this.jmxc = null; this.mbsc = ManagementFactory.getPlatformMBeanServer(); this.server = Snapshot.newSnapshot(mbsc); } else { // Monitor another process if (lvm != null) { if (!lvm.isManageable()) { lvm.startManagementAgent(); if (!lvm.isManageable()) { // FIXME: what to throw throw new IOException(lvm + "not manageable"); } } if (this.jmxUrl == null) { this.jmxUrl = new JMXServiceURL(lvm.connectorAddress()); } } Map<String, Object> env = new HashMap<String, Object>(); if (requireRemoteSSL) { env.put("jmx.remote.x.check.stub", "true"); } // Need to pass in credentials ? if (userName == null && password == null) { if (isVmConnector()) { // Check for SSL config on reconnection only if (stub == null) { checkSslConfig(); } this.jmxc = new RMIConnector(stub, null); jmxc.connect(env); } else { this.jmxc = JMXConnectorFactory.connect(jmxUrl, env); } } else { env.put(JMXConnector.CREDENTIALS, new String[] {userName, password}); if (isVmConnector()) { // Check for SSL config on reconnection only if (stub == null) { checkSslConfig(); } this.jmxc = new RMIConnector(stub, null); jmxc.connect(env); } else { this.jmxc = JMXConnectorFactory.connect(jmxUrl, env); } } this.mbsc = jmxc.getMBeanServerConnection(); this.server = Snapshot.newSnapshot(mbsc); } this.isDead = false; try { ObjectName on = new ObjectName(THREAD_MXBEAN_NAME); this.hasPlatformMXBeans = server.isRegistered(on); this.hasHotSpotDiagnosticMXBean = server.isRegistered(new ObjectName(HOTSPOT_DIAGNOSTIC_MXBEAN_NAME)); // check if it has 6.0 new APIs if (this.hasPlatformMXBeans) { MBeanOperationInfo[] mopis = server.getMBeanInfo(on).getOperations(); // look for findDeadlockedThreads operations; for (MBeanOperationInfo op : mopis) { if (op.getName().equals("findDeadlockedThreads")) { this.supportsLockUsage = true; break; } } on = new ObjectName(COMPILATION_MXBEAN_NAME); this.hasCompilationMXBean = server.isRegistered(on); } } catch (MalformedObjectNameException e) { // should not reach here throw new InternalError(e.getMessage()); } catch (IntrospectionException e) { InternalError ie = new InternalError(e.getMessage()); ie.initCause(e); throw ie; } catch (InstanceNotFoundException e) { InternalError ie = new InternalError(e.getMessage()); ie.initCause(e); throw ie; } catch (ReflectionException e) { InternalError ie = new InternalError(e.getMessage()); ie.initCause(e); throw ie; } if (hasPlatformMXBeans) { // WORKAROUND for bug 5056632 // Check if the access role is correct by getting a RuntimeMXBean getRuntimeMXBean(); } }
/** * Returns a client stub for this connector server. A client stub is a serializable object whose * {@link JMXConnector#connect(Map) connect} method can be used to make one new connection to this * connector server. * * <p>A given connector need not support the generation of client stubs. However, the connectors * specified by the JMX Remote API do (JMXMP Connector and RMI Connector). * * <p>The default implementation of this method uses {@link #getAddress} and {@link * JMXConnectorFactory} to generate the stub, with code equivalent to the following: * * <pre> * JMXServiceURL addr = {@link #getAddress() getAddress()}; * return {@link JMXConnectorFactory#newJMXConnector(JMXServiceURL, Map) * JMXConnectorFactory.newJMXConnector(addr, env)}; * </pre> * * <p>A connector server for which this is inappropriate must override this method so that it * either implements the appropriate logic or throws {@link UnsupportedOperationException}. * * @param env client connection parameters of the same sort that could be provided to {@link * JMXConnector#connect(Map) JMXConnector.connect(Map)}. Can be null, which is equivalent to * an empty map. * @return a client stub that can be used to make a new connection to this connector server. * @exception UnsupportedOperationException if this connector server does not support the * generation of client stubs. * @exception IllegalStateException if the JMXConnectorServer is not started (see {@link * JMXConnectorServerMBean#isActive()}). * @exception IOException if a communications problem means that a stub cannot be created. */ public JMXConnector toJMXConnector(Map<String, ?> env) throws IOException { if (!isActive()) throw new IllegalStateException("Connector is not active"); JMXServiceURL addr = getAddress(); return JMXConnectorFactory.newJMXConnector(addr, env); }
private static boolean test(String proto, MBeanServer mbs, ObjectName on) throws Exception { System.out.println("Testing for protocol " + proto); JMXConnectorServer cs; JMXServiceURL url = new JMXServiceURL(proto, null, 0); try { cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); } catch (MalformedURLException e) { System.out.println("System does not recognize URL: " + url + "; ignoring"); return true; } cs.start(); JMXServiceURL addr = cs.getAddress(); JMXConnector client = JMXConnectorFactory.connect(addr); MBeanServerConnection mbsc = client.getMBeanServerConnection(); Object getAttributeExotic = mbsc.getAttribute(on, "Exotic"); AttributeList getAttrs = mbsc.getAttributes(on, new String[] {"Exotic"}); AttributeList setAttrs = new AttributeList(); setAttrs.add(new Attribute("Exotic", new Exotic())); setAttrs = mbsc.setAttributes(on, setAttrs); Object invokeExotic = mbsc.invoke(on, "anExotic", new Object[] {}, new String[] {}); MBeanInfo exoticMBI = mbsc.getMBeanInfo(on); mbsc.setAttribute(on, new Attribute("Exception", Boolean.TRUE)); Exception getAttributeException, setAttributeException, invokeException; try { try { mbsc.getAttribute(on, "Exotic"); throw noException("getAttribute"); } catch (Exception e) { getAttributeException = e; } try { mbsc.setAttribute(on, new Attribute("Exotic", new Exotic())); throw noException("setAttribute"); } catch (Exception e) { setAttributeException = e; } try { mbsc.invoke(on, "anExotic", new Object[] {}, new String[] {}); throw noException("invoke"); } catch (Exception e) { invokeException = e; } } finally { mbsc.setAttribute(on, new Attribute("Exception", Boolean.FALSE)); } client.close(); cs.stop(); boolean ok = true; ok &= checkAttrs("getAttributes", getAttrs); ok &= checkAttrs("setAttributes", setAttrs); ok &= checkType("getAttribute", getAttributeExotic, Exotic.class); ok &= checkType("getAttributes", attrValue(getAttrs), Exotic.class); ok &= checkType("setAttributes", attrValue(setAttrs), Exotic.class); ok &= checkType("invoke", invokeExotic, Exotic.class); ok &= checkType("getMBeanInfo", exoticMBI, ExoticMBeanInfo.class); ok &= checkExceptionType("getAttribute", getAttributeException, ExoticException.class); ok &= checkExceptionType("setAttribute", setAttributeException, ExoticException.class); ok &= checkExceptionType("invoke", invokeException, ExoticException.class); if (ok) System.out.println("Test passes for protocol " + proto); return ok; }