Chapter 12. JMX Use Case: The JBoss Server

The JBoss server is a collaborative effort of a worldwide group of developers to create a J2EE application server in Open Source. The goal of the project is to commoditize the J2EE service stack and make it available free of charge for everyone to use. Started in 1999, JBoss is currently the leading Open Source effort to implement the enterprise Java APIs.

The JBoss application server was the first J2EE server to embrace the JMX API. In fact, the architecture of the JBoss application server has been built on top of the JMX infrastructure. This chapter will go briefly through the JBoss arhitecture for those parts where JMX is involved and explain the reasons and benefits of using JMX in the server core.

You can download the JBoss server for free from http://www.jboss.org. See Appendix A for more detailed download and installation instructions.

Microkernel Architecture

“The Microkernel architectural pattern applies to software systems that must be able to adapt to changing system requirements. It separates a minimal functional core from extended functionality and customer-specific parts. The microkernel also serves as a socket for plugging in these extensions and coordinating their collaboration.”

(Pattern-Oriented Software Architecture: A System of Patterns by Buschmann, Meunier, Rohnert, Sommerlad, and Stal)

The J2EE platform is a service based platform. The platform contains services for naming, messaging, transactions, persistence, security, logging, and so on. It also defines server-side component models, such as Enterprise Java Beans and Java servlets. Both servlets and the EJBs require their own containers for the components to be deployed on the server. The containers also need to be able to interact with all the other services in the platform.

Many application servers are built as monolithic applications, containing all the services of the J2EE platform at all times. Whether or not you are using the Java Message Service (JMS) or the Java Connector Architecture (JCA), or Java servlets, these service implementations are always present on the server.

JBoss takes a different approach to implementing the J2EE platform. Instead of building a monolithic server application, JBoss implements a microkernel architecture of MBean components, each of which implements different J2EE services or other server infrastructure components. The fact that the server itself is built on top of the JMX infrastructure makes both the applications deployed to the server easily manageable and also makes the server itself extremely flexible in how it can be configured.

The quotation at the beginning of this section very clearly defines in a couple of sentences the design goals of the JBoss server and the reasons why a microkernel approach to implement the server were chosen. The microkernel definition given by Buschmann et al. also closely matches the design of a JMX based management system. The J2EE platform is used for a variety of different purposes; from simple Web sites to handling critical business transactions. Being able to adapt to changing requirements, allowing for customer specific extensions and enabling high availability during maintenance are important factors when you choose your platform implementation.

Adapt to Changing System Requirements

As you have learned throughout the course of this book, the JMX agent level was designed to be adaptable to a range of runtime environments, from J2ME to J2EE. The core of the JMX agent level, the MBean server, is a rather simple and lightweight object. The MBean server decouples the MBeans from each other and allows components to be managed or switched at run-time.

The JBoss server can be configured and built with a set of MBean components, each implementing a different J2EE service. For example, several different servlet containers can be embedded to the JBoss server, from Tomcat to Jetty Web Server and servlet container. Similarly, it is possible to choose different JMS implementation or transaction manager for the server, if necessary. All of this enables you to more easily adapt the server to match your requirements. If one service implementation cannot provide the functionality required by your application, you are able to choose another service implementation for the server. You do not need to find a whole new J2EE platform implementation which, in practice, is often an expensive operation to go through—in some cases, it may also turn out to be technically very difficult to do.

Minimal Core

Both the JMX agent and the JBoss server have a very small core—the MBean server. The MBean server itself is merely an invocation bus containing a registry of the MBean components and their management interfaces. Registering agent service MBeans, such as the M-Let service, Relation Service, or connector MBeans can extend the core functionality.

Also the core of the server is able to adapt as requirements change. The JMX agent level allows run-time configuration to some extent through the agent service MBeans. Also the MBean server can be switched by choosing a different JMX implementation. For example, the JBoss server has been run on MBean server implementations provided by both Sun Microsystems and IBM Tivoli teams. A new JMX compliant agent core can be installed as a base to the JBoss platform if the runtime system so requires.

Extended Functionality and Customer-Specific Parts

By virtue of the JMX-based implementation, the JBoss server is extremely easy to extend with new functionality. Adding new services, or application specific components, to the server is a matter of creating a new MBean and registering it to the MBean server. For example, extending the server to report platform statistics and resource usage requires you to implement the code as an MBean, just as you would with any other MBean server. You can easily extend the server with parts that are specific to your installation only. The mechanism to do this is standardized by the JMX specification.

Collaboration Between Components

