Resin 4 Application Server JMX Tutorial

From Resin 4.0 Wiki

Revision as of 00:00, 15 June 2012 by Rick (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

JMX/Administration Tutorials

Simple JMX-managed Resource

Resources can be JMX managed by exposing a management interface and registering as an MBean.

Files in this tutorial

File Description
WEB-INF/web.xml Configures the JMX-managed bean
WEB-INF/classes/example/Basic.java The resource bean implementation.
WEB-INF/classes/example/BasicMBean.java The management interface for the bean.
index.jsp Using the managed bean.


JMX Resource

Any resource in Resin can be managed by JMX by implementing an MBean interface and by specifying an MBean name. The interface exposes the resource's methods to be managed.

The Basic resource

The Basic bean is the example resource implementation. It exposes its managed interface by implementing a BasicMBean interface. The xxxMBean naming convention lets JMX determine which interface to use for management. The MBean interface will expose the Data attribute to JMX.

Basic.java

package example;

public class Basic implements BasicMBean {
  private String _data = "default";

  public void setData(String data)
  {
    _data = data;
  }

  public String getData()
  {
    return _data;
  }
}

BasicMBean is the bean's management interface. It exposes a single attribute, Data, as a getter/setter pair. The name of the interface is important. Since the resource is named Basic, the MBean interface will be named BasicMBean.

BasicMBean.java

package example;

public interface BasicMBean {
  public void setData(String data);

  public String getData();
}


MBean names

MBeans are stored in the MBean server using an ObjectName as its key. Essentially, the MBean server stores the managed beans in a map using the mbean name as a key.

The mbean name consists of a set of <name,value> properties and a "domain" used like a namespace. The properties allow for querying related mbeans. For example, you could request for all mbeans with "J2EEType=Servlet", which would return all the managed servlets.

The example uses the name "example:name=basic". "example" is the domain and the bean's single property is "name" with a value of "basic". By convention, an mbean would normally also have a "type" property, but this example is using a name as simple as possible.


web.xml configuration

The web.xml (or resin.conf) configures the resource with the <resource> tag just as with [doc|ioc-bean.xtp other resources]. The resources is registered as an MBean by specifying an mbean-name.

web.xml

<web-app xmlns="http://caucho.com/ns/resin">
  <resource mbean-name="example:name=basic" type="example.Basic">
    <init>
      <data>An Example Resource</data>
    </init>
  </resource>
</web-app>
tagdescription
resourcedefines the resource
mbean-namethe MBean name of the resource
typethe class name of the resource bean
initAny bean-style configuration goes here
dataThe example bean's setData parameter.


Using the resource proxy

Resin's JMX implementation provides a proxy to managed object using the interface for an API. You can, of course, use the standard JMX interface, the proxy interface is much easier to use.

index.jsp

<%@ page import='com.caucho.jmx.Jmx, example.BasicMBean' %>
<%
BasicMBean basic = (BasicMBean) Jmx.find("example:name=basic");

out.println("data: " + basic.getData());
%>

results

data: An example resource


Compatibility

The resource's code is completely compatible with other JMX implementations. The proxy interface, however, is unique to Resin. If you choose, you can use the JMX API to access the resource. The configuration, of course, is Resin-dependent.


MBean listeners

Example showing configuration of MBean event listeners.

Files in this tutorial

File Description
WEB-INF/web.xml Configures the JMX-managed bean
WEB-INF/classes/example/Listener.java The listener bean implementation.
WEB-INF/classes/example/ListenerMBean.java The management interface for the listener.
WEB-INF/classes/example/Emitter.java The emitter bean implementation.
WEB-INF/classes/example/EmitterMBean.java The management interface for the emitter.
WEB-INF/classes/example/ListenerServlet.java Using the managed bean.

Emitter and Listener

JMX provides a general notification capability where MBean emitters send data to MBean listeners. Any managed bean can be an emitter or a listener by implementing the proper interfaces. The listeners are hooked up to the emitters either in the configuration file or through MBeanServer calls.

Listener

A listener implements NotificationListener to receive Notification events. The notification contains information for the type of the notification, the sender of the notification, and any notification-specific information.

The listener implements the single handleNotification method. It's parameters are the notification and an opaque handback object. The handback is specified during the listener registration and can be any information the listener wants.

Listener.java

package example;

import javax.management.NotificationListener;
import javax.management.Notification;

public class Listener
  implements NotificationListener, ListenerMBean {
  private int _count;

  public void handleNotification(Notification notif,
                                 Object handback)
  {
    _count++;
  }

  public int getNotificationCount()
  {
    return _count;
  }
}


Emitter

The Emitter sends notifications. Any managed bean which implements the NotificationEmitter interface can be an emitter. Many Emitters will extend the NotificationBroadcasterSupport, although this is not required.

NotificationBroadcasterSupport will handle the logic for adding and removing listeners as well as sending notifications to the proper listener. By extending NotificationBroadcasterSupport, the emitter only needs to call sendNotification to send the notification.

The first argument for the Notification is the notification type. Because each emitter can send multiple notifications, the type tells the listener which event has happened.

The second argument is typically the ObjectName for the emitter. Often, emitters will use the MBeanRegistration interface to find out the ObjectName.

Emitter.java

package example;

import javax.management.NotificationBroadcasterSupport;
import javax.management.Notification;

/**
 * Implements an MBean which sends notifications.
 */
public class Emitter extends NotificationBroadcasterSupport
  implements EmitterMBean {
  private long _sequence;
  
  /**
   * Sends a notification.
   */
  public void send()
  {
    Notification notif;

    notif = new Notification("example.send", this, _sequence++);

    sendNotification(notif);
  }
}


web.xml configuration

The web.xml (or resin.conf) configures the resource with the <resource> tag just as with [doc|ioc-bean.xtp other resources]. The resources is registered as an MBean by specifying an mbean-name.

web.xml

<web-app xmlns="http://caucho.com/ns/resin">
  <resource mbean-name="example:name=emitter"
            type="example.Emitter">
  </resource>

  <resource mbean-name="example:name=listener"
            type="example.Listener">
    <listener mbean-name="example:name=emitter" handback="tutorial"/>
  </resource>
</web-app>
tagdescription
resourcedefines the resource
mbean-namethe MBean name of the resource
typethe class name of the resource bean
listenerregisters the mbean with a notification emitter mbean
handbacka custom object to be passed back to the listener


Using the listener

This example provides a send() method to trigger a notification, but most notifications occuring when specific events occur, e.g. when a pool fills up.

In this case, invoking the send() method triggers the notification which will be sent to any waiting listeners. Calling listener.getNotificationCount() checks that the listener is getting called back.

ListenerServlet.java

public class ListenerServlet extends GenericServlet {
  private EmitterMBean _emitter;
  private ListenerMBean _listener;

  public void setEmitter(EmitterMBean emitter)
  {
    _emitter = emitter;
  }

  public void setListener(ListenerMBean listener)
  {
    _listener = listener;
  }

  public void service(ServletRequest request,
		      ServletResponse response)
    throws ServletException, IOException
  {
    PrintWriter out = response.getWriter();
    
    _emitter.send();

    out.println("listener count: " + _listener.getNotificationCount());
  }
}

results

count: 15

<results title="log"> [15:37:15.545] notification(type=example.send,handback=tutorial) [15:37:16.624] notification(type=example.send,handback=tutorial) [15:37:17.453] notification(type=example.send,handback=tutorial) </results>


Configuration with Dependency Injection

The ListenerServlet example follows the Dependency Injection pattern. Resin's web.xml will assemble the correct EmitterMBean and ListenerMBean. Using the Dependency Injection pattern simplifies the servlet, makes it more configurable, and more testable.

The configuration takes advantage of the "mbean:" JNDI scheme in Resin. The name following "mbean:" is used to lookup the mbean instance. The "mbean:" scheme then constructs a proxy for the mbean. The proxy of the JNDI lookup is then passed to setEmitter and setListener.

web.xml

<servlet-mapping url-pattern="/listener"
                 servlet-class="example.ListenerServlet">
  <init>
    <emitter>\${jndi:lookup("mbean:example:name=emitter")}</emitter>
    <listener>\${jndi:lookup("mbean:example:name=listener")}</listener>
  </init>
</servlet-mapping>


Compatibility

Notifications and listeners are part of the JMX standard. Client MBean proxies are standard and can be generated with javax.management.MBeanServerInvocationHandler

The <resource> configuration is Resin-specific. The support for the Dependency Injection for servlet configuration and the "mbean:" JNDI scheme are also Resin-specific.


Using MBeanRegistration

MBeans can implement the MBeanRegistration interface to find the ObjectName and MBeanServer they're registered with.

Files in this tutorial

File Description
WEB-INF/web.xml Configures the JMX-managed bean
WEB-INF/classes/example/Test.java The resource bean implementation.
WEB-INF/classes/example/TestMBean.java The management interface for the bean.
index.jsp Using the managed bean.

MBeanRegistration

Frequently, a managed bean will either need its ObjectName or its MBeanServer. When the bean implements the MBeanRegistration interface, the JMX server tells the bean its ObjectName on registration.

The bean can verify the ObjectName or even returning a different name, although returning a different ObjectName is generally a bad idea in most cases since it makes the to configure.

Test.java

package example;

import javax.management.ObjectName;
import javax.management.MBeanServer;
import javax.management.MBeanRegistration;

public class Test implements TestMBean, MBeanRegistration {
  private ObjectName _name;

  public ObjectName getObjectName()
  {
    return _name;
  }
  
  public ObjectName preRegister(MBeanServer server, ObjectName name)
    throws Exception
  {
    _name = name;

    return name;
  }
  
  public void postRegister(Boolean registrationDone)
  {
  }
  
  public void preDeregister()
    throws Exception
  {
  }
  
  public void postDeregister()
  {
  }
}

Client

The client JSP asks for the object's ObjectName to see the ObjectName passed in the preRegistration call.

index.jsp

<%@ page import='com.caucho.jmx.Jmx, example.BasicMBean' %>
<%
BasicMBean basic = (BasicMBean) Jmx.find("example:name=test");

out.println("ObjectName: " + test.getObjectName());
%>

results

ObjectName: example:name=test


Compatibility

MBeanRegistration is part of the JMX specification.


Using the JMX MBeanServer API

Example showing JMX-managed resources using the MBeanServer API.

Files in this tutorial

File Description
WEB-INF/web.xml Configures the JMX-managed bean
WEB-INF/classes/example/Test.java The resource bean implementation.
WEB-INF/classes/example/TestAdmin.java The management interface for the bean.
index.jsp Using the managed bean.

JMX Resource

Any resource in Resin can be managed by JMX by implementing an MBean interface and by specifying an MBean name. The interface exposes the resource's methods to be managed.

The Test resource

The test resource is identical to the [../jmx-basic/index.xtp basic example] but implements TestAdmin instead of TestMBean. Because the name TestAdmin does not conform to the MBean convention, the web.xml will need to specify the interface explicitly.

Test.java

package example;

public class Test implements TestMBean {
  private String _data = "default";

  public void setData(String data)
  {
    _data = data;
  }

  public String getData()
  {
    return _data;
  }
}


web.xml configuration

The web.xml (or resin.conf) configures the resource with the <resource> tag just as with [doc|ioc-bean.xtp other resources]. The resources is registered as an MBean by specifying an mbean-name.

web.xml

<web-app xmlns="http://caucho.com/ns/resin">
  <resource mbean-name="example:name=basic"
            type="example.Test"
            mbean-interface="example.TestAdmin>
    <init>
      <data>An Example Resource</data>
    </init>
  </resource>
</web-app>
tagdescription
resourcedefines the resource
mbean-namethe MBean name of the resource
typethe class name of the resource bean
mbean-interfacethe class name to use as the managed interface
initAny bean-style configuration goes here
dataThe example bean's setData parameter.


Using MBeanServer

MBeanServer is the main JMX interface for managing resources. Although it is less convenient than Resin's proxy interface, it has the advantage of being part of the JMX standard.

Resin stores the MBeanServer it uses for resources in WebBeans. Since MBeanServer is unique, the application can use @In to inject the server.

All management of an MBean uses the MBeanServer and the MBean's ObjectName. In this case, the ObjectName is "example:name=test".

The MBeanServer has three primary management calls: getAttribute, setAttribute, and invoke. This example just uses getAttribute.

index.jsp

<%@ page import='javax.webbeans.In, javax.management.*, example.TestAdmin' %>
<%!
@In MBeanServer _server;
%><%

ObjectName name = new ObjectName("example:name=test");

out.println("data: " + _server.getAttribute(name, "Data"));
%>

results

data: An example resource


Compatibility

Using the MBeanServer interface is compatible with other JMX implementations. The two Resin-dependencies are the configuration and how to obtain the Resin MBeanServer. Different JMX implementations will use a different technique to get the MBeanServer, so it's a good idea to encapsulate getting the MBeanServer in a class that you can change for different implementations.

Personal tools
TOOLBOX
LANGUAGES