Chapter 3. JMX Application Development

Table of Contents

3.1. JMX Client Application
3.2. Connecting MBean Servers
3.2.1. Using JNDI
3.2.2. Using JMX Remote API
3.3. Security Setting
3.4. MBean Object Names
3.5. Spring JMX Support

This chapter describes how to develop client applications for accessing MBean provided in JEUS.

3.1. JMX Client Application

This section describes how to run a JMX client application.

  1. The following two methods are used to connect to the JEUS MBean server.

  2. Access the MBean that provides the function that the user wants to use, and retrieve the property value, or execute a task.

    • To access an MBean, the user must know the ObjectName, which is a unique name that indicates the MBean. For the ObjectName format of the MBeans provided in JEUS, refer to"3.4. MBean Object Names".

    • For security reasons, there are cases where a privilege check is performed when the property value or operations provided by MBeans are executed. To use such MBeans, a user must be authenticated as a user with appropriate privilege, and then access. For information about security configurations when connecting to JMX, refer to "3.3. Security Setting".

  3. Receive and process the result of the executed task or the retrieved property value.

  4. When multiple tasks are executed, repeat steps two and three.

Note

In order to fully understand what is explained in this chapter, basic knowledge of JMX Remote API 1.0 and Java EE management specification is required. For details about JMX remote API, refer to J2EE JMX remote API 1.0 specification provided by Oracle, and the JMX remote API.

3.2. Connecting MBean Servers

This section explains how to connect to MBean servers.

3.2.1. Using JNDI

This section describes the JMX application which monitors JEUS by using JNDI.

Each server registers the javax.naming.Reference object, which contains information needed for connecting to JMX, in the JNDI.

The name used for registration is in the format, "mgmt/rmbs/adminServer". Users can connect to the MBean server by using the reference registered in the JNDI.

The following is an example of a client using JNDI.

package jmxclient;

import java.util.Set;
import java.util.Iterator;
import java.util.Hashtable;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.naming.Context;
import javax.naming.InitialContext;

/**
 * JMX Client which uses JNDI lookup.
 */
public class JMXClientUsingJndi {

    public static void main(String args[]) throws Exception {
        if(args.length < 4) {
            System.out.println("Required arguments: " 
                + "hostname username password target-name");
            return;
        }
        
        // Step 1. Setting Environments
        String hostname = args[0];
        String username = args[1];
        String password = args[2];

        // targetName could be server name,
        // for example, "adminServer", "server1"
        String targetName = args[3];
        
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "jeus.jndi.JEUSContextFactory");
        env.put(Context.PROVIDER_URL, hostname);
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);

        // Step 2. Getting MBeanServerConnection
        InitialContext ctx = new InitialContext(env);
        JMXConnector connector = (JMXConnector)ctx.lookup("mgmt/rmbs/" + targetName);
        MBeanServerConnection mbeanServer = connector.getMBeanServerConnection();

        // Step 3. Query
        ObjectName jeusScope = new ObjectName("JEUS:*");
        Set objectNames = mbeanServer.queryNames(jeusScope, null);

        // Step 4. Handling the Query Result
        for(Iterator i = objectNames.iterator(); i.hasNext();) {
            System.out.println("[MBean] " + i.next());
        }
    }
}

Write the above example and compile. After connecting to the JEUS server, the list of MBeans applicable to "JEUS:*" will be displayed. In the example, there are four arguments. The first is the server hostname, the second is the JEUS user name, the third is the password, and the last is the server name.

$ java -classpath .:${JEUS_HOME}/lib/client/jclient.jar jmxclient.JMXClientUsingJndi 127.0.0.1:9736 jeus jeus adminServer

[2016.05.28 15:20:24][2] [t-1] [NET-0002] Beginning to listen to NonBlockingChannelAcceptor: /127.0.0.1:9756.
[MBean] JEUS:j2eeType=JeusService,jeusType=ThreadPool,JMXManager=adminServer,
J2EEServer=adminServer,name=threadpool.System
[MBean] JEUS:j2eeType=JeusService,jeusType=JEUSMPConnector,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSDestinationResource,
JMXManager=adminServer,J2EEServer=adminServer,JMSResource=adminServer_jms,
name=ExamplesQueue
[MBean] JEUS:j2eeType=JeusService,jeusType=JeusLogService,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=ThreadPool_WEBC,JMXManager=adminServer,
WebEngine=adminServer_servlet,J2EEServer=adminServer,WebListener=http1,name=http1
[MBean] JEUS:j2eeType=JeusService,jeusType=SecurityDomain,JMXManager=adminServer,
J2EEDomain=domain1,SecurityService=SecurityService,name=SYSTEM_DOMAIN
[MBean] JEUS:j2eeType=JeusService,jeusType=DeploymentPlanManagementService,
JMXManager=adminServer,J2EEDomain=domain1,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSConnectionFactoryResource,
JMXManager=adminServer,J2EEServer=adminServer,JMSResource=adminServer_jms,
name=ConnectionFactory
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSEngine,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer_jms
[MBean] JEUS:j2eeType=JeusService,jeusType=ServerDeploymentService,
JMXManager=adminServer,J2EEServer=adminServer,name=adminServer
. . .

