|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /proc/self/root/usr/share/doc/mx4j-manual-3.0.1/ |
Upload File : |
<html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>The
javax.management.MBeanServerBuilder class
</title><link href="styles.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.69.1" name="generator"><link rel="start" href="index.html" title="MX4J English Documentation"><link rel="up" href="ch02.html" title="Chapter 2. JMX 1.2 Explained"><link rel="prev" href="ch02s02.html" title="Support for remote API"><link rel="next" href="ch02s04.html" title="The
javax.management.MBeanServerInvocationHandler class
"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table summary="Navigation header" width="100%"><tr><th align="center" colspan="3">The
<code class="classname">javax.management.MBeanServerBuilder</code> class
</th></tr><tr><td align="left" width="20%"><a accesskey="p" href="ch02s02.html">Prev</a> </td><th align="center" width="60%">Chapter 2. JMX 1.2 Explained</th><td align="right" width="20%"> <a accesskey="n" href="ch02s04.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="N1011C"></a>The
<code class="classname">javax.management.MBeanServerBuilder</code> class
</h2></div></div><div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N10122"></a>Introduction</h3></div></div><div></div></div><p>
JMX 1.2 introduced the possibility to replace, at runtime, the MBeanServer implementation by specifying
a full qualified name of a
<code class="classname">javax.management.MBeanServerBuilder</code> subclass with the
system property "javax.management.builder.initial".
<br>
When creating a new
<code class="classname">MBeanServer</code> instance, the
<code class="classname">MBeanServerFactory</code>
checks (every time) for the value of that system property; if it is not null, loads (using the context classloader),
instantiates, and delegates the
<code class="classname">MBeanServerBuilder</code> subclass to create
<code class="classname">MBeanServer</code> instances.
</p><p>
Since now the creation of
<code class="classname">MBeanServer</code> instances can be delegated to a custom
<code class="classname">MBeanServerBuilder</code>, it is possible to achieve two things:
<div class="itemizedlist"><ul type="disc"><li>Use Sun's JMX reference implementation (JMXRI) but telling it to use MX4J's
<code class="classname">MBeanServer</code> implementation
</li><li>"Wrap" the
<code class="classname">MBeanServer</code> implementation and "decorate" it with added functionality.
</li></ul></div>
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N1014C"></a>How to use MX4J's
<code class="classname">MBeanServer</code> implementation with Sun's JMX Reference Implementation.
</h3></div></div><div></div></div><p>
This is very simple to achieve:
</p><p>
<div class="example"><a name="N10156"></a><p class="title"><b>Example 2.1. </b></p><pre class="programlisting">
java -cp jmxri.jar;mx4j-impl.jar -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder <MyClass>
</pre></div>
</p><p>
Note how the classpath specifies
<span class="emphasis"><em>first</em></span> the JMXRI jar and
<span class="emphasis"><em>then</em></span> the MX4J
implementation jar.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N10163"></a>How to "decorate"
<code class="classname">MBeanServer</code> methods.
</h3></div></div><div></div></div><p>
A custom
<code class="classname">MBeanServerBuilder</code> allows you to specify how to create an
<code class="classname">MBeanServer</code>.
<br>
Any JMX implementation has already in place a mechanism that uses a default
<code class="classname">MBeanServerBuilder</code>
to create instances of the default
<code class="classname">MBeanServer</code> implementation.
<br>
In order to be able to "decorate" an
<code class="classname">MBeanServer</code> it is sufficient to specify a custom
<code class="classname">MBeanServerBuilder</code> that "decorates" the default one; then the implementation of the custom
<code class="classname">MBeanServerBuilder</code> will "decorate" the default
<code class="classname">MBeanServer</code>.
</p><p>
However, implementing a "decorating"
<code class="classname">MBeanServerBuilder</code> requires a bit of precision.
<br>
We will explain how to do this in detail in the following, using as example the MX4J implementation.
</p><p>
Using the
<code class="classname">MBeanServerBuilder</code> to "decorate" an
<code class="classname">MBeanServer</code>
requires to write two classes:
<div class="itemizedlist"><ul type="disc"><li>a custom
<code class="classname">MBeanServerBuilder</code></li><li>a decorating
<code class="classname">MBeanServer</code></li></ul></div>
<br>
Although it's possible to start from scratch, the MX4J API gives you two base classes to start from:
<div class="itemizedlist"><ul type="disc"><li><code class="classname">mx4j.server.ChainedMBeanServerBuilder</code></li><li><code class="classname">mx4j.server.ChainedMBeanServer</code></li></ul></div>
</p><p>
Let's suppose we want to decorate the default
<code class="classname">MBeanServer</code> by adding logging statements
whenever a
<code class="classname">MBeanServer</code> method is called.
<br>
First, we write the "decorating"
<code class="classname">MBeanServer</code>:
</p><p>
<div class="example"><a name="N101B9"></a><p class="title"><b>Example 2.2. A "decorating"
<code class="classname">MBeanServer</code> that logs method calls.
</b></p><pre class="programlisting">
public class LoggingMBeanServer extends ChainedMBeanServer
{
// Overridden just to make it public
public void setMBeanServer(MBeanServer server)
{
super.setMBeanServer(server);
}
public Object getAttribute(ObjectName objectName, String attribute)
throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException
{
Object value = super.getAttribute(objectName, attribute);
System.out.println("[LOGGER] getAttribute() returned: " + value);
return value;
}
// And so on for all other MBeanServer methods.
}
</pre></div>
</p><p>
The class
<code class="classname">ChainedMBeanServer</code> simply forwards the calls to a nested
<code class="classname">MBeanServer</code>.
<code class="classname">ChainedMBeanServer</code> thus allows to create a "chain" of
<code class="classname">MBeanServer</code>s
that are called in succession, one after the other, from the outermost to the innermost.
</p><p>
Second, we write the "decorating"
<code class="classname">MBeanServerBuilder</code>:
</p><p>
<div class="example"><a name="N101D8"></a><p class="title"><b>Example 2.3. A "decorating"
<code class="classname">MBeanServerBuilder</code>
</b></p><pre class="programlisting">
public class LoggingBuilder extends ChainedMBeanServerBuilder
{
public LoggingBuilder()
{
super(new mx4j.server.MX4JMBeanServerBuilder());
}
public MBeanServer newMBeanServer(String defaultDomain, MBeanServer outer, MBeanServerDelegate delegate)
{
LoggingMBeanServer extern = new LoggingMBeanServer();
MBeanServer nested = getMBeanServerBuilder().newMBeanServer(defaultDomain, outer == null ? extern : outer, delegate);
extern.setMBeanServer(nested);
return extern;
}
}
</pre></div>
</p><p>
As for the
<code class="classname">ChainedMBeanServer</code> class, also
<code class="classname">ChainedMBeanServerBuilder</code>
simply forwards the calls to a nested
<code class="classname">MBeanServerBuilder</code>.
Also here,
<code class="classname">ChainedMBeanServerBuilder</code> allows to create a "chain" of
<code class="classname">MBeanServerBuilder</code>s
that are called in succession, one after the other, from the outermost to the innermost.
</p><p>
The
<code class="classname">MBeanServerBuilder</code> chain works in parallel with the
<code class="classname">MBeanServer</code>
chain in this way:
</p><p>
<div class="example"><a name="N101FD"></a><p class="title"><b>Example 2.4. The
<code class="classname">MBeanServerBuilder</code> and
<code class="classname">MBeanServer</code> chains
</b></p><pre class="programlisting">
MBeanServerFactory -- calls --> LoggingBuilder -- calls --> MX4JMBeanServerBuilder
| |
creates creates
| |
V V
Application -- calls --> LoggingMBeanServer -- calls --> MX4JMBeanServer
</pre></div>
</p><p>
Note the
<code class="classname">LoggingBuilder</code> constructor: there is where the
<code class="classname">MBeanServerBuilder</code> chain is created.
<br>
The
<code class="classname">LoggingBuilder</code> specifies a chain of only two rings, the
<code class="classname">LoggingBuilder</code>
itself, and MX4J's default
<code class="classname">MBeanServerBuilder</code>,
<code class="classname">MX4JMBeanServerBuilder</code>.
<br>
This chain is hardcoded in the builder, meaning that if you want to change it at runtime you cannot: either you
change and recompile the custom builder, or you use another custom builder.
</p><p>
Note also the usage of the ternary operator (condition ? this : that) in the nested
<font color="red"><funcdef>
<code class="function">newMBeanServer()</code>
</funcdef></font> call: checking for nullity of the "outer" argument is
of fundamental importance for the builder to be "chainable". If this check is not made, then
<code class="classname">LoggingBuilder</code> cannot be reused as a ring of a longer chain if, in future, we modify it
to accept as parameter to the constructor other builders (i.e. other "rings").
</p><p>
It is of course possible to use different builders from different vendors, simply by creating a custom builder
that "chains" all the other in the desired sequence:
</p><p>
<div class="example"><a name="N10232"></a><p class="title"><b>Example 2.5. A "decorating"
<code class="classname">MBeanServerBuilder</code>
</b></p><pre class="programlisting">
public class ComplexBuilder extends ChainedMBeanServerBuilder
{
public LoggingBuilder()
{
super(new com.sun.jmx.bar.BarBuilder(new com.ibm.jmx.foo.FooBuilder(new mx4j.server.MX4JMBeanServerBuilder())));
}
}
</pre></div>
</p><p>
Just remember that
<code class="classname">MX4JMBeanServerBuilder</code> is a "terminal" builder and must
always be the last in the chain.
<br>
Other vendors are expected to provide an API for their custom builders very similar to
<code class="classname">ChainedMBeanServerBuilder</code> (which is mostly being able to take a
<code class="classname">javax.management.MBeanServerBuilder</code> as argument to a constructor).
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N10249"></a>More complex
<code class="classname">MBeanServer</code> "decorations".
</h3></div></div><div></div></div><p>
We saw above that is possible to "decorate"
<code class="classname">MBeanServer</code>s by decorating the
default mechanism of the
<code class="classname">MBeanServerBuilder</code> already in place in any JMX implementation.
<br>
We saw that to a chain of builders corresponded a chain of servers.
<br>
However, it's possible that a builder specifies more than one ring for the server chain, in the following way:
</p><p>
<div class="example"><a name="N1025D"></a><p class="title"><b>Example 2.6. A More complex
<code class="classname">MBeanServerBuilder</code> and
<code class="classname">MBeanServer</code> chains
</b></p><pre class="programlisting">
MBeanServerFactory --calls--> LoggingBuilder --calls--> PerformanceBuilder --calls--> MX4JMBeanServerBuilder
| | |
creates creates creates
| / \ |
V V V V
Application --calls--> LoggingMBeanServer --calls--> TimingServer --calls--> CountingServer --calls--> MX4JMBeanServer
</pre></div>
</p><p>
An example of such chains is present in the MX4J testsuite, in the test class that tests the
<code class="classname">MBeanServerBuilder</code> functionality.
</p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N1026F"></a>Possible usages of MBeanServer "decorators"</h3></div></div><div></div></div><p>
A (non complete) list of possible "decorators" for
<code class="classname">MBeanServer</code>
may include functionality such as:
<div class="itemizedlist"><ul type="disc"><li>Logging the invocation</li><li>Measuring the invocation time</li><li>Counting the number of invocations</li><li>Load-balancing the invocations among server nodes</li><li>Cascading the invocations to child servers</li><li>Notifying a message to someone for a particular invocation</li><li>...</li></ul></div>
</p></div></div><div class="navfooter"><hr><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02.html">Prev</a> </td><td align="center" width="20%"><a accesskey="u" href="ch02.html">Up</a></td><td align="right" width="40%"> <a accesskey="n" href="ch02s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">Support for remote API </td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%"> The
<code class="classname">javax.management.MBeanServerInvocationHandler</code> class
</td></tr></table></div></body></html>