How to Access MBeanServerConnection from remote JMX Client in JBoss EAP 6.x
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 6.x
Issue
- The JMX access seems to have changed in JBoss EAP 6, So how can we access the
javax.management.MBeanServerConnectionin order to query JBoss EAP6. - Is there some function that can be called while JBoss EAP shutdown?
- How is
JMX-remotingconfigured in JBoss EAP 6.1? - How can we make visible any MBean registered at the JBoss EAP 6.2 and how to setup JBoss for accessing the JBoss MBeans remotely?
- We have several custom mbeans that we are registering at JVM startup using basic JMX APIs. Here is sample code on how we registered:
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
String objectName = packageName + ":type=" + className;
ObjectName mbeanName = new ObjectName(objectName);
server.registerMBean(mbean, mbeanName);
- From within the JVM, I can connect to the Platform MBean Server and get information about my custom MBeans but if I try to use the remoting API from a different server I can only see the JBoss MBeans. Remoting code example:
Map feature=new HashMap();
String[] data=new String[]{"id","pwd"};
feature.put(JMXConnector.CREDENTIALS, data);
String url = "service:jmx:remoting-jmx://{host}:{port}";
JMXServiceURL jurl = new JMXServiceURL(url);
JMXConnector connector = JMXConnectorFactory.connect(jurl, feature);
- I am assuming that I am connecting to the domain controller MBean Server and my custom MBeans are registered in the JVM MBean Server. So Is it even possible to connect to custom standard mbeans in domain mode?
Resolution
Note Make sure remoting-jmx classes are in your classpath via jboss-client.jar for a standalone application or for an application running in JBoss EAP 6.x it should have a dependency on org.jboss.remoting-jmx as described in: protocol remoting-jmx
Note: If you are not using JBoss EAP 6 but actually using JBoss EAP 7, see another knowledge article How to access MBeanServerConnection from remote JMX Client in JBoss EAP 7 for details.
- The following kind of JMX Code can be used in order to access the JBoss EAP 6 MBeans :
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class JMXExample {
public static void main(String[] args) throws Exception {
String host = "localhost";
int port = 9999; // management-native port
String urlString ="service:jmx:remoting-jmx://" + host + ":" + port;
System.out.println("\n\n\t**** urlString: "+urlString);;
JMXServiceURL serviceURL = new JMXServiceURL(urlString);
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL, null);
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
//Invoke on the JBoss AS MBean server
int count = connection.getMBeanCount();
System.out.println(count);
jmxConnector.close();
}
}
- The above code only work with JBoss running locally, If JBoss run remotely, the authentication credentials should be added. Note that the user and password are created via
add-user.shwithManagementRealm in standalone mode andApplicationRealm in domain mode (In Windows, useadd-user.batinstead). In this condition, the code snippets like:
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class JMXExample {
public static void main(String[] args) throws Exception {
String host = "remote-host";
int port = 9999; // management-native port
String urlString ="service:jmx:remoting-jmx://" + host + ":" + port;
System.out.println("\n\n\t**** urlString: "+urlString);;
JMXServiceURL serviceURL = new JMXServiceURL(urlString);
Map map = new HashMap();
String[] credentials = new String[] { "user", "password" };
map.put("jmx.remote.credentials", credentials);
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL, map);
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
//Invoke on the JBoss AS MBean server
int count = connection.getMBeanCount();
System.out.println(count);
jmxConnector.close();
}
}
-
To compile and run the above sample program, make sure that JAR
$JBOSS_HOME/bin/client/jboss-client.jarexists on the JMX client's CLASSPATH. -
In domain mode, user need to connect to the individual JBoss instances using the Remoting Port (which defaults to 4447) in order to get the MBean details available on the individual JBoss instances using following url:
service:jmx:remoting-jmx://ip:4447 -
If user want to connect to the
JMX MBeanServerusing Remoting then use remoting connector under jmx subsystem, do the following chages in thedomain.xml.NOTE: if your server is using
haprofile then make changes inhaprofile and same for the other servers.<subsystem xmlns="urn:jboss:domain:jmx:1.1"> <remoting-connector use-management-endpoint="false"/> </subsystem>Here, by default the property
use-management-endpoint=trueis true. If the value ofuse-management-endpointistruethen this connector will use the management endpoint.
By adding the the propertyuse-management-endpoint=falsein on respective JBoss Profile insidedomain.xml, user can access the MBeans via Remoting port 4447 rather than (native management port 9999).
This knowledge article is for remote JMX Client. If you want to connect to JBoss EAP instance itself from a deployed application on the JBoss EAP instance, you can simply obtains javax.management.MBeanServer from ManagementFactory.getPlatformMBeanServer() without using the above API. See also this knowledge article.
Diagnostic Steps
-
It's possible to encounter the following error when trying to connect to the remote host:
3:52:17 PM org.xnio.Xnio <clinit> INFO: XNIO Version 3.0.4.GA-redhat-1 3:52:17 PM org.xnio.nio.NioXnio <clinit> INFO: XNIO NIO Implementation Version 3.0.4.GA-redhat-1 3:52:17 PM org.jboss.remoting3.EndpointImpl <clinit> INFO: JBoss Remoting version 3.2.8.GA-redhat-1 Exception in thread "main" java.lang.RuntimeException: Operation failed with status WAITING at org.jboss.remotingjmx.RemotingConnector.internalConnect(RemotingConnector.java:168) at org.jboss.remotingjmx.RemotingConnector.connect(RemotingConnector.java:94) at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248) at org.jboss.example.jmx.client.JMXClient.main(JMXClient.java:31) -
This error can be corrected by insuring that the client has proper name (DNS) resolution for the remote host. Otherwise, the client will timeout and disconnect with this stacktrace after 5 seconds. You may also see a corresponding log entry in the JBoss server.log file, on the remote host, that is similar to this:
15:52:22,968 ERROR [org.jboss.remoting.remote.connection] (Remoting "remote-host:MANAGEMENT" read-1) JBREM000200: Remote connection failed: java.io.IOException: Connection reset by peer
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.