The MBean server allows queries that are to be executed to find different service implementations. For example, a JMS MBean or the EJB Container MBean can query the MBean server to find a Naming service that both components use. The notification mechanism also allows the components to broadcast information to other interested components in the system. The standard agent services (monitoring, timers, and relation service) allow additional collaboration between the MBean components via the notification mechanism.

The Server Spine

At the core of the JBoss server is the JMX MBean server. The MBean server acts as the spine of the JBoss server, allowing different J2EE service implementations to register to the server, as shown in Figure 12.1. Depending on your needs, the server can contain the full J2EE platform, parts of the J2EE platform, or nothing except the MBean server in the initial startup.

Different services in the JBoss platform are implemented as MBeans.

Figure 12.1. Different services in the JBoss platform are implemented as MBeans.

The default configuration of the JBoss server loads up all services—the servlet container, EJB containers, message service, naming service, connection pools, log service, and so on. However, you can quite easily configure the server to leave out the messaging service if you do not utilize it in any way. Or maybe the message service really is the only J2EE service your application requires; in this case, you can quite effortlessly leave out the EJB container. All that is required is for you to register one less MBean at startup.

JBoss utilizes the JMX M-Let service in its configuration and initial startup. As you explored in Chapter 7, “Standard Agent Services,” the M-Let service can be used to build applications that have very minimal bootstrap code and load the rest of their configuration and components from the network, as requested. This allows the centralized administration and maintenance of the application components.

The JBoss server can be used exactly this way. It is possible to start the server with only the JMX spine installed. Everything else, including the configuration services, EJB containers, messaging service, naming service, pools, and so on, can be loaded from a central configuration server. This enables an easy maintenance of a farm of servers, for example in an Application Service Provider (ASP) environment, where dozens of servers need to be both maintained and new ones installed. The configuration is stored in one location where each server will find it and install and configure the required components to the host machine (see Figure 12.2).

The administrator can easily control how each server is configured and which versions of the components are installed.

Figure 12.2. The administrator can easily control how each server is configured and which versions of the components are installed.

Configuration Service

One of the core components loaded the JBoss M-Let service is a Configuration Service implementation. The ConfigurationService MBean allows the JBoss bootstrap to download and configure the server using an XML based configuration file format. The XML file jboss.jcml includes a list of the downloadable MBean components and their initial configuration values. After the ConfigurationService MBean has been loaded and registered to the MBean server, it takes over the server startup sequence from the JMX M-Let service implementation. It loads the containers, databases, connection pools, and so on and configures them, as shown in Figure 12.3.

As part of the JBoss core application, the M-Let service loads a ConfigurationService MBean, which is then used to load individual J2EE service components to the server.

Figure 12.3. As part of the JBoss core application, the M-Let service loads a ConfigurationService MBean, which is then used to load individual J2EE service components to the server.

The M-Let file from the JBoss 2.4.1 installation is shown as an example in Listing 12.1. At the end of the file, you can see the ConfigurationService MBean being loaded, which then reads in the XML based configuration file in Listing 12.2. Both jboss.conf and jboss.jcml files can be found under the JBoss-2.4.1/conf/default directory.

Example 12.1. jboss.conf M-Let Text File

<!— ============================================================ —>
<!—                                                              —>
<!—  JBoss JMX Boot-strap Configuration                          —>
<!—                                                              —>
<!— ============================================================ —>

<MLET CODE = "org.jboss.logging.Logger"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
</MLET>

<!— The log4j based logging service  —>
<MLET CODE = "org.jboss.logging.Log4jService"
      ARCHIVE="jboss.jar,log4j.jar"
      CODEBASE="../../lib/ext/">
</MLET>

<!— location of log.properties —>
<MLET CODE = "org.jboss.util.ClassPathExtension"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
   <ARG TYPE="java.lang.String" VALUE="../../log/">
</MLET>

<!— Place the config directory in the classpath —>
<MLET CODE = "org.jboss.util.ClassPathExtension"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
   <ARG TYPE="java.lang.String" VALUE="./">
</MLET>

<MLET CODE = "org.jboss.util.Info"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
</MLET>

<MLET CODE = "org.jboss.util.ClassPathExtension"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
   <ARG TYPE="java.lang.String" VALUE="../../tmp/">
</MLET>

<MLET CODE = "org.jboss.util.ClassPathExtension"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
   <ARG TYPE="java.lang.String" VALUE="../../db/">
</MLET>

<MLET CODE = "org.jboss.configuration.ConfigurationService"
      ARCHIVE="jboss.jar,../xml.jar"
      CODEBASE="../../lib/ext/">
