http://wiki4.caucho.com/index.php?title=Resin_4_Application_Server_JMX_Tutorial&feed=atom&action=historyResin 4 Application Server JMX Tutorial - Revision history2024-03-28T12:00:54ZRevision history for this page on the wikiMediaWiki 1.18.0http://wiki4.caucho.com/index.php?title=Resin_4_Application_Server_JMX_Tutorial&diff=664&oldid=prevRick at 00:00, 16 June 20122012-06-16T00:00:00Z<p></p>
<table class='diff diff-contentalign-left'>
<col class='diff-marker' />
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
<tr valign='top'>
<td colspan='2' style="background-color: white; color:black;">← Older revision</td>
<td colspan='2' style="background-color: white; color:black;">Revision as of 00:00, 16 June 2012</td>
</tr><tr><td colspan="2" class="diff-lineno">Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;">{{Cookbook}}  {{Development}}</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="background: #cfc; color:black; font-size: smaller;"><div><ins style="color: red; font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>=JMX/Administration Tutorials=</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>=JMX/Administration Tutorials=</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>=Simple JMX-managed Resource=</div></td><td class='diff-marker'> </td><td style="background: #eee; color:black; font-size: smaller;"><div>=Simple JMX-managed Resource=</div></td></tr>
</table>Rickhttp://wiki4.caucho.com/index.php?title=Resin_4_Application_Server_JMX_Tutorial&diff=647&oldid=prevRick: Created page with "=JMX/Administration Tutorials= =Simple JMX-managed Resource= <p> Resources can be JMX managed by exposing a management interface and registering as an MBean..."2012-06-15T00:00:00Z<p>Created page with "=JMX/Administration Tutorials= =Simple JMX-managed Resource= <p> Resources can be JMX managed by exposing a management interface and registering as an MBean..."</p>
<p><b>New page</b></p><div>=JMX/Administration Tutorials=<br />
=Simple JMX-managed Resource=<br />
<p><br />
Resources can be JMX managed by exposing a management interface<br />
and registering as an MBean.<br />
</p><br />
<br />
==Files in this tutorial==<br />
<table><br />
<tr><br />
<th>File</th><br />
<th>Description</th><br />
</tr><br />
<tr><br />
<td><code>WEB-INF/web.xml</code></td><br />
<td>Configures the JMX-managed bean</td><br />
</tr><br />
<tr><br />
<td><code>WEB-INF/classes/example/Basic.java</code></td><br />
<td>The resource bean implementation.</td><br />
</tr><br />
<tr><br />
<td><code>WEB-INF/classes/example/BasicMBean.java</code></td><br />
<td>The management interface for the bean.</td><br />
</tr><br />
<tr><br />
<td><code>index.jsp</code></td><br />
<td>Using the managed bean.</td><br />
</tr><br />
</table><br />
<br />
<br />
==JMX Resource==<br />
<br />
<p>Any resource in Resin can be managed by JMX by implementing<br />
an MBean interface and by specifying an MBean name. The interface<br />
exposes the resource's methods to be managed.</p><br />
<br />
===The Basic resource===<br />
<br />
<br />
<p>The <code>Basic</code> bean is the example resource implementation.<br />
It exposes its managed interface by implementing a <code>BasicMBean</code><br />
interface. The <code>xxxMBean</code> naming convention lets JMX determine<br />
which interface to use for management. The MBean interface will expose<br />
the Data attribute to JMX.</p><br />
<br />
====Basic.java====<br />
<pre><br />
package example;<br />
<br />
public class Basic implements BasicMBean {<br />
private String _data = "default";<br />
<br />
public void setData(String data)<br />
{<br />
_data = data;<br />
}<br />
<br />
public String getData()<br />
{<br />
return _data;<br />
}<br />
}<br />
</pre><br />
<br />
<p><code>BasicMBean</code> is the bean's management interface.<br />
It exposes a single attribute, Data, as a getter/setter pair.<br />
The name of the interface is important. Since the resource is named<br />
<code>Basic</code>, the MBean interface will be<br />
named <code>BasicMBean</code>.</p><br />
<br />
====BasicMBean.java====<br />
<pre><br />
package example;<br />
<br />
public interface BasicMBean {<br />
public void setData(String data);<br />
<br />
public String getData();<br />
}<br />
</pre><br />
<br />
<br />
===MBean names===<br />
<br />
<br />
<p>MBeans are stored in the MBean server using<br />
an <code>ObjectName</code> as its key. Essentially, the MBean server<br />
stores the managed beans in a map using the mbean name as a key.</p><br />
<br />
<p>The mbean name consists of a set of &lt;name,value&gt; properties<br />
and a "domain" used like a namespace. The properties allow for<br />
querying related mbeans. For example, you could request for<br />
all mbeans with "J2EEType=Servlet", which would return all the<br />
managed servlets.</p><br />
<br />
<p>The example uses the name "example:name=basic".<br />
"example" is the domain and the bean's single property is "name" with<br />
a value of "basic". By convention, an mbean would normally also have<br />
a "type" property, but this example is using a name as simple as possible.</p><br />
<br />
<br />
===web.xml configuration===<br />
<br />
<br />
<p>The web.xml (or resin.conf) configures the resource with the<br />
&lt;resource&gt; tag just as with<br />
[doc|ioc-bean.xtp other resources]. The resources is<br />
registered as an MBean by specifying an '''''mbean-name'''''.<br />
</p><br />
<br />
====web.xml====<br />
<pre><br />
<web-app xmlns="http://caucho.com/ns/resin"><br />
<resource mbean-name="example:name=basic" type="example.Basic"><br />
<init><br />
<data>An Example Resource</data><br />
</init><br />
</resource><br />
</web-app><br />
</pre><br />
<br />
<table><br />
<tr><th>tag</th><th>description<br />
</th></tr><tr><td>resource</td><td>defines the resource<br />
</td></tr><tr><td>mbean-name</td><td>the MBean name of the resource<br />
</td></tr><tr><td>type</td><td>the class name of the resource bean<br />
</td></tr><tr><td>init</td><td>Any bean-style configuration goes here<br />
</td></tr><tr><td>data</td><td>The example bean's <code>setData</code> parameter.<br />
</td></tr></table><br />
<br />
<br />
===Using the resource proxy===<br />
<br />
<br />
<p>Resin's JMX implementation provides a proxy to<br />
managed object using the interface for an API. You can, of course,<br />
use the standard JMX interface, the proxy interface is much easier to<br />
use.</p><br />
<br />
====index.jsp====<br />
<pre><br />
<%@ page import='com.caucho.jmx.Jmx, example.BasicMBean' %><br />
<%<br />
BasicMBean basic = (BasicMBean) Jmx.find("example:name=basic");<br />
<br />
out.println("data: " + basic.getData());<br />
%><br />
</pre><br />
====results====<br />
<pre><br />
data: An example resource<br />
</pre><br />
<br />
<br />
<br />
==Compatibility==<br />
<br />
<p>The resource's code is completely compatible with other JMX<br />
implementations. The proxy interface, however, is unique to Resin.<br />
If you choose, you can use the JMX API to access the resource.<br />
The configuration, of course, is Resin-dependent.</p><br />
<br />
<br />
=MBean listeners=<br />
<p><br />
Example showing configuration of MBean event listeners.<br />
</p><br />
<br />
==Files in this tutorial==<br />
<table><br />
<tr><br />
<th>File</th><br />
<th>Description</th><br />
</tr><br />
<tr><td><code>WEB-INF/web.xml</code><br />
</td><td>Configures the JMX-managed bean<br />
</td></tr><tr><td><code>WEB-INF/classes/example/Listener.java</code><br />
</td><td>The listener bean implementation.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/ListenerMBean.java</code><br />
</td><td>The management interface for the listener.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/Emitter.java</code><br />
</td><td>The emitter bean implementation.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/EmitterMBean.java</code><br />
</td><td>The management interface for the emitter.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/ListenerServlet.java</code><br />
</td><td>Using the managed bean.<br />
</td></tr></table><br />
<br />
==Emitter and Listener==<br />
<br />
<p>JMX provides a general notification capability where MBean<br />
'''''emitters''''' send data to MBean '''''listeners'''''. Any managed<br />
bean can be an emitter or a listener by implementing the<br />
proper interfaces. The listeners are hooked up to the emitters either<br />
in the configuration file or through MBeanServer calls.</p><br />
<br />
===Listener===<br />
<br />
<br />
<p>A listener implements <code>NotificationListener</code> to receive<br />
<code>Notification</code> events. The notification contains information<br />
for the type of the notification, the sender of the notification, and<br />
any notification-specific information.</p><br />
<br />
<p>The listener implements the single <code>handleNotification</code><br />
method. It's parameters are the notification and an opaque<br />
'''''handback''''' object. The '''''handback''''' is specified during<br />
the listener registration and can be any information the listener<br />
wants.</p><br />
<br />
====Listener.java====<br />
<pre><br />
package example;<br />
<br />
import javax.management.NotificationListener;<br />
import javax.management.Notification;<br />
<br />
public class Listener<br />
implements NotificationListener, ListenerMBean {<br />
private int _count;<br />
<br />
public void handleNotification(Notification notif,<br />
Object handback)<br />
{<br />
_count++;<br />
}<br />
<br />
public int getNotificationCount()<br />
{<br />
return _count;<br />
}<br />
}<br />
</pre><br />
<br />
<br />
===Emitter===<br />
<br />
<br />
<p>The Emitter sends notifications. Any managed bean which implements<br />
the <code>NotificationEmitter</code> interface can be an emitter. Many<br />
Emitters will extend the <code>NotificationBroadcasterSupport</code>,<br />
although this is not required.</p><br />
<br />
<p><code>NotificationBroadcasterSupport</code> will handle the logic<br />
for adding and removing listeners as well as sending notifications to<br />
the proper listener. By extending<br />
<code>NotificationBroadcasterSupport</code>, the emitter only needs to<br />
call <code>sendNotification</code> to send the notification.</p><br />
<br />
<p>The first argument for the <code>Notification</code> is the notification<br />
type. Because each emitter can send multiple notifications, the type<br />
tells the listener which event has happened.</p><br />
<br />
<p>The second argument is typically the <code>ObjectName</code> for<br />
the emitter. Often, emitters will use<br />
the <code>MBeanRegistration</code> interface to find out the<br />
<code>ObjectName</code>.</p><br />
<br />
====Emitter.java====<br />
<pre><br />
package example;<br />
<br />
import javax.management.NotificationBroadcasterSupport;<br />
import javax.management.Notification;<br />
<br />
/**<br />
* Implements an MBean which sends notifications.<br />
*/<br />
public class Emitter extends NotificationBroadcasterSupport<br />
implements EmitterMBean {<br />
private long _sequence;<br />
<br />
/**<br />
* Sends a notification.<br />
*/<br />
public void send()<br />
{<br />
Notification notif;<br />
<br />
notif = new Notification("example.send", this, _sequence++);<br />
<br />
sendNotification(notif);<br />
}<br />
}<br />
</pre><br />
<br />
<br />
===web.xml configuration===<br />
<br />
<br />
<p>The web.xml (or resin.conf) configures the resource with the<br />
&lt;resource&gt; tag just as with<br />
[doc|ioc-bean.xtp other resources]. The resources is<br />
registered as an MBean by specifying an '''''mbean-name'''''.<br />
</p><br />
<br />
====web.xml====<br />
<pre><br />
<web-app xmlns="http://caucho.com/ns/resin"><br />
<resource mbean-name="example:name=emitter"<br />
type="example.Emitter"><br />
</resource><br />
<br />
<resource mbean-name="example:name=listener"<br />
type="example.Listener"><br />
<listener mbean-name="example:name=emitter" handback="tutorial"/><br />
</resource><br />
</web-app><br />
</pre><br />
<br />
<table><br />
<tr><th>tag</th><th>description<br />
</th></tr><tr><td>resource</td><td>defines the resource<br />
</td></tr><tr><td>mbean-name</td><td>the MBean name of the resource<br />
</td></tr><tr><td>type</td><td>the class name of the resource bean<br />
</td></tr><tr><td>listener</td><td>registers the mbean with a notification emitter mbean<br />
</td></tr><tr><td>handback</td><td>a custom object to be passed back to the listener<br />
</td></tr></table><br />
<br />
<br />
===Using the listener===<br />
<br />
<br />
<p>This example provides a <code>send()</code> method to<br />
trigger a notification, but most notifications occuring when<br />
specific events occur, e.g. when a pool fills up.</p><br />
<br />
<p>In this case, invoking the <code>send()</code> method triggers<br />
the notification which will be sent to any waiting listeners. Calling<br />
<code>listener.getNotificationCount()</code> checks that the listener<br />
is getting called back.</p><br />
<br />
====ListenerServlet.java====<br />
<pre><br />
public class ListenerServlet extends GenericServlet {<br />
private EmitterMBean _emitter;<br />
private ListenerMBean _listener;<br />
<br />
public void setEmitter(EmitterMBean emitter)<br />
{<br />
_emitter = emitter;<br />
}<br />
<br />
public void setListener(ListenerMBean listener)<br />
{<br />
_listener = listener;<br />
}<br />
<br />
public void service(ServletRequest request,<br />
ServletResponse response)<br />
throws ServletException, IOException<br />
{<br />
PrintWriter out = response.getWriter();<br />
<br />
_emitter.send();<br />
<br />
out.println("listener count: " + _listener.getNotificationCount());<br />
}<br />
}<br />
</pre><br />
====results====<br />
<pre><br />
count: 15<br />
</pre><br />
<results title="log"><br />
[15:37:15.545] notification(type=example.send,handback=tutorial)<br />
[15:37:16.624] notification(type=example.send,handback=tutorial)<br />
[15:37:17.453] notification(type=example.send,handback=tutorial)<br />
</results><br />
<br />
<br />
===Configuration with Dependency Injection===<br />
<br />
<br />
<p>The ListenerServlet example follows the<br />
Dependency Injection pattern. Resin's web.xml will assemble the<br />
correct EmitterMBean and ListenerMBean. Using the Dependency Injection<br />
pattern simplifies the servlet, makes it more configurable,<br />
and more testable.</p><br />
<br />
<p>The configuration takes advantage of the "mbean:" JNDI scheme in Resin.<br />
The name following "mbean:" is used to lookup the mbean instance. The<br />
"mbean:" scheme then constructs a proxy for the mbean. The proxy<br />
of the JNDI lookup is then passed to <code>setEmitter</code><br />
and <code>setListener</code>.</p><br />
<br />
====web.xml====<br />
<pre><br />
<servlet-mapping url-pattern="/listener"<br />
servlet-class="example.ListenerServlet"><br />
<init><br />
<emitter>\${jndi:lookup("mbean:example:name=emitter")}</emitter><br />
<listener>\${jndi:lookup("mbean:example:name=listener")}</listener><br />
</init><br />
</servlet-mapping><br />
</pre><br />
<br />
<br />
<br />
==Compatibility==<br />
<br />
<p>Notifications and listeners are part of the JMX standard.<br />
Client MBean proxies are standard and can be generated<br />
with <code>javax.management.MBeanServerInvocationHandler</code><br />
</p><br />
<br />
<p>The &lt;resource&gt; configuration is Resin-specific. The support<br />
for the Dependency Injection for servlet configuration<br />
and the "mbean:" JNDI scheme are also Resin-specific.</p><br />
<br />
<br />
=Using MBeanRegistration=<br />
<p><br />
MBeans can implement the MBeanRegistration interface to find the<br />
ObjectName and MBeanServer they're registered with.<br />
</p><br />
<br />
==Files in this tutorial==<br />
<table><br />
<tr><br />
<th>File</th><br />
<th>Description</th><br />
</tr><br />
<tr><td><code>WEB-INF/web.xml</code><br />
</td><td>Configures the JMX-managed bean<br />
</td></tr><tr><td><code>WEB-INF/classes/example/Test.java</code><br />
</td><td>The resource bean implementation.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/TestMBean.java</code><br />
</td><td>The management interface for the bean.<br />
</td></tr><tr><td><code>index.jsp</code><br />
</td><td>Using the managed bean.<br />
</td></tr></table><br />
<br />
==MBeanRegistration==<br />
<br />
<p>Frequently, a managed bean will either need<br />
its <code>ObjectName</code> or its <code>MBeanServer</code>. When the<br />
bean implements the <code>MBeanRegistration</code> interface, the<br />
JMX server tells the bean its <code>ObjectName</code> on registration.</p><br />
<br />
<p>The bean can verify the <code>ObjectName</code> or even<br />
returning a different name, although returning a different<br />
<code>ObjectName</code> is generally a bad idea in most cases since it<br />
makes the to configure.</p><br />
<br />
====Test.java====<br />
<pre><br />
package example;<br />
<br />
import javax.management.ObjectName;<br />
import javax.management.MBeanServer;<br />
import javax.management.MBeanRegistration;<br />
<br />
public class Test implements TestMBean, MBeanRegistration {<br />
private ObjectName _name;<br />
<br />
public ObjectName getObjectName()<br />
{<br />
return _name;<br />
}<br />
<br />
public ObjectName preRegister(MBeanServer server, ObjectName name)<br />
throws Exception<br />
{<br />
_name = name;<br />
<br />
return name;<br />
}<br />
<br />
public void postRegister(Boolean registrationDone)<br />
{<br />
}<br />
<br />
public void preDeregister()<br />
throws Exception<br />
{<br />
}<br />
<br />
public void postDeregister()<br />
{<br />
}<br />
}<br />
</pre><br />
<br />
===Client===<br />
<br />
<br />
<p>The client JSP asks for the object's ObjectName to see the ObjectName<br />
passed in the <code>preRegistration</code> call.</p><br />
<br />
====index.jsp====<br />
<pre><br />
<%@ page import='com.caucho.jmx.Jmx, example.BasicMBean' %><br />
<%<br />
BasicMBean basic = (BasicMBean) Jmx.find("example:name=test");<br />
<br />
out.println("ObjectName: " + test.getObjectName());<br />
%><br />
</pre><br />
====results====<br />
<pre><br />
ObjectName: example:name=test<br />
</pre><br />
<br />
<br />
<br />
==Compatibility==<br />
<br />
<p>MBeanRegistration is part of the JMX specification.</p><br />
<br />
<br />
=Using the JMX MBeanServer API=<br />
<p><br />
Example showing JMX-managed resources using the MBeanServer API.<br />
</p><br />
<br />
==Files in this tutorial==<br />
<table><br />
<tr><br />
<th>File</th><br />
<th>Description</th><br />
</tr><br />
<tr><td><code>WEB-INF/web.xml</code><br />
</td><td>Configures the JMX-managed bean<br />
</td></tr><tr><td><code>WEB-INF/classes/example/Test.java</code><br />
</td><td>The resource bean implementation.<br />
</td></tr><tr><td><code>WEB-INF/classes/example/TestAdmin.java</code><br />
</td><td>The management interface for the bean.<br />
</td></tr><tr><td><code>index.jsp</code><br />
</td><td>Using the managed bean.<br />
</td></tr></table><br />
<br />
==JMX Resource==<br />
<br />
<p>Any resource in Resin can be managed by JMX by implementing<br />
an MBean interface and by specifying an MBean name. The interface<br />
exposes the resource's methods to be managed.</p><br />
<br />
===The Test resource===<br />
<br />
<br />
<p>The test resource is identical to the<br />
[../jmx-basic/index.xtp basic example] but implements<br />
<code>TestAdmin</code> instead of <code>TestMBean</code>. Because<br />
the name <code>TestAdmin</code> does not conform to the MBean convention,<br />
the web.xml will need to specify the interface explicitly.</p><br />
<br />
====Test.java====<br />
<pre><br />
package example;<br />
<br />
public class Test implements TestMBean {<br />
private String _data = "default";<br />
<br />
public void setData(String data)<br />
{<br />
_data = data;<br />
}<br />
<br />
public String getData()<br />
{<br />
return _data;<br />
}<br />
}<br />
</pre><br />
<br />
<br />
===web.xml configuration===<br />
<br />
<br />
<p>The web.xml (or resin.conf) configures the resource with the<br />
&lt;resource&gt; tag just as with<br />
[doc|ioc-bean.xtp other resources]. The resources is<br />
registered as an MBean by specifying an '''''mbean-name'''''.<br />
</p><br />
<br />
====web.xml====<br />
<pre><br />
<web-app xmlns="http://caucho.com/ns/resin"><br />
<resource mbean-name="example:name=basic"<br />
type="example.Test"<br />
mbean-interface="example.TestAdmin><br />
<init><br />
<data>An Example Resource</data><br />
</init><br />
</resource><br />
</web-app><br />
</pre><br />
<br />
<table><br />
<tr><th>tag</th><th>description<br />
</th></tr><tr><td>resource</td><td>defines the resource<br />
</td></tr><tr><td>mbean-name</td><td>the MBean name of the resource<br />
</td></tr><tr><td>type</td><td>the class name of the resource bean<br />
</td></tr><tr><td>mbean-interface</td><td>the class name to use as the managed interface<br />
</td></tr><tr><td>init</td><td>Any bean-style configuration goes here<br />
</td></tr><tr><td>data</td><td>The example bean's <code>setData</code> parameter.<br />
</td></tr></table><br />
<br />
<br />
===Using MBeanServer===<br />
<br />
<br />
<p>MBeanServer is the main JMX interface for managing resources.<br />
Although it is less convenient than Resin's proxy interface, it has the<br />
advantage of being part of the JMX standard.</p><br />
<br />
<p>Resin stores the MBeanServer it uses for resources in WebBeans.<br />
Since MBeanServer is unique, the application can use <code>@In</code><br />
to inject the server.</p><br />
<br />
<p>All management of an MBean uses the MBeanServer and the MBean's<br />
ObjectName. In this case, the ObjectName is "example:name=test".</p><br />
<br />
<p>The MBeanServer has three primary management calls:<br />
<code>getAttribute</code>, <code>setAttribute</code>,<br />
and <code>invoke</code>. This example just uses <code>getAttribute</code>.<br />
</p><br />
<br />
====index.jsp====<br />
<pre><br />
<%@ page import='javax.webbeans.In, javax.management.*, example.TestAdmin' %><br />
<%!<br />
@In MBeanServer _server;<br />
%><%<br />
<br />
ObjectName name = new ObjectName("example:name=test");<br />
<br />
out.println("data: " + _server.getAttribute(name, "Data"));<br />
%><br />
</pre><br />
====results====<br />
<pre><br />
data: An example resource<br />
</pre><br />
<br />
<br />
<br />
==Compatibility==<br />
<br />
<p>Using the MBeanServer interface is compatible with other<br />
JMX implementations. The two Resin-dependencies are the configuration<br />
and how to obtain the Resin MBeanServer. Different JMX implementations<br />
will use a different technique to get the MBeanServer, so it's a good<br />
idea to encapsulate getting the MBeanServer in a class that you can<br />
change for different implementations.</p></div>Rick