Note

1. jclient.jar is required to run the example program. In general, it is located under the JEUS_HOME/lib/client directory.

2. For more information about JNDI, refer to JEUS Server Guide. "Chapter 4. JNDI Naming Server". If a JMX application is executed in the servlet or the EJB, then the JNDI parameter does not need to be configured.

3.2.2. Using JMX Remote API

This section describes how to use the JMX application, which monitors JEUS by using the JMX Remote API.

Specify the target to be connected through the JMX Service URL. The URL for connecting to the JEUS MBean server is in the following formats.

  • service:jmx:jmxmp://0.0.0.0:9736/JeusMBeanServer

  • service:jmx:jmxmp://0.0.0.0:9736/JEUSMP_adminServer

The second URL will be different depending on the name of the server that will access the adminServer.

The following is an example of the client that uses the JMX Remote API.

package jmxclient;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;

/**
 * JMX Client which uses JMX Remote API
 */
public class JMXClientUsingJmxUrl {
	private static final String URL_PATH = "/JeusMBeanServer";

    public static void main(String args[]) throws Exception {
        if(args.length < 4) {
            System.out.println("Required arguments: " 
                + "hostname port username password");
            return;
        }
        
        // Step 1. Setting Environments
        String address = args[0];
        int port = Integer.parseInt(args[1]);
        String username = args[2];
        String password = args[3];
        
        Hashtable env = new Hashtable();
        env.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES, "jeus.management.remote.protocol");
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);        
        
        // Step 2. Getting MBeanServerConnection
        JMXServiceURL serviceURL = new JMXServiceURL("jmxmp", address, port, URL_PATH);
        JMXConnector connector = JMXConnectorFactory.connect(serviceURL, env);
        MBeanServerConnection mbeanServer = connector.getMBeanServerConnection();

        // Step 3. Query
        ObjectName jeusScope = new ObjectName("JEUS:*");
        Set objectNames = mbeanServer.queryNames(jeusScope, null);

        // Step 4. Handling the Query Result
        for(Iterator i = objectNames.iterator(); i.hasNext();) {
            System.out.println("[MBean] " + i.next());
        }
    }
}

Write the above example and compile it. After connecting to the JEUS server, the list of MBeans applicable to "JEUS:*" will be displayed. The arguments are the server address, port, user name, and password.

$ java -classpath .:${JEUS_HOME}/lib/client/jclient.jar jmxclient.JMXClientUsingJmxUrl 127.0.0.1 9736 jeus jeus

[2016.05.28 15:21:29][2] [t-1] [NET-0002] Beginning to listen to NonBlockingChannelAcceptor: /127.0.0.1:9756.
[MBean] JEUS:j2eeType=JeusService,jeusType=ThreadPool,JMXManager=adminServer,
J2EEServer=adminServer,name=threadpool.System
[MBean] JEUS:j2eeType=JeusService,jeusType=JEUSMPConnector,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSDestinationResource,
JMXManager=adminServer,J2EEServer=adminServer,JMSResource=adminServer_jms,
name=ExamplesQueue
[MBean] JEUS:j2eeType=JeusService,jeusType=JeusLogService,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=ThreadPool_WEBC,JMXManager=adminServer,
WebEngine=adminServer_servlet,J2EEServer=adminServer,WebListener=http1,name=http1
[MBean] JEUS:j2eeType=JeusService,jeusType=SecurityDomain,JMXManager=adminServer,
J2EEDomain=domain1,SecurityService=SecurityService,name=SYSTEM_DOMAIN
[MBean] JEUS:j2eeType=JeusService,jeusType=DeploymentPlanManagementService,
JMXManager=adminServer,J2EEDomain=domain1,name=adminServer
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSConnectionFactoryResource,
JMXManager=adminServer,J2EEServer=adminServer,JMSResource=adminServer_jms,
name=ConnectionFactory
[MBean] JEUS:j2eeType=JeusService,jeusType=JMSEngine,JMXManager=adminServer,
J2EEServer=adminServer,name=adminServer_jms
[MBean] JEUS:j2eeType=JeusService,jeusType=ServerDeploymentService,
JMXManager=adminServer,J2EEServer=adminServer,name=adminServer
. . .

Note

The jclient.jar file is required to run the example program. In general, the jclient.jar file is located under the JEUS_HOME/lib/client directory.

3.3. Security Setting

This section describes the security settings for the JEUS monitoring service. JEUS server performs security checks for a user who reads and performs operations on the properties of various MBeans registered with JEUS server using the JMX API. For more information about the permissions required to access each MBean, refer to JEUS API documents.

API documents can be found in the following location.

JEUS_HOME/docs/api

Note

API documents provide permission names as well as ObjectNamePattern, attributes, operation information, and others required for using MBeans.

JMX applications provide username and password information when connecting to the server to create the MBeanServerConnection object. In general, the following code is used to create MBeanServerConnection object. The code shows that the username and password is included in the environment configuration that is sent to the hash table.