</MLET>

<MLET CODE = "org.jboss.util.Shutdown"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
</MLET>

<MLET CODE = "org.jboss.util.ServiceControl"
      ARCHIVE="jboss.jar"
      CODEBASE="../../lib/ext/">
</MLET>

Example 12.2. Partial MBean XML Configuration file (jboss.jcml)

<?xml version="1.0" encoding="UTF-8"?>
<!— This is where you can add and configure your MBeans
  ATTENTION: The order of the listing here is the same order as
    the MBeans are loaded. Therefore if a MBean depends on another
    MBean to be loaded and started it has to be listed after all
    the MBeans it depends on.
—>

<server>
  <!— ========================================================= —>
  <!— Classloading                                              —>
  <!— ========================================================= —>
  <mbean code="org.jboss.web.WebService"
         name="DefaultDomain:service=Webserver">
    <attribute name="Port">8083</attribute>
  </mbean>

  <!— ========================================================= —>
  <!— JNDI                                                      —>
  <!— ========================================================= —>
  <mbean code="org.jboss.naming.NamingService"
         name="DefaultDomain:service=Naming">
    <attribute name="Port">1099</attribute>
  </mbean>

  <mbean code="org.jboss.naming.JNDIView"
         name="DefaultDomain:service=JNDIView" />
  <!— ========================================================= —>
  <!— Transactions                                              —>
  <!— ========================================================= —>
  <mbean code="org.jboss.tm.TransactionManagerService"
         name="DefaultDomain:service=TransactionManager">
    <attribute name="TransactionTimeout">300</attribute>
  </mbean>


 <!— ========================================================== —>
 <!— Security                                                   —>
 <!— ========================================================== —>

 <!— JAAS security manager and realm mapping —>
 <mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
        name="Security:name=JaasSecurityManager">
   <attribute name="SecurityManagerClassName">
       org.jboss.security.plugins.JaasSecurityManager
   </attribute>
 </mbean>


  <!— ========================================================= —>
  <!— J2EE deployment                                           —>
  <!— ========================================================= —>

  <mbean code="org.jboss.ejb.ContainerFactory"
         name=":service=ContainerFactory">
    <attribute name="VerifyDeployments">true</attribute>
    <attribute name="ValidateDTDs">false</attribute>
    <attribute name="MetricsEnabled">false</attribute>
    <attribute name="VerifierVerbose">true</attribute>
    <attribute name="BeanCacheJMSMonitoringEnabled">false</attribute>
  </mbean>

  <!— ========================================================= —>
  <!— Auto deployment                                           —>
  <!— ========================================================= —>
  <mbean code="org.jboss.ejb.AutoDeployer"
         name="EJB:service=AutoDeployer">
    <attribute name="Deployers">
      J2EE:service=J2eeDeployer;
      JCA:service=RARDeployer
    </attribute>
    <attribute name="URLs">../deploy,../deploy/lib</attribute>
  </mbean>

  <!— ========================================================= —>
  <!— JMX adaptors                                              —>
  <!— ========================================================= —>

  <mbean code="org.jboss.jmx.server.JMXAdaptorService"
         name="Adaptor:name=RMI" />

  <mbean code="org.jboss.jmx.server.RMIConnectorService"
         name="Connector:name=RMI" />

  <mbean code="com.sun.jdmk.comm.HtmlAdaptorServer"
         name="Adaptor:name=html">
    <attribute name="MaxActiveClientCount">10</attribute>
    <attribute name="Parser" />
    <attribute name="Port">8082</attribute>
  </mbean>

  <!— ========================================================= —>
  <!— Mail Connection Factory                                   —>
  <!— ========================================================= —>
  <mbean code="org.jboss.mail.MailService" name=":service=Mail">
    <attribute name="JNDIName">Mail</attribute>
    <attribute name="ConfigurationFile">mail.properties</attribute>
    <attribute name="User">user_id</attribute>
    <attribute name="Password">password</attribute>
  </mbean>


  <!— ==================================================================== —>
  <!— Add your custom MBeans here                                          —>
  <!— ==================================================================== —>

</server>

Should you want to replace or remove one of the services, you can easily do so by editing the XML file. However, you can also do this at run-time through a Web interface, as explained in the next section.

Remote Management

By choosing to implement the JMX management architecture as part of the server core, the JBoss platform has had remote management capabilities virtually from the beginning. The server can be managed through HTTP adaptors, or custom management tools can be created using the standard JMX programming interface.

