WebSphere Application Server Liberty Profile provides a new type of remote JMX connector: the REST connector. It supports all operations from the MBeanServerConnection interface, and its pure REST design over HTTPS allows for many future integration and expansion possibilities.

Configuring Liberty

The server-side configuration is extremely simple. All you need is the following server.xml:

<server>
     <featureManager>
         <feature>restConnector-1.0</feature>
     </featureManager>
     <quickStartSecurity userName="theUser" userPassword="thePassword"/>
     <keyStore id="defaultKeyStore" password="Liberty"/>
</server>

The above code is the smallest configuration that you need: it loads the server-side of the JMX REST Connector, sets the server keystore and creates a single administrator role user. If you wish to expand on some of the security attributes or reuse existing registries you can certainly do so. Please see the Information Center for more information.

Use JMX from a simple Java client

A Java client will need only two artifacts to make remote calls using Liberty’s REST JMX Connector:

  • a truststore for the secure remote connection to the server
  • the client-side jar, located inside Liberty’s installation folder <install_location>/clients/restConnector.jar

The Java client will place the restConnector.jar in its classpath, and use the following code to connect:

System.setProperty("javax.net.ssl.trustStore", <trustStore_location>);
System.setProperty("javax.net.ssl.trustStorePassword", <trustStore_password>);
Map<String, Object> environment = new HashMap<String, Object>();
environment.put("jmx.remote.protocol.provider.pkgs", "com.ibm.ws.jmx.connector.client");
environment.put(JMXConnector.CREDENTIALS, new String[] { "theUser", "thePassword" });
environment.put(ConnectorSettings.DISABLE_HOSTNAME_VERIFICATION, true); //optional setting
environment.put(ConnectorSettings.READ_TIMEOUT, 2 * 60 * 1000); //optional setting
JMXServiceURL url = new JMXServiceURL("REST", hostName, httpsPort, "/IBMJMXConnectorREST");
JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment);
MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();

The first two lines will setup your trustStore location and password. The environment map must contain the jmx.remote.protocol.provider.pkgs key, because that is used by the JMX framework to look for the client-side implementation. The JMXConnector.CREDENTIALS is also required because it specifies the credentials that the client will use when connecting to the server – notice that these are the credentials we specified in our server configuration.

The user can then override some of the default attributes of the connection by using the constants defined on com.ibm.websphere.jmx.connector.rest.ConnectorSettings interface (see <install_location>/dev/ibm-api/javadoc/com.ibm.websphere.appserver.api.restConnector-javadoc.zip for the interface documentation). In the sample above we could have also used the JMXServiceURL(String) constructor, passing in a string with the format:

service:jmx:rest://<host>:<httpsPort>/IBMJMXConnectorREST

That’s it! You can now set up notifications, create proxy MBeans, etc, all using a reliable and secure remote connection.

Use JMX from JConsole

To use the REST Connector with JConsole we need the same artifacts as we did in the simple Java client scenario, but we pass most of them as launch parameters. An example launch is:

jconsole
-J-Djava.class.path=%JAVA_HOME%libjconsole.jar;%JAVA_HOME%libtools.jar;<path_to_restConnector.jar>
-J-Djavax.net.ssl.trustStore=<trustStore_location>
-J-Djavax.net.ssl.trustStorePassword=<trustStore_password>
-J-Dcom.ibm.ws.jmx.connector.client.disableURLHostnameVerification=true

The first portion sets the classpath for JConsole, which includes the client-side jar of the rest connector. The next two options setup the trust store location/password, while the last option is an example of how we can pass extra settings defined in com.ibm.websphere.jmx.connector.rest.ConnectorSettings. Notice that in the simple Java client we used the ConnectorSettings keys directly into a Map, whereas in the JConsole scenario we must use the system property variant – the end result is exactly the same.

Once JConsole starts, you must pick the “Remote Process” radio button and provide 3 inputs:

  • the URL to connect, which is service:jmx:rest://:<host>:<httpsPort>/IBMJMXConnectorREST
  • the username, defined in server.xml
  • the password for that user, defined in server.xml

Press connect and there you go! You can now access all the available MBeans remotely through the underlying HTTPS connection.

10 comments on"Creating remote JMX connections in Liberty"

  1. Chris Robinson September 28, 2017

    I could use a bit more detail on using a java client. Could you provide perhaps screenshots as examples. It would really help following along.

    • Arthur De Magalhaes October 02, 2017

      Hey Chris – thanks for trying out the blog. I will be happy to help out. The pre-requisite for running the code in the Java client section is:
      (1) create a Java project (ie: in Eclipse, or favorite IDE)
      (2) add the restConnector.jar into your project’s classpath (this jar can be copied from your Liberty’s installation, inside the wlp/clients folder
      (3) if you are just doing development / test, you can also copy the server’s keystore file from the running target Liberty server (with the server.xml specified in the top of the blog), which is located at /resources/security/key.jks and use that as your Java client’s truststore (this is what you point to as the value of the “javax.net.ssl.trustStore” key in the hashmap, with the corresponding password, which is setup in your “keystore” element in server.xml”
      — please note that you would not do this approach for production: in that scenario you should use the appropriate Java keystore tools to extra a truststore for your client.
      (4) Copy the code in that section into your Java program/app, making sure you put the right values for the truststore location/password (from 3), and the host/port of the target Liberty server you’re connecting to.
      (5) Use your mbsc object to interact with the remote server (see this interface: https://docs.oracle.com/javase/8/docs/api/javax/management/MBeanServerConnection.html)

      Let me know if I can help clarify any of the steps.

      Thanks,
      Arthur

  2. This is excellent, helped me a lot.

    Please note that the “Use JMX from JConsole” is truncated though.

  3. Any ideas about this issue:

    File “/AppServer/clients/jython/restConnector.py”, line 10, in ?
    ImportError: no module named ibm

    • Arthur De Magalhaes June 16, 2016

      Hi Mark – did you add the restConnector.jar to your classpath?

  4. Hi,

    Am trying these steps, but connection to DSI server keeps failing with error –

    connection to tester@service:jmx:rest://localhost:9443/IBMJMXConnectorREST did not succeed. Would you like to try again?

    Thanks
    Raj

    • Arthur De Magalhaes April 11, 2016

      Hi Raj,

      I assume this is connecting via JConsole. If so, include the flag “-debug” in your java invocation to start JConsole and you should see any errors that are causing your connection to fail.

      Thanks,
      Arthur

  5. Ok, never mind about my previous question. I was reading the docs which says that the local connector is for client of the same host and same user id. But when I looked at other source, it is clear that it must be the same jdk, or use the Attach API, so we can use the MBeanServer

  6. Hi Arthur, if I want to use localConnector to connect to JMX, my URL connect should be service:jmx:local://localhost:someport/JBMJMXConnectorLocal ?? Thanks

Join The Discussion

Your email address will not be published. Required fields are marked *