. . .

    JMXServiceURL serviceURL = 
            new JMXServiceURL("service:jmx:jmxmp://127.0.0.1:9736/adminServer");

    Map<String, Object> env = new HashMap<String, Object>();
    env.put(Context.SECURITY_PRINCIPAL, id);
    env.put(Context.SECURITY_CREDENTIALS, password);
    env.put(Context.INITIAL_CONTEXT_FACTORY, "jeus.jndi.JEUSContextFactory");
    env.put("jmx.remote.x.request.timeout", "10");

    JMXConnector connector = JMXConnectorFactory.connect(serviceURL, env);
    MBeanServerConnection connection = connector.getMBeanServerConnection();

. . .

Note

The username, password, and permissions are specified through JEUS security service. For more information about JEUS security settings, refer to JEUS Security Guide. "2.5. Configuring the Security System User Information" and JEUS Security Guide. "2.6. Configuring Security System Policies".

3.4. MBean Object Names

An ObjectName is the default object name of an MBean object. In order to access the MBean server and interoperate with MBean, the name of the target MBean must be known. If the name is not fully known, then use the known parts to send a query to the MBean server, and then receive the result value to find the name.

An ObjectName for the MBean provided in JEUS has the following format.

<domain_name>: j2eeType=<j2eeType_value>, name=<name_value>,
    [<parent-j2eeType_value>], [jeusType = <jeusType_value>],
    [isTargetable = <isTargetable_value>],
    JMXManager = <JMXManager_value> [,*]

Alternative format is:

<domain_name>: *

An ObjectName must start with the <domain_name> and there is no defined sequence for each name-value pairs.

For example, both of the following ways will retrieve the object names of JEUSManager MBean.

JEUS:j2eeType=J2EEDomain,JMXManager=adminServer, *
JEUS:JMXManager=adminServer, j2eeType=J2EEDomain, *

The following describes each item:

  • <domain_name>

    • JEUS domain name. Set to JEUS.

  • j2eeType

    • The J2EE type of MBean, which is described in the J2EE management specifications.

    • Set with one of the following values:

      AppClientModuleEJBModuleEntityBean
      J2EEApplicationJ2EEDomainJ2EEServer
      JAXRResourceJCAConnectionFactoryJCAManagedConnectionFactory
      JCAResourceJDBCDataSourceJDBCDriver
      JDBCResourceJMSResourceJNDIResource
      JTAResourceJVMJavaMailResource
      JeusServiceMessageDrivenBeanResourceAdaptor
      ResourceAdapterModuleServletStatefulSessionBean
      StatelessSessionBeanURLResourceWebModule
  • name

    • The name of MBean. There is a unique name for each MBean object.

      For example, the name of the JVM on which the "adminServer" server runs is "adminServer."

  • parent-j2eeType

    • The J2EE type of the MBean's parent. There is a defined hierarchy for MBeans.

      For example, the parent-j2ee type of "JDBCDriver" is "JDBCDataSource."

  • jeusType

    • Mbeans' type defined in JEUS JMX. Only "JeusService" j2eeType can have several jeusTypes.

    • Set with one of the following values:

      EJBEngineJMSClientResourceJMSConnectionFactoryResource
      JMSDestinationResourceJMSDurableSubscriberResourceJMSEngine
      JMSPersistenceStoreManagerJMSServiceChannelSecurityDomain
      SecurityPolicySecurityServiceSecuritySubject
      SessionContainerSessionContainerCentralSessionContainerP2P
      ThreadPoolThreadPool_WEBCWebEngine
      WebListenerWebServices 

  • isTargetable

    • A boolean type that should be set to true for the MBean on which user AP (e.g. EJB, servlet, and JSP) is deployed and is running as isTargetable.

  • JMXManager

    • The name of the JMXManager that provides MBean service. In general, it is the name of the server that the JMXManager belongs to.

3.5. Spring JMX Support

JEUS 8 supports a library that enables the JEUS MBean server to integrate Spring JMX. The path to the library is as follows:

JEUS_HOME/lib/client/spring-support.jar

Note

Spring JMX operates in JEUS even without the JEUS library. Because using the library requires packaging it for deployment to the application and making additional configurations, it is recommended for use only to integrate the JEUS MBean server with Spring JMX.

Before using the JEUS Spring JMX support library, place the spring-support.jar file in the WEB-INF/lib directory, and set the configuration file for Spring as shown below so that the JEUS MBean server is available for use.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  ...

  <bean id="mBeanServer" class="com.tmax.jeus.spring.jmx.JeusMBeanServerFactoryBean"/>

  <!-- this bean must not be lazily initialized if the exporting is to happen -->
  <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="server" ref="mBeanServer"/>
    <property name="beans">
      <map>
        <entry key="bean:name=testBean1" value-ref="testBean"/>
      </map>
    </property>
  </bean>

  ...

</beans>

Note

For details about the Spring framework and Spring JMX, refer to http://spring.io/docs/reference.