By default, the JBoss server enables automatic management of the server via an HTML adaptor. Both the default platform services and the customer-specific extensions to the server become manageable automatically through the MBean server. For example, an MBean extension to run a periodic batch reporting task on the server can easily be exposed to Web management and executed by the administrator from his or her Web browser. In fact, bringing new component implementations to the JBoss server and registering and managing them can easily be achieved through the basic HTTP adaptor interface. This means the administrator can customize the server and add new code and service implementations without ever having to leave his or her seat. A simple Web browser will do. In the next section, “Extending the JBoss Server,” you will first build a simple MBean component and then install it to a live server through the Web browser.

Extending the JBoss Server

To demonstrate the extensibility of the JMX based server, you will

  1. Write an MBean that starts a new thread in the server and periodically polls the Java runtime for the amount of used memory and thread count (see Listing 12.3).

  2. Expose a management attribute that allows you to set the polling interval (see Listing 12.4).

  3. Attach it to a running JBoss server instance.

Example 12.3. JBossMonitorMBean.java

package book.jmx.examples;

public interface JBossMonitorMBean {

  void setInterval(int interval);
  int  getInterval();

}

Example 12.4. JBossMonitor.java

package book.jmx.examples;

import javax.management.*;

public class JBossMonitor implements JBossMonitorMBean,
    MBeanRegistration, Runnable {

  Thread monitor = null;
  int interval = 10000;

  public ObjectName preRegister(MBeanServer server,
                                ObjectName name) throws Exception {

    if (name == null)
      return new ObjectName(":className=" + getClass().getName());

    else return name;
  }

  public void postRegister(Boolean registrationSuccessful) {
    monitor = new Thread(this);
    monitor.setDaemon(true);
    monitor.setName("My JBoss Thread");
    monitor.start();
  }

  public void preDeregister() throws Exception {
    monitor.interrupt();
  }

  public void postDeregister() { }

  public void setInterval(int interval) {
    this.interval = interval;
  }

  public int getInterval() {
    return interval;
  }

  public void run() {

    boolean running = true;

    while (running) {
      try {
          Thread.sleep(interval);
          System.out.println(getMem());
          System.out.println(getThreads());
                }

      catch (InterruptedException e) {
        running = false;
      }
    }
  }

  private String getMem() {
    return "Total Mem: " + Runtime.getRuntime().totalMemory() + "  " +
           "Free Mem:  " + Runtime.getRuntime().freeMemory();
  }

  private String getThreads() {
    ThreadGroup root = null;
    root = Thread.currentThread().getThreadGroup();

    while (root.getParent() != null)
      root = root.getParent();

    return "Thread Count: " + root.activeCount();
  }

}

The thread in Listing 12.4 prints the memory and thread values to the console when it is run.

To compile and package the MBean, execute the following commands:

C: Examples> javac -d . -classpath jmx-1_0_1-ri_bin jmx lib jmxri.jar JBossMonitor
JBossMonitor.java.java JBossMonitorMBean.java

C: Examples>  jar -cvf mon.jar book/jmx/examples/JBossMonitor*.class

Next, start the JBoss server by invoking the run.bat or run.sh command:

C: Examples> cd JBoss-2.41
C: Examples JBoss-2.4.1> cd bin
C: Examples JBoss-2.4.1 bin> run

When you have started the JBoss server, you can point your Web browser to http://localhost:8082. It should open the Web management view to JBoss components. Find the link to the M-Let MBean (see Figure 12.4).

Locate the JBoss server M-Let class loader.

Figure 12.4. Locate the JBoss server M-Let class loader.

Use the M-Let to add your new classes to the server. Execute the M-Let's addURL() operation to add the mon.jar to the class loader (see Figure 12.5).

Add your new compiled classes to the server at runtime via M-Let class loaders addURL() method.

Figure 12.5. Add your new compiled classes to the server at runtime via M-Let class loaders addURL() method.

To create the MBean on the MBean server, go back to the Agent View page at the beginning. On the top-right corner, you can see an Admin link (see Figure 12.6). Click it.

Locate the Admin link on the Agent View page to create a new MBean.

Figure 12.6. Locate the Admin link on the Agent View page to create a new MBean.

On the Admin page, you can create new MBeans and register them to the server. Fill in the requested fields:

  • Set domain to Example

  • Set keys to name=MyComponent

  • Set Java Class Name to book.jmx.examples.JBossMonitor

You can leave the Classloader field blank. Select the Create action and click Send Request (see Figure 12.7). The Web page should change to inform you that the create operation was successful. Now you can go back to the Agent View at the beginning, find the newly created MBean under the Example domain, and select it (see Figure 12.8). If you check the JBoss console, it should be printing out the information from the MBean.

Fill in the object name domain, keys, and the MBean classname before executing the Create action.

Figure 12.7. Fill in the object name domain, keys, and the MBean classname before executing the Create action.

The Web management view of the JBossMonitor MBean.

Figure 12.8. The Web management view of the JBossMonitor MBean.

[Service Control] Started 48 services
[Default] JBoss 2.4.1 Started in 0m:6s
[Default] Total Mem: 4112384  Free Mem:  1694272
[Default] Thread Count: 25
[Default] Total Mem: 4112384  Free Mem:  2133984
[Default] Thread Count: 25

You can change the interval setting to set the pace at which the output is being printed on the console. For a more sophisticated implementation, find the JMS implementation under the JBossMQ management domain. Change your MBean implementation to invoke createTopic() or createQueue() operations at startup. You can now change the MBean thread implementation to push the information to a JMS topic or a queue. The code to accomplish this is left as an exercise to the reader.

To add the MBean permanently as part of the server startup sequence, add the code in Listing 12.3 to the end of the jboss.jcml file .

Example 12.3. jboss.jcml

<!— ==================================================================== —>
<!— Add your custom MBeans here                                          —>
<!— ==================================================================== —>
<mbean code="book.jmx.examples.JBossMonitor"
       name="Example:name=MyExtension">
</mbean>

Integration and Development Process

The JBoss project has grown to become one of the most successful open-source Java projects. During its lifetime, several dozen developers have worked to create new features, maintain, and improve the existing services.

To support the distributed development of JBoss, a common infrastructure was needed. The developers of JBoss needed to be able to concentrate on their own area of interest without being disturbed by development efforts occurring on other parts of the server. This requirement to isolate the implementation effort is highlighted by the fact that developers are scattered across the globe and only have the electronic means of e-mail and mailing lists to communicate with each other.

A unified approach to registering and using the services was needed because many components need to communicate with other parts of the platform. The JMX API offered an easy-to-use and lightweight solution to the development problem. MBeans are easy to create and quick to implement. The MBean server interface is simple to understand and offers the basic “pluggability” for the platform components.

The JMX approach has allowed the JBoss platform to incorporate several other service implementations as part of the platform with little effort. The JBoss server can be easily configured to use different servlet containers—Tomcat 3 series, Tomcat 4 (Catalina), or Jetty Web Server and servlet container. The transaction manager can be switched between the JBossTX and Tyrex implementations; the Log4j logging framework has been embedded to the server as an MBean, as is CastorJDO, a Java Data Objects (JDO) implementation. All of the mentioned products are independently developed, without a specific focus on the JBoss server. However, by building an MBean component wrapper for each service implementation, the JBoss platform has been able to leverage the independent work of other projects. The JBoss platform has become an umbrella of independently developed J2EE service implementations with the help of the microkernel design and the JMX API. As the J2EE platform has grown bigger with new service specifications, the JBoss project has been able to adapt to the new requirements by integrating third-party implementations of those services. The users of the JBoss server today are able to mix and match these service implementations to build the exact kind of server platform their application requires.

Summary

The technical aspects of flexibility, extensibility, and manageability are the reasons the JBoss platform is built on top of the JMX infrastructure. The flexibility offered by the JMX— decoupled and non-typed invocation mechanism and the metadata based management interface—enables the integration of server components and automated management of the server through a Web interface.

The instrumentation level of the JMX specification defines a standardized mechanism to extend the server functionality. Anyone can extend the JBoss server by implementing custom code as an MBean. There is no need for server-specific “startup classes” in JBoss or server-specific timer or scheduler services. For scheduled batch jobs, the JMX Timer service can be used to notify application components at a given date and time. The startup classes can be implemented as MBeans and added either to the standard M-Let service file or the JBoss Configuration Service XML file. The JMX agent allows any JMX-compliant management application to be built to manage the JBoss server. Again, customer-specific tools can be built because all management operations are based on the standardized JMX API. Also, generic management tools, such as the HTTP adaptor, can be used for the rapid development of management applications.

The fact that the JBoss platform has been built as a collaborative project of hundreds of developers all around the world has required a standard component model to be used in building the platform. For JBoss, that component model has been the one defined by the JMX specification, and it has proven itself to be the right choice. Without the flexibility and ease-of-use of the MBean server and the MBean components, the JBoss project would not have been able to maintain the number of developers it enjoys today.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.56.29