jdk/src/share/sample/jmx/jmx-scandir/index.html
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
       
     2 
       
     3 <html>
       
     4   <head>
       
     5 <!--
       
     6  Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     7 
       
     8  Redistribution and use in source and binary forms, with or without
       
     9  modification, are permitted provided that the following conditions
       
    10  are met:
       
    11 
       
    12    - Redistributions of source code must retain the above copyright
       
    13      notice, this list of conditions and the following disclaimer.
       
    14 
       
    15    - Redistributions in binary form must reproduce the above copyright
       
    16      notice, this list of conditions and the following disclaimer in the
       
    17      documentation and/or other materials provided with the distribution.
       
    18 
       
    19    - Neither the name of Sun Microsystems nor the names of its
       
    20      contributors may be used to endorse or promote products derived
       
    21      from this software without specific prior written permission.
       
    22 
       
    23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       
    24  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    25  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    26  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    27  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    28  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    29  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    30  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    31  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    32  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    33  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    34 -->
       
    35 
       
    36     <title>JMX(TM) "scandir" Example</title>
       
    37   </head>
       
    38   <body>
       
    39   
       
    40   <h1><center>Java<font size="-1"><sup>TM</sup></font> Management Extensions (JMX<font size="-1"><sup>TM</sup></font>) <i>scandir</i> Example</center></h1>
       
    41   
       
    42   <h2><a name="h2-Introduction">Introduction</a></h2>
       
    43   <ul>
       
    44   <p>The JMX <i>scandir</i> example is an application that
       
    45      scans parts of a filesystem - e.g. a set of directories
       
    46      used by a number of lab machines when running tests - in
       
    47      order to clean up and optimize disk space by removing
       
    48      obsolete files - e.g. files that are leaked by the test
       
    49      suites running on those machines, like coredump files, or
       
    50      temporary files that might remain after a test crash.
       
    51      It could also serve as a basis for an application that
       
    52      would monitor disk usage and suggest removal of old big
       
    53      long-unaccessed files.
       
    54   </p>
       
    55   <p>The JMX <i>scandir</i> example does not however implement
       
    56      the full fledged logic that such an application might
       
    57      have. It implements a subset of this logic which is
       
    58      sufficient to demonstrate common patterns and
       
    59      solutions used when implementing a monitoring and
       
    60      management interface for an application with JMX
       
    61      Technology.</p>
       
    62   <p>This example is an advanced JMX example, which presents 
       
    63      advanced JMX concepts. It is assumed that the reader is already
       
    64      familiar with the JMX API. Newcomers to JMX Technology are
       
    65      invited to have a look at the <a
       
    66      href="http://java.sun.com/javase/6/docs/technotes/guides/jmx/"
       
    67      >JMX API Overview, Tutorial and Examples</a> before going any further.
       
    68   </p>
       
    69   <p></p>
       
    70       <hr>
       
    71   <blockquote>
       
    72     <u>Note:</u> This example was developed using <a 
       
    73      href="http://www.netbeans.org">NetBeans 5.0 IDE</a>. The instructions
       
    74      given in this document to build, run, and test the example assume that
       
    75      you have at your disposal:
       
    76      <ul><li>either <a href="http://www.netbeans.org">NetBeans 5.0 IDE</a>,</li>
       
    77          <li>or <a href="http://ant.apache.org/">Apache Ant 1.6.5</a> and 
       
    78              <a href="http://sourceforge.net/projects/junit/">JUnit 3.8.1 or
       
    79              3.8.2</a><br>
       
    80              (JUnit is only needed to run the example's unit tests).
       
    81          </li>
       
    82      </ul>
       
    83      <p><a name="setup">In order to build the example</a>, 
       
    84      <u>you may need to copy the jmx-scandir</u>
       
    85      directory to somewhere where you have write permissions. 
       
    86      <br>In that case, you will need to update the <i>nbjdk.home</i> variable
       
    87      in the copied <i><a href="build.properties">build.properties</a></i> 
       
    88      file located at the root of the copied project directory. 
       
    89      Please make sure that this variable points to the JDK 6 home directory.
       
    90      </p>
       
    91      <p>If you wish to run the testsuite from within the <a 
       
    92      href="http://www.netbeans.org">NetBeans IDE</a> you will also have
       
    93      to set the <i>libs.junit.classpath</i> variable in 
       
    94      <a href="build.properties">build.properties</a>. 
       
    95      The <i>libs.junit.classpath</i>  variable should point to your
       
    96      <a href="http://sourceforge.net/projects/junit/">junit.jar</a>, 
       
    97      version 3.8.1 or 3.8.2.
       
    98      </p>
       
    99   </blockquote>
       
   100      <hr>
       
   101      <p></p>
       
   102      <p><u>Table Of Contents:</u></p>
       
   103   <p><center>[<a href="#h2-Generating">Generating&nbsp;the&nbsp;Java&nbsp;Documentation</a>]
       
   104   [<a href="#h2-Overview">Overview&nbsp;of&nbsp;the&nbsp;<i>scandir</i>&nbsp;Example</a>]
       
   105   [<a href="#h2-API-Doc">API&nbsp;Documentation&nbsp;and&nbsp;Sources</a>]
       
   106   [<a href="#h2-Patterns">Patterns,&nbsp;Best&nbsp;Practices,&nbsp;and&nbsp;Common&nbsp;Pitfalls</a>]
       
   107   [<a href="#h2-Testing">Testing&nbsp;the&nbsp;<i>scandir</i>&nbsp;Example</a>]
       
   108   [<a href="#h2-Running">Running&nbsp;the&nbsp;<i>scandir</i>&nbsp;Example</a>]
       
   109   [<a href="#h2-Playing">Playing&nbsp;with&nbsp;JConsole</a>]
       
   110   [<a href="#h2-Turning">Turning&nbsp;the&nbsp;example&nbsp;into&nbsp;a&nbsp;Secure&nbsp;JMX&nbsp;Application</a>]
       
   111   [<a href="#h2-Connecting">Connecting&nbsp;to&nbsp;the&nbsp;Secure&nbsp;JMX&nbsp;Application</a>]
       
   112   [<a href="#h2-Conclusion">Conclusion</a>]
       
   113   [<a href="#h2-References">References</a>]</center></p>
       
   114 
       
   115   </ul>
       
   116   <h2><a name="h2-Generating">Generating the Java Documentation</a></h2>
       
   117 
       
   118     <ul>
       
   119         <p>Before reading further, you will need to generate the 
       
   120         Java Documentation for the example's sources.</p>
       
   121         <p>In the example root directory (where the <code>build.xml</code> 
       
   122            file is located) run the following command:
       
   123            <pre>ant javadoc</pre>
       
   124         </p>
       
   125         <p>Alternatively you can open the jmx-scandir project with the 
       
   126            NetBeans IDE and generate the Javadoc from its <code>Build</code>
       
   127            menu.
       
   128         </p>
       
   129         <p>If building the documentation fails, please make sure to read the 
       
   130            <a href="#setup">note</a> at the beginning of this document.</p> 
       
   131     </ul>
       
   132   
       
   133   <h2><a name="h2-Overview">Overview of the <i>scandir</i> Example</a></h2>
       
   134   
       
   135   <ul>
       
   136     <p>The JMX <i>scandir</i> example is built around the
       
   137     following MBeans:</p>
       
   138     <ul>
       
   139         <li>The first MBean we will present here is the
       
   140         <a
       
   141 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   142 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   143         >DirectoryScannerMXBean</a>. <br>A
       
   144         <code>DirectoryScannerMXBean</code> is an MBean that scans a
       
   145         file system starting at a given root directory, and then looks
       
   146         for files that match the given criteria.  When such a file is
       
   147         found, the <code>DirectoryScannerMXBean</code> takes the
       
   148         action for which it was configured: emit a notification,
       
   149         <i>and/or</i> log a <code>record</code> for this file,
       
   150         <i>and/or</i> delete that file. The code that would actually
       
   151         delete the file is commented out - so that nothing valuable is
       
   152         lost if the example is run by mistake on the wrong set of
       
   153         directories.<br> <code>DirectoryScannerMXBeans</code> are
       
   154         created by the <a
       
   155 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   156 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   157         >ScanManagerMXBean</a> - see next item on the list, from its
       
   158         configuration.
       
   159         </li>
       
   160         <li>
       
   161             The <a
       
   162 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   163 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   164             >ScanManagerMXBean</a> is the actual entry point of the
       
   165             application. It reads the application's
       
   166             configuration, and from that configuration,
       
   167             will create a <a
       
   168 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManager.html"
       
   169 title="The ResultLogManager is in charge of managing result logs"
       
   170         >ResultLogManager</a> and some <a
       
   171 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   172 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   173         >DirectoryScannerMXBeans</a>.
       
   174             <br>The <code>ScanManagerMXBean</code> lets you start, stop, and
       
   175             schedule directory scans. The
       
   176             <code>ScanManagerMXBean</code> is a singleton
       
   177             MBean: there can be at most one instance of such
       
   178             an MBean registered in a given MBeanServer.
       
   179         </li>
       
   180         <li>The <a
       
   181 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   182 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   183            >ScanDirConfigMXBean</a> is an MBean which is able to
       
   184            load/save the configuration to/from an XML file. It
       
   185            will also let you modify that configuration - by e.g.
       
   186            creating new directory scanners in there.
       
   187            The corresponding MBeans will be created later, only 
       
   188            when you later
       
   189            ask the <code><a 
       
   190 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   191 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   192              >ScanManagerMXBean</a> </code> to apply the
       
   193            configuration again.<br>
       
   194            The <code>ScanDirConfigMXBean</code> is created by the
       
   195            <code>ScanManagerMXBean</code>, when the
       
   196            <code>ScanManagerMXBean</code> is registered.
       
   197            It is also possible to create an alternate
       
   198            <code>ScanDirConfigMXBean</code>, and to switch the
       
   199            <code>ScanDirConfigMXBean</code> to use one or the other
       
   200            configuration.
       
   201            <br>An example of XML configuration file is given
       
   202            <a href="src/etc/testconfig.xml"
       
   203            title="An Example Of Configuration"
       
   204            >here</a>. Although you could edit such a file by
       
   205            hand, it is easier to do it programmatically (or
       
   206            with <a href="#JConsole">JConsole</a>) through
       
   207            the <code>ScanDirConfigMXBean</code> interface.
       
   208         </li>
       
   209         <li>The <a
       
   210 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   211 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   212         >ResultLogManagerMXBean</a> is in charge of managing result logs.
       
   213         <br>Directory Scanners can be configured to log a
       
   214         <a
       
   215 href="dist/javadoc/com/sun/jmx/examples/scandir/config/ResultRecord.html"
       
   216 title="A ResultRecord contains information about a file matching the criteria of a Directory Scanner"
       
   217         >ResultRecord</a> whenever they take action upon a file that
       
   218         matches their criteria. The <code>ResultLogManagerMXBean</code> is
       
   219         responsible for logging these result records.
       
   220         The <code>ResultLogManagerMXBean</code> can be configured to log
       
   221         such records to a flat file, or into a log held in memory, or
       
   222         both. Both logs (file and memory) can be configured with a
       
   223         maximum capacity. 
       
   224         <br>When the maximum capacity of the memory
       
   225         log is reached, its first entry (i.e. its oldest entry) is
       
   226         removed to make place for the latest one.
       
   227         <br>When the maximum
       
   228         capacity of the file log is reached, the file is
       
   229         renamed by appending a tilde '~' to its name and a
       
   230         new result log is created. 
       
   231         <br>The <code>ResultLogManagerMXBean</code>
       
   232         will let you interactively clear these result logs, change their
       
   233         capacity, and decide where (memory or file) to log.
       
   234         The memory log is useful in that its content can be interactively
       
   235         returned by the <code>ResultLogManagerMXBean</code>, while
       
   236         the file log doesn't have this facility.<br>
       
   237         The result logs are intended to be used by e.g. an offline
       
   238         program that would take some actions on the files that
       
   239         matched the scan criteria:
       
   240         <br>The <i>scandir</i> application
       
   241         could be configured to only produce logs (i.e. takes no
       
   242         action but logging the matching files), and the real
       
   243         action could be performed by another program or module (e.g. mail the result log to the engineer who
       
   244         maintains the lab, or parse that log and delete all the
       
   245         files listed there, or parse the log and prepare and send
       
   246         a single mail to each owner of matching files, containing
       
   247         the list of files they should consider deleting).<br>
       
   248         The <code>ResultLogManagerMXBean</code> is a singleton
       
   249         MBean created by the <code><a 
       
   250 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   251 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   252              >ScanManagerMXBean</a> </code>
       
   253         which reads and writes its configuration from the
       
   254         <code><a
       
   255 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   256 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   257            >ScanDirConfigMXBean</a></code>.
       
   258         </li>
       
   259     </ul>
       
   260     <p>An application <code>main()</code> method is
       
   261        provided in the <a 
       
   262        href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirAgent.html"
       
   263        >ScanDirAgent</a> class. The <code>main()</code> simply registers 
       
   264        a <code><a 
       
   265 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   266 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   267              >ScanManagerMXBean</a> </code> in the platform MBeanServer, and
       
   268        then waits for someone to call <code>close()</code> on the
       
   269        <code>ScanManagerMXBean</code>.
       
   270     </p>
       
   271      <p>When the <code>ScanManagerMXBean</code> is registered, it
       
   272         will create a default <code><a
       
   273 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   274 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   275            >ScanDirConfigMXBean</a></code> bound
       
   276         to a default XML config file.
       
   277      </p>
       
   278      <p>The application's default XML config file is determined as
       
   279         follows:
       
   280         <ol>
       
   281             <li>If the property <code>scandir.config.file</code> is
       
   282                 defined, the default application file will be the
       
   283                 file pointed to by this property. If that file
       
   284                 doesn't exist, it will be created when 
       
   285                 <code>ScanDirConfigMXBean.save()</code> is
       
   286                 invoked.
       
   287             </li>
       
   288             <li>Otherwise the application config file is
       
   289                 assumed to be a file called <code>jmx-scandir.xml</code>,
       
   290                 located in the user's directory (as defined by
       
   291                 the System property <code>user.home</code>). 
       
   292                 If that file doesn't exists, it will be created when 
       
   293                 <code>ScanDirConfigMXBean.save()</code> is
       
   294                 invoked.
       
   295             </li>
       
   296         </ol>
       
   297         <p>It is worth noting that this project is defined to
       
   298            run with the following properties:
       
   299            <pre>-Djava.util.logging.config.file=logging.properties</pre>
       
   300            <pre>-Dscandir.config.file=src/etc/testconfig.xml</pre>
       
   301            With <code>ScanDirAgent</code> defined as the project's
       
   302            main class. Hence when you invoke from the NetBeans IDE 
       
   303            <i>Run Project</i> on the <i>jmx-scandir</i> project, 
       
   304            or <i>Run file</i> on the <code>ScanDirAgent</code>, the
       
   305            application starts with the test configuration provided in
       
   306            <a href="src/etc/testconfig.xml"
       
   307            title="An Example Of Configuration"
       
   308            >src/etc/testconfig.xml</a>
       
   309         </p>
       
   310   </ul>
       
   311   <h2><a name="h2-API-Doc">API Documentation and Sources</a></h2>
       
   312   <ul>
       
   313       <p>Once generated, the Javadoc of example classes can
       
   314       be found starting from <a href="dist/javadoc/index.html"
       
   315       title="The API Documentation"
       
   316       ><code>dist/javadoc/index.html</code></a>.</p>
       
   317       <p>You can view the sources in the <a
       
   318       href="src"
       
   319       title="The Example Source Tree"
       
   320       ><code>src</code></a> subdirectory.</p>
       
   321   </ul>
       
   322   <h2><a name="h2-Patterns">Patterns, Best Practices, and Common Pitfalls</a></h2>
       
   323   <ul>  
       
   324   <p>This section discusses some common patterns and
       
   325      design choices that this example demonstrates, and some pitfalls that
       
   326      it avoids.
       
   327   </ul>
       
   328   <h3>MBeans or MXBeans?</h3>
       
   329   <ul>
       
   330   <p>What is an MXBean? MXBeans made their appearance in
       
   331      J2SE 5.0 (Tiger), with the Management and Monitoring
       
   332      API of the JVM. However, Java SE 6 is the first
       
   333      Java SE release that contains a standard framework which
       
   334      makes it possible to create and register your own MXBeans.
       
   335   </p>
       
   336   <p>MXBeans are a special kind of MBean, which once registered
       
   337      in the MBeanServer, get automatically transformed into
       
   338      OpenMBeans. From a developer point of view, nothing changes:
       
   339      A Wombat MBean can become an MXBean simply by renaming
       
   340      its <code>WombatMBean</code> interface into <code>WombatMXBean</code>.</p>
       
   341   <p>Using MXBeans rather than plain Standard MBean brings its
       
   342      own advantages:</p>
       
   343      <ul>
       
   344          <li>
       
   345              Generic tools, like JConsole, will be able to
       
   346              display and interact with your MXBeans nicely, even
       
   347              if your MXBean interfaces reference custom types
       
   348              - e.g. custom Java enums. This is because all the types
       
   349              exposed by your MXBeans are converted to Open Types.
       
   350              Just look at the <a
       
   351 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   352 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   353              >ScanDirConfigMXBean</a> with JConsole and you will
       
   354              understand the benefits.
       
   355          </li>
       
   356          <li>
       
   357              When writing a programmatic client, you can obtain
       
   358              a proxy that implements the original MXBean interface,
       
   359              and forget about the Open Type conversion.
       
   360              The JUnit unit tests that come with this example
       
   361              use this feature very widely. Have a look at them.
       
   362          </li>
       
   363          <li>
       
   364             The MXBean framework also lets you nicely navigate
       
   365             from one MXBean to another: your MXBeans can
       
   366             have attributes and parameters which are proxies
       
   367             to other MXBeans! We demonstrate this in the
       
   368             <a
       
   369 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   370 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   371             >ScanManagerMXBean</a> which exposes a list
       
   372             of <code><a
       
   373 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   374 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   375         >DirectoryScannerMXBean</a></code> and points
       
   376             towards a <code><a
       
   377 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   378 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   379            >ScanDirConfigMXBean</a></code>.
       
   380          </li>
       
   381      </ul>
       
   382      <p>In short, MXBeans are so much easier to use that
       
   383         this example doesn't even have a single regular
       
   384         Standard MBean.
       
   385      </p>
       
   386      <p>See also <a
       
   387 href="http://weblogs.java.net/blog/emcmanus/archive/2006/02/what_is_an_mxbe.html"
       
   388 title="What is an MXBean?"
       
   389      >What is an MXBean?</a>
       
   390      and <a
       
   391 href="http://weblogs.java.net/blog/emcmanus/archive/2006/06/intermxbean_ref.html"
       
   392 title="Inter-MXBean references"
       
   393      >Inter-MXBean References</a>.
       
   394      </p>
       
   395      <blockquote><u>Hint:</u> In order to simplify the task of coding a 
       
   396         JMX programmatic client, we recommend that getters, setters, and
       
   397         operations defined in MBean and MXBean interfaces throw 
       
   398         <code>IOException</code>. Proxy objects will then be able
       
   399         to rethrow directly any <code>IOException</code> received from
       
   400         their underlying MBean Server connection, without wrapping
       
   401         them into <code>UndeclaredThrowableExceptions</code>.<br>
       
   402         Since the life cycle of the proxy object is not directly tied to 
       
   403         the life cycle of the MBean it proxies, you may also want to
       
   404         have all methods in the MBean or MXBean interface throw
       
   405         <code>InstanceNotFoundException</code> or more generally
       
   406         <code>JMException</code>.
       
   407     </blockquote>
       
   408   </ul>
       
   409   <h3>MBean Names - aka ObjectNames</h3>
       
   410   <ul>
       
   411   <p>As you must know if you've been studying JMX, MBeans are
       
   412      named objects. The names of MBeans are represented by
       
   413      instances of <code>ObjectName</code>. An ObjectName is
       
   414      composed of a <i>domain</i>, followed by a colon ':',
       
   415      followed by a comma-separated list of <i>key=value</i>
       
   416      pairs.<br>
       
   417      The ordering of the <i>key=value</i> pairs is not
       
   418      important, but <code>ObjectNames</code> are case sensitive
       
   419      (both keys and values are case sensitive) and <b>white space
       
   420      is not ignored</b>.<br>
       
   421      A common pitfall for JMX beginners is to inadvertently
       
   422      insert white space after commas into an ObjectName,
       
   423      and expect that two ObjectNames which differ only by such white
       
   424      space will be considered identical. This is not the
       
   425      case.<br>
       
   426      As an example, the ObjectName '<b><code>D:k1=v1, k2=v2, k3=v3</code></b>' has
       
   427      three keys, which are '<b><code>k1</code></b>', '<b><code> k2</code></b>',
       
   428      and '<b><code> k3</code></b>': beware
       
   429      of the space in the name of the second and third
       
   430      keys!<br>
       
   431      It is therefore a different ObjectName from
       
   432      '<b><code>D:k1=v1,k2=v2,k3=v3</code></b>' (the keys are now
       
   433      '<b><code>k1</code></b>', '<b><code>k2</code></b>', and
       
   434      '<b><code>k3</code></b>'), but the same ObjectName as
       
   435      '<b><code>D: k2=v2, k3=v3,k1=v1</code></b>', and yet different
       
   436      from '<b><code>D:k2=v2, k3=v3, k1=v1</code></b>'!
       
   437      <p>In this example, we are following the rules
       
   438         for ObjectName suggested in the <a
       
   439 href="http://java.sun.com/products/JavaManagement/best-practices.html"
       
   440         >JMX Best Practices</a>:</p>
       
   441      <ul>
       
   442          <li>ObjectNames should be <a
       
   443          href="http://java.sun.com/products/JavaManagement/best-practices.html#mozTocId654884"
       
   444          >predictable</a>
       
   445          </li>
       
   446         <li>The domain part of our ObjectNames starts with a Java
       
   447             package name
       
   448         </li>
       
   449         <li>Our ObjectNames contain a <code>type=</code>
       
   450             key property. This property is different for every
       
   451             object type in our domain.
       
   452         </li>
       
   453         <li>For every ObjectName with a given type, we have the same set of key
       
   454             properties with the same syntax and semantics for their values - in
       
   455             fact we only use an additional <code>name=</code> key.
       
   456         </li>
       
   457         <li>When there can only be one instance of a given type
       
   458             there aren't any other key properties than <code>type=</code>.
       
   459             The ObjectNames of the <a
       
   460 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   461 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   462             >ScanManagerMXBean</a> and <a
       
   463 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   464 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   465         >ResultLogManagerMXBean</a>, which are both singleton MBeans, are
       
   466         composed in this way.
       
   467         </li>
       
   468         <li>When there can be several instances of a given type,
       
   469             we differentiate them by further key properties.
       
   470             To achieve this, we are using the most usual key property
       
   471             in addition to <code>type=</code>: the <code>name=</code> key.
       
   472             In this example, a key property list of the form
       
   473             <code>type=X,name=Y</code> is always enough to uniquely name
       
   474             an MBean. Tools like jconsole are usually aware
       
   475             of the semantics of the <code>type=</code> key and
       
   476             <code>name=</code> key, and are therefore able to
       
   477             display this form of name in a way that
       
   478             is easier to read than other name forms.
       
   479         </li>
       
   480      </ul>
       
   481      <p>The rules listed above are implemented by a couple
       
   482         of static helper functions in the <a
       
   483 href="src/com/sun/jmx/examples/scandir/ScanManager.java"
       
   484 title="ScanManager.java"
       
   485       >ScanManager</a> class. See the code of the
       
   486       <b><code>makeSingletonName</code></b> and
       
   487       <b><code>makeMBeanName</code></b> methods.
       
   488      </p>
       
   489   </ul>
       
   490   <h3>Inter MBean Navigation</h3>
       
   491   <ul>
       
   492   <p>One of the most common problems that needs to be solved
       
   493      when designing a management interface with JMX is to
       
   494      choose a representation for inter-MBean relationships.<br>
       
   495      Prior to Java 6, there were basically three possible
       
   496      choices:</p>
       
   497      <ul>
       
   498          <li><b>Make the relation appear in the ObjectName</b>.
       
   499              For instance, if MBean B was contained in
       
   500              MBean A, you could choose to name MBean B so
       
   501              that its parent relationship with MBean A
       
   502              appeared in its name. <br>
       
   503              The obvious limitation of this solution is that
       
   504              it only allows to model one such relation (an
       
   505              MBean has only one name) and the relation must
       
   506              be fixed - it cannot change during the life of
       
   507              the MBean since the name of an MBean cannot
       
   508              change.<br>
       
   509              This scheme is therefore mostly used when
       
   510              the application MBeans are modeling objects
       
   511              which are conceptually contained within
       
   512              each other in a tree-like structure.
       
   513              <br>For instance, most MBean names defined by 
       
   514              <a href="http://jcp.org/en/jsr/detail?id=77"
       
   515               >J2EE Management (JSR 77)</a> follow
       
   516               this scheme.
       
   517          </li>
       
   518          <li><b>Design getters and setters (or operations) which
       
   519              return <code>ObjectName</code> or
       
   520              <code>ObjectName[]</code> values</b>. The ObjectNames
       
   521              point to the MBeans which are related to that
       
   522              object. For instance , <a 
       
   523              href="http://glassfish.dev.java.net/"
       
   524              title="Open Source Java EE 5 Application Server"
       
   525              >GlassFish</a>
       
   526              defines MBeans which also use this pattern.
       
   527          </li>
       
   528          <li><b>Use the JMX RelationService</b>. The JMX RelationService
       
   529              is quite powerful, but simple relationships often
       
   530              do not justify that overhead.
       
   531          </li>
       
   532      </ul>
       
   533      <p>In Java 6, these three possibilities still remain, but
       
   534         the new MXBean framework brings up an interesting
       
   535         alternative. Instead of returning an ObjectName or
       
   536         an ObjectName array, <b>an MXBean can return a proxy</b>
       
   537         to its related MXBeans. This is how we have chosen to
       
   538         implement our inter MBean relationships in this
       
   539         example:
       
   540         <br>For instance the
       
   541         <code>ScanManagerMXBean</code>/<code>DirectoryScannerMXBean</code>
       
   542         relationship and the
       
   543         <code>ScanManagerMXBean</code>/<code>ScanDirConfigMXBean</code>
       
   544         relationships are implemented in this way.
       
   545         <p>
       
   546         The additional benefit, as compared to returning ObjectNames or
       
   547         using the RelationService is that interface type of the MBeans
       
   548         which are pointed to by the relationship becomes directly
       
   549         apparent. The method:
       
   550         <pre>
       
   551             public Map&lt;String,DirectoryScannerMXBean&gt; getDirectoryScanners();
       
   552         </pre>
       
   553         makes it immediately obvious that the MBeans to which we point are
       
   554         <a
       
   555 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   556 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   557         >DirectoryScannerMXBeans</a>. It would have been much less obvious in prior
       
   558         versions of Java SE, were the returned type would have had to be
       
   559         <code>Map&lt;String,ObjectName&gt;</code>, or
       
   560         even worse just <code>Map</code>.
       
   561      </p>
       
   562      <p>However, it must be clear that the behaviour will be
       
   563         quite different when an MXBean is returned as compared
       
   564         to when a simple bean is returned.
       
   565      </p>
       
   566      <p>When an MXBean is returned, the remote client sees either
       
   567         an ObjectName, if it is a generic client like jconsole, or
       
   568         a proxy to a remote MXBean, if the client is working with the
       
   569         MXBean interface. Invoking an operation on one of the
       
   570         proxy returned by a method such as
       
   571         <code>getDirectoryScanners</code> will cause the
       
   572         MBean to be invoked on the remote server side.
       
   573      </p>
       
   574      <p>If <code>getDirectoryScanners</code> were
       
   575         defined as:
       
   576         <pre>
       
   577             public Map&lt;String,DirectoryScannerConfig&gt; getDirectoryScanners();
       
   578         </pre>
       
   579         then invoking a method on one of the returned objects
       
   580         would have absolutely no effect on the remote
       
   581         server side - because the returned objects in this
       
   582         case would simply be a bunch of serialized data objects.
       
   583      </p>
       
   584      <p>It is worth noting that although an MXBean interface
       
   585         can have getters and operations which return an MXBean
       
   586         interface, a regular standard MBean shouldn't have
       
   587         any getters or methods which return MBean interfaces or
       
   588         MXBean interfaces.
       
   589      </p>
       
   590      <p>For more information see also <a
       
   591 href="http://weblogs.java.net/blog/emcmanus/archive/2006/06/intermxbean_ref.html"
       
   592 title="Inter-MXBean references"
       
   593      >Inter-MXBean References</a>.
       
   594      </p>
       
   595   </ul>
       
   596   <h3>The MBeanRegistration interface, or how an MBean can
       
   597       know or provide its own name</h3>
       
   598   <ul>
       
   599       <p>
       
   600         Sometimes, an MBean needs to have a reference to the
       
   601         MBeanServer in which it is registered, or needs to know
       
   602         with which ObjectName it has been registered.
       
   603       </p>
       
   604       <p>
       
   605          Sometimes also, an MBean may need to perform some
       
   606          checks before being registered, or will need
       
   607          to carry out some actions right after it has been 
       
   608          successfully registered in the MBeanServer.
       
   609       </p>
       
   610       <p>
       
   611         Sometimes again, an MBean may need to perform some
       
   612         checks, or some cleaning actions, just before, or
       
   613         just after, it is unregistered.
       
   614       </p>
       
   615       <p>
       
   616       When an MBean has such needs, the easiest solution
       
   617       for it is to implement the <code>MBeanRegistration</code>
       
   618       interface.
       
   619       </p>
       
   620       <p>The <code>MBeanRegistration</code> interface is a callback 
       
   621       interface which defines pre and post registration and 
       
   622       unregistration callbacks.
       
   623       </p>
       
   624       <p>
       
   625        When an MBean implementing this interface is created
       
   626       (with <code>createMBean</code>) or registered 
       
   627       (with <code>registerMBean</code>) in an MBeanServer,
       
   628       the MBeanServer will call the <code>preRegister</code>
       
   629       and <code>postRegister</code> method implemented by
       
   630       the MBean. The <code>preRegister</code> method
       
   631       has an <code>MBeanServer</code> and <code>ObjectName</code>
       
   632       parameter, which are passed by the MBeanServer to the
       
   633       MBean. The MBean can store the reference it is being passed
       
   634       in a private instance variable for later use. 
       
   635       </p>
       
   636       <p>
       
   637       Most of the MXBeans we have defined in this example
       
   638       implement the <code>MBeanRegistration</code> interface. The table
       
   639       below show how our MBeans use this interface to control
       
   640       their own names, make sanity checks, perform 
       
   641       initialization steps or cleanup actions.
       
   642       </p>
       
   643       <p><br><center>
       
   644       <table border="1" cellpadding="4" cellspacing="2" 
       
   645              bgcolor="#eeeeee" width="95%">
       
   646           <thead>
       
   647               <tr bgcolor="#cecece">
       
   648                   <th width="20%">MBean Requirement</th>
       
   649                   <th>callback</th>
       
   650                   <th>use case example</th>
       
   651               </tr>
       
   652           </thead>
       
   653           <tbody>
       
   654               <tr>
       
   655                   <td bgcolor="#dedede">get a reference to the MBeanServer</td>
       
   656                   <td><code>preRegister</code></td>
       
   657                   <td bgcolor="#fafafa">The <a 
       
   658 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   659 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   660              >ScanManagerMXBean</a>  needs a reference
       
   661                   to the MBeanServer in order to create and
       
   662                   register other MBeans, such as the 
       
   663                   <a
       
   664 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   665 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   666         >ResultLogManagerMXBean</a>, and the 
       
   667                   <a
       
   668 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   669 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   670         >DirectoryScannerMXBeans</a>.
       
   671                   </td>
       
   672               </tr>
       
   673               <tr>
       
   674                   <td bgcolor="#dedede">reject registration if conditions are
       
   675                       not met.
       
   676                   </td>
       
   677                   <td><code>preRegister</code></td>
       
   678                   <td bgcolor="#fafafa">The <a 
       
   679 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html"
       
   680 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   681              >ScanManagerMXBean</a>  will throw
       
   682                   an IllegalArgumentException in <code>preRegister</code>
       
   683                   if the ObjectName it is being passed is
       
   684                   illegal. Throwing an exception in 
       
   685                   <code>preRegister</code> makes the registration fail.
       
   686                   </td>
       
   687               </tr>
       
   688               <tr>
       
   689                   <td bgcolor="#dedede">get my client-assigned MBean name</td>
       
   690                   <td><code>preRegister</code></td>
       
   691                   <td bgcolor="#fafafa">The <a
       
   692 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   693 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   694            >ScanDirConfigMXBean</a> propagates the
       
   695                   value of the <code>name=</code> property of 
       
   696                   the ObjectName it is given into its
       
   697                   ScanManagerConfig bean.  
       
   698                   </td>
       
   699               </tr>
       
   700               <tr>
       
   701                   <td bgcolor="#dedede">provide my own default ObjectName if none
       
   702                       was given to the MBeanServer
       
   703                   </td>
       
   704                   <td><code>preRegister</code></td>
       
   705                   <td bgcolor="#fafafa">The name that is returned by <code>preRegister</code>
       
   706                   is the ObjectName with which the MBean will be
       
   707                   eventually registered. 
       
   708                   The <a
       
   709 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   710 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   711            >ScanDirConfigMXBean</a> is able to suggest
       
   712                   a value for its own ObjectName if none was
       
   713                   provided. Similarly, the <a 
       
   714 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   715 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   716              >ScanManagerMXBean</a> 
       
   717                   always returns its singleton ObjectName
       
   718                   defined by <a 
       
   719 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html#SCAN_MANAGER_NAME" 
       
   720 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   721              >ScanManagerMXBean.SCAN_MANAGER_NAME</a>.
       
   722                   </td>
       
   723               </tr>
       
   724               <tr>
       
   725                   <td bgcolor="#dedede">perform initialization steps</td>
       
   726                   <td><code>preRegister</code></td>
       
   727                   <td bgcolor="#fafafa">The <a
       
   728 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   729 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   730            >ScanDirConfigMXBean</a> uses <code>preRegister</code>
       
   731                   to initialize its internal ScanManagerConfig bean.
       
   732                   </td>
       
   733               </tr>
       
   734               <tr>
       
   735                   <td bgcolor="#dedede">perform initialization steps, once it is
       
   736                   known that the registration was successful.
       
   737                   </td>
       
   738                   <td><code>postRegister</code></td>
       
   739                   <td bgcolor="#fafafa">The <code>postRegister</code> method 
       
   740                   can be used to implement
       
   741                   initialization steps that need to be done once it
       
   742                   is known that the registration was successful, or to
       
   743                   undo any action performed by <code>preRegister</code> once it
       
   744                   is known that registration was not successful.
       
   745                   The <code>postRegister</code> method has a Boolean parameter
       
   746                   which tells the MBean whether it was or wasn't
       
   747                   successfully registered in the MBeanServer.
       
   748                   The <a 
       
   749 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   750 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   751              >ScanManagerMXBean</a>  uses <code>postRegister</code> to create
       
   752                   and register other MBeans, such as the 
       
   753                   <a
       
   754 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   755 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   756         >ResultLogManagerMXBean</a> and the default
       
   757                   <a
       
   758 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   759 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   760            >ScanDirConfigMXBean</a>.
       
   761                   Note that <code>postRegister</code> is not expected to throw any
       
   762                   exception. If an exception needs to be thrown, it should
       
   763                   be thrown in <code>preRegister</code>.
       
   764                   </td>
       
   765               </tr>
       
   766               <tr>
       
   767                   <td bgcolor="#dedede">check whether the MBean can be deregistered</td>
       
   768                   <td><code>preDeregister</code></td>
       
   769                   <td bgcolor="#fafafa">The <a 
       
   770 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   771 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   772              >ScanManagerMXBean</a>  uses this method to verify
       
   773                    that its state allows it to be deregistered. 
       
   774                    In particular, it will refuse to be deregistered
       
   775                    if it is in the RUNNING or SCHEDULED state.
       
   776                    If <code>preDeregister</code> throws an exception, the unregisterMBean
       
   777                    call will fail and the MBean will remain registered in
       
   778                    the MBeanServer. 
       
   779                    Take particular care when implementing business logic
       
   780                    in this method: if the logic you implement has an 
       
   781                    unfortunate bug which makes it always throw an 
       
   782                    exception, you will never be able to unregister
       
   783                    that MBean.
       
   784                   </td>
       
   785               </tr>
       
   786               <tr>
       
   787                   <td bgcolor="#dedede">clean up resources, refusing to be deregistered if
       
   788                       it fails
       
   789                   </td>
       
   790                   <td><code>preDeregister</code></td>
       
   791                   <td bgcolor="#fafafa">The <a 
       
   792 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   793 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   794              >ScanManagerMXBean</a>  uses this method to unregister
       
   795                   all the other MBeans it has created and registered in the
       
   796                   MBeanServer. This includes the <a
       
   797 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   798 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   799         >ResultLogManagerMXBean</a>, the 
       
   800                   <a
       
   801 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   802 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   803            >ScanDirConfigMXBeans</a> it has created, and the 
       
   804                   <a
       
   805 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   806 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   807         >DirectoryScannerMXBeans</a> it has created when
       
   808                   applying its configuration.
       
   809                   </td>
       
   810               </tr>
       
   811               <tr>
       
   812                   <td bgcolor="#dedede">clean up resources which need to be released in
       
   813                   a best-effort way, when it is known that the MBean is no
       
   814                   longer registered.
       
   815                   </td>
       
   816                   <td><code>postDeregister</code></td>
       
   817                   <td bgcolor="#fafafa"><code>postDeregister</code> is only called if the MBean was succesfully
       
   818                   unregistered.
       
   819                   The <a 
       
   820 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   821 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   822              >ScanManagerMXBean</a>  uses this method to cancel
       
   823                   its internal java.util.Timer.
       
   824                   </td>
       
   825               </tr>
       
   826           </tbody>
       
   827       </table>
       
   828       </center><br></p>
       
   829   </ul>
       
   830   <h3>The Singleton MBean Pattern</h3>
       
   831   <ul>
       
   832       <p>
       
   833         A singleton MBean is an MBean which can only have one
       
   834         instance registered in a given MBeanServer. <br>
       
   835         A singleton MBean usually has a well-known name,
       
   836         which can be defined as a constant. In that case,
       
   837         clients no longer need to call <code>new ObjectName(...)</code> 
       
   838         and catch the declared <code>MalformedObjectNameException</code>.
       
   839       </p>
       
   840       <p>There are already quite a few examples of singleton
       
   841          MBeans in the java.lang.management API. The 
       
   842          ThreadingMXBean, ClassLoadingMXBean, RuntimeMXBean, etc.
       
   843          are all singleton MBeans.
       
   844       </p>
       
   845       <p>In this example, we have two singleton MBeans:
       
   846          The <code><a 
       
   847 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   848 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   849              >ScanManagerMXBean</a></code> and the 
       
   850          <code><a
       
   851 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   852 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   853         >ResultLogManagerMXBean</a></code>. But in fact,
       
   854          the only real singleton MBean is the 
       
   855         <code>ScanManagerMXBean</code>. The 
       
   856         <code>ResultLogManagerMXBean</code> just happens to
       
   857         be a singleton MBean because it has a 1-1 relationship
       
   858         with the <code>ScanManagerMXBean</code>.
       
   859       </p>
       
   860       <p>The <code>ScanManagerMXBean</code> implements the
       
   861          singleton MBean pattern in this way:
       
   862       </p>
       
   863       <ul>
       
   864           <li>The <code>ScanManagerMXBean</code> name has a single 
       
   865               key property: <code>type=ScanManagerMXBean</code>.</li>
       
   866           <li>Its name is defined by an ObjectName constant called
       
   867               <code>SCAN_MANAGER_NAME</code> in the <code>ScanManager</code> class</li>
       
   868           <li>The <code>ScanManagerMXBean</code> enforces its status of 
       
   869               singleton MBean. It will refuse to be registered
       
   870               with a name other than
       
   871               the <code>SCAN_MANAGER_NAME</code>. You can therefore depend on
       
   872               the fact that the <code>ScanManagerMXBean</code> will always 
       
   873               be registered with its singleton <code>SCAN_MANAGER_NAME</code>
       
   874               (see <code>preRegister</code>)
       
   875           </li>
       
   876           <li>You are not obliged to provide a name when you
       
   877               register the <code>ScanManagerMXBean</code>: if you pass null,
       
   878               then the <code>ScanManager</code> will be registered with
       
   879               its singleton <code>SCAN_MANAGER_NAME</code>
       
   880               (see <code>preRegister</code>).
       
   881           </li>
       
   882           <li>The <code>ScanManager</code> class has a no-arg static 
       
   883               <code>register</code> method that will register
       
   884               the singleton instance in the Platform MBeanServer.
       
   885               This static <code>register</code> method returns
       
   886               a proxy to the registered singleton.
       
   887           </li>
       
   888           <li>The <code>ScanManager</code> class has also a static 
       
   889               <code>register</code> method that will create
       
   890               a singleton instance in a (possibly remote)
       
   891               MBeanServerConnection - using 
       
   892               <code>createMBean</code>.
       
   893               This static <code>register</code> method 
       
   894               also returns a proxy to the registered singleton.
       
   895           </li>
       
   896           <li>Only the MBeanServer has a reference to the
       
   897               singleton instance. The singleton instance is
       
   898               not returned to the caller, and not kept
       
   899               in any other static data structure.
       
   900           </li>
       
   901       </ul>
       
   902       <p>
       
   903       On the other hand, the <code><a
       
   904 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   905 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   906         >ResultLogManagerMXBean</a></code>
       
   907       has a much more relaxed implementation of the pattern:
       
   908       <br>It simply provides its own singleton name if it is
       
   909       registered with a null ObjectName, but will not enforce 
       
   910       the use of that name.
       
   911       </p>
       
   912       <p>Note that all singleton MBean names in this example
       
   913       are created using the <code>ScanManager.makeSingletonName</code>
       
   914       method, which implements the pattern for ObjectNames suggested
       
   915       in the JMX Best Practices.
       
   916       </p>
       
   917   </ul>
       
   918   <h3>Managing the Life Cycle of dependent MBeans</h3>
       
   919   <ul>
       
   920       <p>A common task that many JMX applications have
       
   921         is to manage the life cycle of MBeans registered
       
   922         in the MBeanServer.</p>
       
   923       <p>In this example, we have decided to follow a simple
       
   924       pattern:</p>
       
   925       <ul>
       
   926           <li>The application is initialized simply 
       
   927               by registering the singleton 
       
   928               <a 
       
   929 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
   930 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
   931              >ScanManagerMXBean</a> in 
       
   932               the MBeanServer.
       
   933           </li>
       
   934           <li>The <code>ScanManagerMXBean</code> will then
       
   935               in turn register any other MBean that the 
       
   936               application might need:
       
   937               <ul>
       
   938                   <li>It creates and registers the singleton
       
   939                       <code><a
       
   940 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
   941 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
   942         >ResultLogManagerMXBean</a></code>
       
   943                   </li>
       
   944                   <li>It creates and registers the default
       
   945                       <code><a
       
   946 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
   947 title="The ScanDirConfigMXBean is in charge of the configuration"
       
   948            >ScanDirConfigMXBean</a></code>
       
   949                       which loads the initial configuration
       
   950                   </li>
       
   951                   <li>It creates as many 
       
   952                      <code><a
       
   953 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
   954 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
   955         >DirectoryScannerMXBeans</a></code> as
       
   956                      needed when the configuration is applied
       
   957                   </li>
       
   958                   <li>It lets you create alternate 
       
   959                       <code>ScanDirConfigMXBean</code>, to
       
   960                       which you can later switch in order
       
   961                       to apply a new alternate configuration.
       
   962                   </li>
       
   963               </ul>
       
   964           </li>
       
   965           <li>When a new configuration is applied (or if the
       
   966               current configuration is reapplied), the 
       
   967               <code>ScanManagerMXBean</code> will unregister
       
   968               any <code>DirectoryScannerMXBeans</code> it has
       
   969               previously registered, and will re-create
       
   970               brand new <code>DirectoryScannerMXBeans</code>
       
   971               from the applied configuration.
       
   972           </li>
       
   973           <li>When you unregister the <code>ScanManagerMXBean</code>,
       
   974               it does all the cleanup for you, by unregistering
       
   975               all the MBeans that it has created during the
       
   976               course of the application.
       
   977           </li>
       
   978       </ul>
       
   979       <p>The <code>ScanManagerMXBean</code> makes use of its
       
   980          <code>MBeanRegistration</code> interface in order
       
   981          to register the other MBeans it needs (see the
       
   982          <code>ScanManager.postRegister</code> method) and to unregister
       
   983          every MBean it has created (see the <code>ScanManager.preDeregister</code>
       
   984          method).
       
   985       </p>
       
   986       <p>You will note that the <code>ScanManagerMXBean</code>
       
   987          will only allow itself to be deregistered if it can be 
       
   988          closed - that is if there's no other action in
       
   989          progress. 
       
   990          This is to make sure that the deregistration of
       
   991          dependent MBeans will work smoothly. 
       
   992          <br>
       
   993          The deregistration of related MBeans will happen
       
   994          in the <code>ScanManager.preDeregister</code>
       
   995          method.
       
   996          <br>
       
   997          If one of these MBeans could not be deregistered,
       
   998          then the <code>ScanManagerMXBean</code> will throw
       
   999          an exception, refusing to be deregistered.
       
  1000          <br>This leaves you a chance to try to deregister it
       
  1001          again later. Since the <code>ScanManagerMXBean</code>
       
  1002          has switched its state to CLOSED before starting
       
  1003          to unregister its dependent MBeans, it will refuse
       
  1004          any further actions, ensuring that e.g. nobody
       
  1005          can try to start it or schedule it while it
       
  1006          is in that partially-deregistered state.
       
  1007       </p>
       
  1008       <p>Handling the LifeCycle of all the application's
       
  1009          MBeans in a single MBean is usually a good design
       
  1010          pattern, especially if the application is a 
       
  1011          module which is intended to share a JVM - or
       
  1012          an MBeanServer - with other modules.
       
  1013       </p>
       
  1014       <p>This is specially useful if the application needs to
       
  1015          be loaded and unloaded on demand: in that 
       
  1016          case, simply registering or unregistering the top level 
       
  1017          MBean (in our example the <code>ScanManagerMXBean</code>) does
       
  1018          the trick.
       
  1019       </p>
       
  1020   </ul>
       
  1021   <h3>Emitting Notifications</h3>
       
  1022   <ul>
       
  1023        <p>In order to emit notifications, an MBean must be
       
  1024        an instance of <code>NotificationEmitter</code>. 
       
  1025        The <code>NotificationEmitter</code> interface defines methods 
       
  1026        that the MBeanServer will call on the MBean in order
       
  1027        to register <code>NotificationListeners</code> with the MBean.
       
  1028        </p>
       
  1029        <p>It is worth noting that the MBean may not be
       
  1030           invoked each time a JMX client wants to register
       
  1031           a listener. For instance, the RMIConnectorServer
       
  1032           registers <i>only once</i> a single listener with each MBean 
       
  1033           which is a <code>NotificationEmitter</code>.
       
  1034           In that specific case, the listener may even be registered
       
  1035           with the MBean before any client has actually subscribed
       
  1036           for notifications from that particular MBean.
       
  1037        </p>
       
  1038        <p>An MBean can therefore make no assumption about 
       
  1039           which client or how many clients have registered for
       
  1040           notifications.
       
  1041        </p>
       
  1042        <p>It is also worth noting that the logic of the
       
  1043        methods defined in <code>NotificationEmitter</code> would not
       
  1044        be trivial to implement from scratch. Fortunately
       
  1045        the JMX API defines a helper class, called 
       
  1046        <code>NotificationBroadcasterSupport</code>, which 
       
  1047        provides an implementation for these methods.
       
  1048        </p>
       
  1049        <p>There are actually three ways for an MBean to
       
  1050        implement <code>NotificationEmitter</code>, of which only two
       
  1051        are recommended.
       
  1052        </p>
       
  1053   </ul>
       
  1054 
       
  1055   <h4>Extending NotificationBroadcasterSupport</h4>
       
  1056   <ul>
       
  1057     <p>This is the simplest way of coding an MBean which
       
  1058        is a <code>NotificationEmitter</code>:
       
  1059     </p>
       
  1060     <p>Simply extend <code>NotificationBroadcasterSupport</code>,
       
  1061     then override its <code>getNotificationInfo</code> method
       
  1062     which returns the <code>MBeanNotificationInfo[]</code> array
       
  1063     that should be included in your MBean's <code>MBeanInfo</code>
       
  1064     and that's it. 
       
  1065     <br>You just need to call the <code>sendNotification</code> method
       
  1066     inherited from <code>NotificationBroadcasterSupport</code> whenever
       
  1067     your MBean needs to send a notification.
       
  1068     </p>
       
  1069     <p>In our example, both the <a
       
  1070 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
  1071 title="The ScanDirConfigMXBean is in charge of the configuration"
       
  1072            >ScanDirConfigMXBean</a> and <a
       
  1073 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
  1074 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
  1075         >ResultLogManagerMXBean</a> extend 
       
  1076       <code>NotificationBroadcasterSupport</code> in order
       
  1077       to send notifications.
       
  1078     </p>
       
  1079   </ul>
       
  1080   <h4>The Delegation Pattern: delegating to a 
       
  1081       NotificationBroadcasterSupport delegate</h4>
       
  1082   <ul>
       
  1083       <p>There may be cases however where delegating to a
       
  1084       wrapped <code>NotificationBroadcasterSupport</code> 
       
  1085       object may be preferred to extending 
       
  1086       <code>NotificationBroadcasterSupport</code>.
       
  1087       </p>
       
  1088       <p>For instance, if your MBeans already derive from
       
  1089       some base class, extending <code>NotificationBroadcasterSupport</code>
       
  1090       might not be an option.
       
  1091       </p>
       
  1092       <p>Similarly, if you do not want to have the inherited 
       
  1093       <code>public void sendNotification(Notification notification)</code>
       
  1094       method appear in the Javadoc of the concrete class of your
       
  1095       MBean, you may want to consider using the delegation
       
  1096       pattern instead of extending 
       
  1097       <code>NotificationBroadcasterSupport</code>
       
  1098       </p>
       
  1099       <p>In our example both the <a 
       
  1100 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1101 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1102              >ScanManagerMXBean</a> and the <a
       
  1103 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
  1104 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
  1105         >DirectoryScannerMXBean</a> use the delegation 
       
  1106        pattern rather than extending 
       
  1107        <code>NotificationBroadcasterSupport</code>.
       
  1108        In the end, choosing between one or the other method
       
  1109        is more a question of taste, although the delegation 
       
  1110        pattern could be considered more flexible since it
       
  1111        doesn't require extending any given superclass.
       
  1112       </p>
       
  1113       <p>It may be also worth noting that some tools like
       
  1114       the JMX Module of <a 
       
  1115 href="http://www.netbeans.org"
       
  1116       >NetBeans IDE</a>, will be able to 
       
  1117       generate for you all the code that delegates to a
       
  1118       wrapped <code>NotificationBroadcasterSupport</code>.
       
  1119       </p>
       
  1120   </ul>
       
  1121       
       
  1122   <h4>Implementing NotificationEmitter from scratch</h4>
       
  1123   <ul>
       
  1124     <p>This is the last possibility for an MBean that
       
  1125     needs to send notifications: simply implement 
       
  1126     <code>NotificationEmitter</code> from scratch. This is highly
       
  1127     discouraged since that logic is not trivial, and 
       
  1128     already provided by 
       
  1129     <code>NotificationBroadcasterSupport</code> anyway.
       
  1130     </p>
       
  1131   </ul>
       
  1132     
       
  1133   <h4>Beware of Synchronization Locks</h4>
       
  1134   <ul>
       
  1135        
       
  1136        <p>One thing you must keep in mind when sending
       
  1137        notifications is not to send them from within
       
  1138        a synchronized block, or while holding a lock on
       
  1139        some resource.</p>
       
  1140        <p>Indeed, what happens when you send a notification
       
  1141           may vary greatly depending on whether the client
       
  1142           which has registered for notifications has done
       
  1143           so through a <code>JMXConnector</code> (like the 
       
  1144           <code>JMXRMIConnector</code>)
       
  1145           or through a direct reference to the MBeanServer
       
  1146           (by calling 
       
  1147           <code>MBeanServer.addNotificationListener</code>).
       
  1148        </p>
       
  1149        <p>In this latter case, the listener will be invoked
       
  1150        synchronously in the same thread that your MBean is
       
  1151        using to send its notification. If by misfortune, the
       
  1152        code of that listener now re-enters your MBean through a
       
  1153        call that flows through a JMXConnector, a deadlock
       
  1154        could occur. It is therefore very important to release
       
  1155        any lock you may have before calling 
       
  1156        <code>sendNotification</code>.</p>
       
  1157        <p>An easy way to do that is demonstrated in the
       
  1158           <code>ScanManager</code> class. The ScanManager
       
  1159           has an internal private queue of pending notifications.
       
  1160           When a notification needs to be sent (e.g. because the
       
  1161           ScanManager state is being switched), the notification
       
  1162           is simply prepared and put into the pending notification
       
  1163           queue. 
       
  1164           The notification queue is then processed later on, 
       
  1165           at the end of the method, when the processing is finally
       
  1166           completed and all the locks have been released.
       
  1167           <br>At this point the notification queue might already
       
  1168           have been emptied by another thread - in which case
       
  1169           the pending notifications will have already been
       
  1170           removed from the queue. Which thread actually gets 
       
  1171           to send the notifications is of no importance. The 
       
  1172           important point is that all the locks detained by
       
  1173           your MBean code in that thread were released before
       
  1174           the notification was sent.
       
  1175        </p>
       
  1176        <p>In our example the <code>ScanManager</code> class 
       
  1177           ensures this by:
       
  1178           <ul>
       
  1179               <li>Only calling <code>sendNotification</code>
       
  1180                   in its private <code>sendQueuedNotifications</code>
       
  1181                   method.
       
  1182               </li>
       
  1183               <li>Only calling <code>sendQueuedNotifications</code>
       
  1184                   when all locks have been released.
       
  1185               </li>
       
  1186               <li>Never calling a method that calls 
       
  1187                   <code>sendQueuedNotifications</code> from within
       
  1188                   a synchronized block.</li>
       
  1189           </ul>
       
  1190        </p>
       
  1191   </ul>
       
  1192        
       
  1193        
       
  1194 
       
  1195   <h4>Don't subclass Notification</h4>
       
  1196   <ul>
       
  1197        <p>Another common best practice when you want
       
  1198           to improve interoperability is to use directly
       
  1199           the Notification base classes provided in the
       
  1200           JMX<sup>TM</sup> API. Do not create your own
       
  1201           subclasses of these standard classes.
       
  1202        </p>
       
  1203        <p>Indeed, if you code your own subclass, a generic
       
  1204        client, like jconsole, will not be able to receive
       
  1205        that notification unless it has that custom 
       
  1206        subclass in its classpath.
       
  1207        </p>
       
  1208        <p>
       
  1209        If you want your application to be interoperable, it is
       
  1210        therefore preferable not to subclass any of the standard
       
  1211        Notification classes. You can define your own 
       
  1212        Notification type string, and if you need to send
       
  1213        additional data, you can put a CompositeData, or a 
       
  1214        HashMap of serializable standard types in the 
       
  1215        Notification's user data fields.
       
  1216        </p>
       
  1217        <p>In this example, we are using directly the 
       
  1218        standard notification classes:
       
  1219        <ul>
       
  1220            <li>The <a 
       
  1221 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1222 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1223              >ScanManagerMXBean</a> and the <a
       
  1224 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
  1225 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
  1226              >DirectoryScannerMXBean</a> both use directly
       
  1227              <code>AttributeChangeNotification</code> to notify
       
  1228              changes in their <code>State</code> attribute.
       
  1229            </li>
       
  1230            <li>The <a
       
  1231 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
  1232 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
  1233              >DirectoryScannerMXBean</a>
       
  1234              also uses the base <code>Notification</code>
       
  1235              class directly in order to notify whenever
       
  1236              it finds a matching file.
       
  1237              <br>In that case, we simply use the base
       
  1238              <code>Notification</code>
       
  1239              class with a new 
       
  1240              <b><code>com.sun.jmx.examples.scandir.filematch</code></b>
       
  1241              type.
       
  1242            </li>
       
  1243            <li>The <a
       
  1244 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
  1245 title="The ScanDirConfigMXBean is in charge of the configuration"
       
  1246              >ScanDirConfigMXBean</a> and <a
       
  1247 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html"
       
  1248 title="The ResultLogManagerMXBean is in charge of managing result logs"
       
  1249              >ResultLogManagerMXBean</a> also both use the base 
       
  1250              <code>Notification</code> class.
       
  1251            </li>
       
  1252        </ul>
       
  1253        <p>Careful readers will have noted that the <a 
       
  1254 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1255 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1256              >ScanManagerMXBean</a> and the <a
       
  1257 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html"
       
  1258 title="A DirectoryScannerMXBean looks for file matching a given set of criteria, starting at a given root."
       
  1259              >DirectoryScannerMXBean</a> both use the 
       
  1260              <code>AttributeChangeNotification</code> class
       
  1261              to notify about their state change, whereas the
       
  1262              <a
       
  1263 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
  1264 title="The ScanDirConfigMXBean is in charge of the configuration"
       
  1265              >ScanDirConfigMXBean</a> uses the base
       
  1266              <code>Notification</code> class.
       
  1267        </p>
       
  1268        <p>In fact, this is because the semantics of these
       
  1269           notifications is not exactly the same - although
       
  1270           both denote a state change:
       
  1271           <ul>
       
  1272               <p>In the case of <code>ScanManagerMXBean</code>
       
  1273               and <code>DirectoryScannerMXBean</code>, the 
       
  1274               notification which is emitted is more about a
       
  1275               state transition, from one state to another.
       
  1276               For instance, going from <code>RUNNING</code>
       
  1277               to <code>STOPPED</code>, or from 
       
  1278               <code>SCHEDULED</code> to <code>STOPPED</code>.
       
  1279               <br>In that case, the 
       
  1280               <code>AttributeChangeNotification</code> was
       
  1281               more appropriate because it made it possible
       
  1282               to send the previous and the new value of the 
       
  1283               state attribute, thus reflecting the whole
       
  1284               state transition.
       
  1285               </p>
       
  1286               <p>In the case of the <code>ScanDirConfigMXBean</code>
       
  1287               however, what is of interest is the state in
       
  1288               which the MBean has arrived. Using the base
       
  1289               <code>Notification</code> class with three different 
       
  1290               notification type strings -  
       
  1291               <b><code>com.sun.jmx.examples.scandir.config.loaded</code></b>,
       
  1292               <b><code>com.sun.jmx.examples.scandir.config.modified</code></b>,
       
  1293               and
       
  1294               <b><code>com.sun.jmx.examples.scandir.config.saved</code></b> - 
       
  1295               was therefore closer to what we wanted to model.
       
  1296               </p>
       
  1297           </ul>
       
  1298        </p>
       
  1299   </ul>
       
  1300        
       
  1301   <h3>Configuration MBeans</h3>
       
  1302     <ul>
       
  1303     <p>A common practice when designing a management application is
       
  1304     to have an MBean, or a set of MBeans, dedicated to configuration. 
       
  1305     Separating configuration from control and monitoring allows
       
  1306     more appropriate logic, and often simplifies the design and 
       
  1307     implementation of the management interface.
       
  1308     </p>
       
  1309     <p>
       
  1310     In our example, the <a
       
  1311 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
  1312 title="The ScanDirConfigMXBean is in charge of the configuration"
       
  1313      >ScanDirConfigMXBean</a> is dedicated to the application configuration.
       
  1314     </p>
       
  1315     <p>The <code>ScanDirConfigMXBean</code> will let you interactively 
       
  1316         modify, save, or load the application configuration. The modifications
       
  1317         will not be taken into account until it is applied, by invoking
       
  1318         <code>applyConfiguration</code> on the <a 
       
  1319 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1320 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1321         >ScanManagerMXBean</a>. 
       
  1322     It is also possible to create many configurations, by creating as
       
  1323     many <code>ScanDirConfigMXBean</code>s, and then to choose and apply
       
  1324     one of these configurations by calling 
       
  1325     <code>ScanManagerMXBean.setConfigurationMBean</code> and then
       
  1326     <code>ScanManagerMXBean.applyConfiguration</code>.
       
  1327     </p>
       
  1328     <p>In this way, all configurations aspects are gathered and concentrated
       
  1329     inside the <code>ScanDirConfigMXBean</code> instead of being scattered
       
  1330     throughout all the MBeans that compose the application.
       
  1331     </p>
       
  1332     <p>In order to save and store the application configuration data, the
       
  1333     <code>ScanDirConfigMXBean</code> uses a set of XML serializable Java beans
       
  1334     defined in the <a 
       
  1335 href="dist/javadoc/com/sun/jmx/examples/scandir/config/package-summary.html" 
       
  1336 title="The com.sun.jmx.examples.scandir.config package defines XML serializable beans"
       
  1337         >com.sun.jmx.examples.scandir.config</a> package. These beans are very
       
  1338    simple Java beans which have been lightly annotated for XML binding.
       
  1339     </p>
       
  1340     <p>It is worth noting that these same beans can also be handled by the
       
  1341     MXBean framework (our beans don't contain recursive data structures) and can 
       
  1342     therefore be used directly as attributes and parameters of MXBeans, without
       
  1343     needing to be Java-serializable (the MXBean framework transform them in
       
  1344     CompositeData objects - which <b>are</b> serializable).
       
  1345     </p>
       
  1346     <p>The same <a 
       
  1347 href="dist/javadoc/com/sun/jmx/examples/scandir/config/ScanManagerConfig.html" 
       
  1348 title="The com.sun.jmx.examples.scandir.config package defines XML serializable beans"
       
  1349         >ScanManagerConfig</a> bean that we use to read from and write to the
       
  1350         XML configuration file is thus also used as attribute of the <a
       
  1351 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html"
       
  1352 title="The ScanDirConfigMXBean is in charge of the configuration"
       
  1353      >ScanDirConfigMXBean</a>. It is transformed into a <code>CompositeData</code> 
       
  1354        by the MXBean framework, and can be easily introspected with
       
  1355        <a href="#JConsole">jconsole</a>.
       
  1356     </p>
       
  1357     </ul>
       
  1358   <h3>MBeans Must Be Thread-Safe</h3>
       
  1359     <ul>
       
  1360     <p>A question often asked by newcomers to JMX technology
       
  1361     is whether the MBeanServer is thread-safe. Well, the MBeanServer <b>is</b> 
       
  1362     thread safe, but it doesn't put any locks on the MBeans it contains. The
       
  1363     MBeans can be concurrently accessed by multiple threads, and must therefore
       
  1364     take care of their own thread safety.
       
  1365     </p>
       
  1366     <p>In this example, we have been using two methods to ensure thread
       
  1367     safety for our MBeans: synchronized blocks, and semaphores.
       
  1368     </p>
       
  1369     <p>Using synchronized blocks is probably the most common and easiest way
       
  1370     to implement thread safety in Java. When dealing with MBeans though, here
       
  1371     are a couple of rules to keep in mind:
       
  1372     <ul>
       
  1373         <li>Don't send notifications from within a synchronized block: there's
       
  1374         no way to tell whether the listener's code will be executed in the
       
  1375         same thread or a different thread, and holding a lock in these
       
  1376         conditions is therefore dangerous, as it could lead to deadlocks.</li>
       
  1377         <li>Also avoid invoking another MBean from a synchronized block
       
  1378         unless you are completely in control of both MBeans, and you can
       
  1379         ascertain that it won't lead to any deadlock. Indeed, if you invoke an
       
  1380         MBean exposed by another application, it can be sometime hard to
       
  1381         know with certainty whether holding a lock while invoking that
       
  1382         MBean will have any side effect. Maybe that MBean will make
       
  1383         further calls to other MBeans which will in turn try to call
       
  1384         your MBean, or maybe it will emit a
       
  1385         notification, and we'll be back to the considerations just 
       
  1386         above.</li>
       
  1387     </ul>
       
  1388     </p>
       
  1389     <p>Another means of implementing thread-safe code is to use semaphores.
       
  1390     The <a 
       
  1391 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1392 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1393         >ScanManagerMXBean</a> uses a semaphore called
       
  1394         <code>sequencer</code> to ensure
       
  1395     that critical code sections are not executed concurrently. In this
       
  1396     MBean, we use <code>Semaphore.tryAcquire</code> to lock the sequencer
       
  1397     semaphore before entering the critical section. If the 
       
  1398     <code>Semaphore.tryAcquire</code> returns true then we enter the critical
       
  1399     section. If it returns false, we throw an IllegalStateException, stating
       
  1400     that we couldn't acquire the lock. The code looks like this:
       
  1401     <pre>
       
  1402         if (!sequencer.tryAcquire())
       
  1403             throw new IllegalStateException("resource locked");
       
  1404         try {
       
  1405             // critical code here ...
       
  1406         } finally {
       
  1407             // Always use try/finally to ensure that the semaphore
       
  1408             // will be released, even if exceptions or errors are raised!
       
  1409             sequencer.release();
       
  1410         }
       
  1411     </pre>
       
  1412     </p>
       
  1413     <p>Using <code>Semaphore.tryAcquire</code> and throwing an exception if
       
  1414         the semaphore is already locked makes it safer to call other MBeans
       
  1415         from within the critical section: in potential deadlock situations
       
  1416         the calling code will get the <code>IllegalStateException</code>
       
  1417         instead of being blocked on the deadlocked lock.
       
  1418     </p>
       
  1419     <p>It is worth noting that each of these techniques has its own 
       
  1420     advantages and disadvantages - which can make one of them more or less
       
  1421     appropriate depending on the inner logic of the MBean you're implementing.
       
  1422     </p>
       
  1423     <p>Careful readers will also have noted that we used 
       
  1424        <code>IllegalStateException</code> directly, instead of defining 
       
  1425        our own subclass of RuntimeException, which could have had a more
       
  1426        precise semantics. If you define a new exception for your JMX application,
       
  1427        you must keep in mind that your client will need to have the class
       
  1428        of your exception in its classpath to get that exception. 
       
  1429        Otherwise your client will get a completely different exception, indicating a
       
  1430        deserialization issue.
       
  1431     </p>
       
  1432     </ul>
       
  1433     
       
  1434   <h3>Waiting for Notifications</h3>
       
  1435     <ul>
       
  1436     <p>Implementing code that needs to wait for notifications is sometimes
       
  1437        difficult. Because notifications are asynchronous, doing something
       
  1438        like:
       
  1439         <pre>
       
  1440           // register a notification listener
       
  1441           ...
       
  1442           // start a management action
       
  1443           ...
       
  1444           // wait for a notification
       
  1445           ...
       
  1446           // do something based on whether the expected notification
       
  1447           // is received
       
  1448           ...
       
  1449         </pre>
       
  1450        is not always trivial. However, there's a very easy way to do that: use
       
  1451        a blocking queue of notifications.
       
  1452        <pre>
       
  1453        final BlockingQueue&lt;Notification&gt; notifQueue = 
       
  1454                 new LinkedBlockingQueue&lt;Notification&gt;();
       
  1455                 
       
  1456        final NotificationListener listener = new NotificationListener() {
       
  1457             public void handleNotification(Notification notification,
       
  1458                                            Object handback) {
       
  1459                 try {
       
  1460                     // Just put the received notification in the queue.
       
  1461                     // It will be consumed later on.
       
  1462                     //
       
  1463                     notifQueue.put(notification);
       
  1464                 } catch (InterruptedException ex) {
       
  1465                     // OK
       
  1466                 }
       
  1467             }
       
  1468           };
       
  1469 
       
  1470        // register the listener - possibly also as a JMXConnectionNotification
       
  1471        // listener to get Notification Lost notification
       
  1472        ...
       
  1473        // start management action
       
  1474        ...
       
  1475        // wait for notification
       
  1476        while (expected notif not received and delay not expired) {
       
  1477             Notification n = notifQueue.poll(3,TimeUnit.SECONDS);
       
  1478             // if expected notif, do something
       
  1479             ...
       
  1480        }
       
  1481        // if expected notification not received do something else.
       
  1482        ....
       
  1483        </pre>
       
  1484     </p>
       
  1485     <p>You will note that this is a technique we've been using in the <a 
       
  1486 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirAgent.html" 
       
  1487 title="The ScanDirAgent class defines a main method for the scandir application"
       
  1488         >ScanDirAgent</a> class and in the example unit tests.
       
  1489     </p>
       
  1490     </ul>
       
  1491     
       
  1492   <h3>Holding hard references to other MBeans: proxy or direct reference?</h3>
       
  1493   <ul>
       
  1494     <p>We have seen that MXBeans will let you return proxy references to other
       
  1495     MXBeans. But should that MXBean hold a direct reference to the MXBeans it
       
  1496     relates to, or would it be better for it to hold only a proxy?
       
  1497     </p>
       
  1498     <p>
       
  1499     As a general rule it is better when an MBean reference is
       
  1500     only held by the MBeanServer. It is a better design
       
  1501     to hold a reference to a proxy, rather than to hold
       
  1502     a hard reference to an MBean. However there are two cases
       
  1503     when holding a hard reference might be preferred: 
       
  1504      <ol>
       
  1505         <li>When MBean A needs to call a method of method B which
       
  1506            is not part of its MBean interface</li>
       
  1507         <li>When the overhead of going through the MBeanServer
       
  1508            plus the MXBean framework is too great (frequently-called
       
  1509            method, with creation of OpenType)</li>
       
  1510      </ol>
       
  1511     However - holding a hard reference is only advisable
       
  1512     when both MBeans are created by the same piece of code,
       
  1513     and the application can ensure that the life cycle
       
  1514     of each MBean is consistent with regard to the other.
       
  1515     </p>
       
  1516     <p>In our example, the <a 
       
  1517 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1518 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1519         >ScanManagerMXBean</a> holds only proxy references to the <a 
       
  1520 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirConfigMXBean.html" 
       
  1521         >ScanDirConfigMXBean</a> and the  <a 
       
  1522 href="dist/javadoc/com/sun/jmx/examples/scandir/DirectoryScannerMXBean.html" 
       
  1523         >DirectoryScannerMXBeans</a>. <br>
       
  1524     However it holds a direct reference to the <a 
       
  1525 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManager.html" 
       
  1526         >ResultLogManager</a>. This makes it possible to pass a direct 
       
  1527         reference to the <code>DirectoryScannerMXBeans</code>, 
       
  1528         which can then log their results
       
  1529         more efficiently, and would also make it possible to remove
       
  1530         the <code>log</code> method from the <a 
       
  1531 href="dist/javadoc/com/sun/jmx/examples/scandir/ResultLogManagerMXBean.html" 
       
  1532         >ResultLogManagerMXBean</a> interface - leaving it in the 
       
  1533         <code>ResultLogManager</code> class (possibly as a package method)
       
  1534         should we wish to do so.
       
  1535     </p>
       
  1536     
       
  1537     </ul>
       
  1538 
       
  1539   <h3>Agent Class</h3>
       
  1540     <ul>
       
  1541    <p>The <a 
       
  1542 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirAgent.html" 
       
  1543 title="The ScanDirAgent class defines a main method for the scandir application"
       
  1544      >ScanDirAgent</a> is the Agent class for the <i>scandir</i> application.
       
  1545     This class contains the <code>main</code> method to start a standalone  
       
  1546     <i>scandir</i> application.
       
  1547     </p>
       
  1548     <p>The <code>main</code> method simply registers a <a 
       
  1549 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1550 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1551        >ScanManagerMXBean</a> in the platform MBeanServer, and then waits
       
  1552     for someone to call <code>ScanManagerMXBean.close</code>.
       
  1553     </p>
       
  1554     <p>
       
  1555     When the <code>ScanManagerMXBean</code> state is switched to 
       
  1556     <code>ScanManagerMXBean.ScanState.CLOSED</code>, the 
       
  1557     <code>ScanManagerMXBean</code> is unregistered, and the application
       
  1558     terminates (i.e. the main thread completes).
       
  1559     </p>
       
  1560     <p>Standalone JMX applications usually have an Agent class that contain 
       
  1561        their <code>main</code> method, which performs all the MBean
       
  1562        registration steps.
       
  1563        However, it is usually not a bad idea if that class can
       
  1564        be easily turned into an MBean. Indeed, this will make your
       
  1565        application easier to integrate in an environment where it would
       
  1566        no longer be standalone and would no longer control the implementation
       
  1567        of <code>main</code>. In our example the Agent
       
  1568        class could be easily turned into an MBean, exposing its three
       
  1569     <code>init</code>, <code>waitForClose</code> and <code>cleanup</code> 
       
  1570     method. However we didn't go as far as turning it into an MBean since 
       
  1571     the application can be already easily started by registering an instance
       
  1572     of <a 
       
  1573 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanManagerMXBean.html" 
       
  1574 title="The ScanManagerMXBean is the main MBean of the scandir application"
       
  1575        >ScanManagerMXBean</a>.
       
  1576     </p>
       
  1577     </ul>
       
  1578   <h3>Secure Client Class</h3>
       
  1579     <ul>
       
  1580    <p>The <a 
       
  1581 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirClient.html" 
       
  1582 title="The ScanDirClient class is a very short example of secure programatic client"
       
  1583      >ScanDirClient</a> is an example class that shows how a
       
  1584     programmatic client can connect to a secured <i>scandir</i> application.
       
  1585     This class contains a <code>main</code> method which creates and
       
  1586     configures a <code>JMXConnector</code> client to connect with
       
  1587     a secured <i>scandir</i> daemon. This class will not work with
       
  1588     the default unsecured agent since it requires mutual authentication.
       
  1589     </p>
       
  1590     <p>How to secure a JMX <i>scandir</i> application and run
       
  1591     the secure <code>ScanDirClient</code> is discussed <a href="#secure"
       
  1592     >later</a> in this document.
       
  1593     </p>
       
  1594     <p>The <code>ScanDirClient</code> is not really part of the
       
  1595        application - and is given here only for the sake of
       
  1596        the example.
       
  1597     </p>
       
  1598     </ul>
       
  1599     
       
  1600   <h2><a name="h2-Testing">Testing the <i>scandir</i> Example</a></h2>
       
  1601     <ul>
       
  1602         <p>Make sure that you have access to junit.jar (either 3.8.1 or 3.8.2).
       
  1603            Make sure also that you have junit.jar in your 
       
  1604            <code>CLASSPATH</code>.<br>
       
  1605            Then in the example root directory (where the <code>build.xml</code> 
       
  1606            file is located) run the following command:
       
  1607            <pre>ant test -Dlibs.junit.classpath=<i><u>path to junit jar (either 3.8.1 or 3.8.2)</u></i></pre>
       
  1608         </p>
       
  1609         <p>Alternatively you can open the jmx-scandir project with the 
       
  1610            NetBeans IDE and test the jmx-scandir project from the 
       
  1611            <code>Run</code> menu.
       
  1612         </p>
       
  1613 
       
  1614     </ul>
       
  1615 
       
  1616   <h2><a name="h2-Running">Running the <i>scandir</i> Example</a></h2>
       
  1617     <ul>
       
  1618         <p>In the example root directory (where the <code>build.xml</code> 
       
  1619            file is located) run the following commands:
       
  1620         <pre>ant jar
       
  1621 ant run-single -Drun.class=com.sun.jmx.examples.scandir.ScanDirAgent -Djavac.includes=src</pre>
       
  1622            or simply <pre>ant run</pre>
       
  1623         </p>
       
  1624         
       
  1625         <p>This will run the example using the configuration
       
  1626            file provided in the src/etc directory.
       
  1627         </p>
       
  1628         <p>Alternatively you can open the jmx-scandir project with the 
       
  1629            NetBeans IDE. You can run the example by 
       
  1630            selecting the <code>ScanDirAgent</code> file
       
  1631            and run it with <code>Run File</code> in the
       
  1632            <code>Run</code> menu or simply
       
  1633            set the <i>jmx-scandir</i> project as main project and
       
  1634            select <code>Run Main Project</code> from the
       
  1635            main menu. Both targets will use the configuration
       
  1636            file provided in the src/etc directory.
       
  1637         </p>
       
  1638         <p>When the application is started, you can connect to
       
  1639            it with <a href="#JConsole">jconsole</a>.
       
  1640         </p>
       
  1641         <blockquote>
       
  1642             <u>Note:</u> You can also run the <i>scandir</i> 
       
  1643             application directly from the <code>java</code> 
       
  1644             command line. Make sure to build the project jar
       
  1645             first. 
       
  1646             <br>On Unix systems:
       
  1647             <pre>ant jar
       
  1648 java -Djava.util.logging.config.file=logging.properties \
       
  1649      -Dscandir.config.file=src/etc/testconfig.xml \
       
  1650      -jar dist/jmx-scandir.jar</pre>
       
  1651             <br>On Windows systems:
       
  1652             <p><code>ant jar<br>
       
  1653 java &nbsp;-Djava.util.logging.config.file=logging.properties
       
  1654      &nbsp;-Dscandir.config.file=src\etc\testconfig.xml
       
  1655      &nbsp;-jar&nbsp;dist\jmx-scandir.jar</code></p>
       
  1656         </blockquote>
       
  1657     </ul>
       
  1658     
       
  1659     <h2><a name="h2-Playing">Playing with JConsole</a></h2>
       
  1660     <ul>
       
  1661     <p>Run the example as explained in the previous section, so
       
  1662     that it uses the provided <code>src/etc/testconfig.xml</code> 
       
  1663     configuration file. Then start
       
  1664     jconsole. In the connection window choose the process that runs
       
  1665     <code>com.sun.jmx.examples.scandir.ScanDirAgent</code> or
       
  1666     <code>jmx-scandir.jar</code>.
       
  1667     </p>
       
  1668     <p><center>
       
  1669         <table border="0" cellpadding="2" cellspacing="2">
       
  1670         <tr><td>
       
  1671     <a href="docfiles/connect-local-ant-run.jpg"
       
  1672     title="jconsole connection window - connect to local process"
       
  1673     ><img height="440"
       
  1674     src="docfiles/connect-local-ant-run.jpg"
       
  1675     alt="jconsole connection window - connect to local process"
       
  1676     /></a>
       
  1677     </td>
       
  1678     <td>
       
  1679     <a href="docfiles/connect-local-java-jar.jpg"
       
  1680     title="jconsole connection window - connect to local process"
       
  1681     ><img height="440"
       
  1682     src="docfiles/connect-local-java-jar.jpg"
       
  1683     alt="jconsole connection window - connect to local process"
       
  1684     /></a>
       
  1685     </td></tr></table>
       
  1686     </center>
       
  1687     </p>
       
  1688     <p>Open the MBeans tab, and look for the 
       
  1689        <code>ScanDirConfigMXBean</code>.
       
  1690        Click on its <code>Attributes</code> node and double click on its
       
  1691        <code>Configuration</code> attribute, to look at
       
  1692        the loaded configuration - values in bold can
       
  1693        be expanded by a double-click.
       
  1694     </p>
       
  1695     <p><center><a href="docfiles/scandir-config.jpg"
       
  1696     title="jconsole MBean tab: ScanDirConfigMXBean"
       
  1697     ><img 
       
  1698     src="docfiles/scandir-config.jpg"
       
  1699     alt="jconsole MBean tab: ScanDirConfigMXBean"
       
  1700     /></a></center>
       
  1701     </p>
       
  1702     <p>Now go to the <code>ScanManagerMXBean</code>, click on
       
  1703        its <code>Notifications</code> node, and subscribe
       
  1704        for notifications. Then click on the 
       
  1705        <code>Operations</code> node and invoke the
       
  1706        <code>start()</code> operation:
       
  1707     </p>
       
  1708     <p><center><a href="docfiles/scandir-start.jpg"
       
  1709     title="jconsole MBean tab: ScanDirConfigMXBean"
       
  1710     ><img 
       
  1711     src="docfiles/scandir-start.jpg"
       
  1712     alt="jconsole MBean tab: ScanDirConfigMXBean"
       
  1713     /></a></center>
       
  1714     </p>
       
  1715     <p>You can see that the notifications counter was 
       
  1716        incremented by three: you have just scheduled, 
       
  1717        run, and completed a batch of directory scans.
       
  1718     </p>
       
  1719     <p>Now go to the <code>ResultLogManagerMXBean</code>,
       
  1720        click on its <code>Attributes</code> node, and 
       
  1721        expand its <code>MemoryLog</code> attribute:
       
  1722     </p>
       
  1723     <p><center><a href="docfiles/scandir-result.jpg"
       
  1724     title="jconsole MBean tab: ScanDirConfigMXBean"
       
  1725     ><img 
       
  1726     src="docfiles/scandir-result.jpg"
       
  1727     alt="jconsole MBean tab: ScanDirConfigMXBean"
       
  1728     /></a></center>
       
  1729     </p>
       
  1730     <p>You can see that the directory scan results have
       
  1731        been logged.</p>
       
  1732     <p>To make the application terminate go back to the 
       
  1733        <code>ScanManagerMXBean</code> and invoke
       
  1734        <code>close()</code>. The <code>ScanDirAgent</code>
       
  1735        will receive the notification, step out of 
       
  1736        the application main thread, and the application
       
  1737        will terminate.
       
  1738     </p>
       
  1739     <p>This is of course a very limited scenario. Feel free
       
  1740     to improvise with all the features of the example, creating
       
  1741     a new configuration - 
       
  1742     <code>ScanManagerMXBean.createOtherConfigurationMBean</code> -
       
  1743     adding multiple directory scanners to that configuration -
       
  1744     <code>ScanDirConfigMXBean.addDirectoryScanner</code> -
       
  1745     then switching the <code>ScanManagerMXBean</code> current
       
  1746     configuration by changing the value of the <i>ConfigurationMBean</i>
       
  1747     attribute - <code>ScanManagerMXBean.setConfigurationMBean</code>
       
  1748     - then applying the new configuration - 
       
  1749     <code>ScanManagerMXBean.applyConfiguration(true)</code> - 
       
  1750     then scheduling repeated directory scans every 10 seconds - 
       
  1751     <code>ScanManagerMXBean.schedule(0,10000)</code> - 
       
  1752     subscribing for notifications, etc...
       
  1753     </p>
       
  1754     </ul>
       
  1755     
       
  1756   <a name="secure"></a>
       
  1757   <h2><a name="h2-Turning">Turning the example into a Secure JMX Application</a></h2>
       
  1758     <ul>
       
  1759     <p>In this section, we will see how to configure and
       
  1760     start the <i>scandir</i> example so that the JVM agent
       
  1761     is bootstrapped with a secure JMXConnectorServer. Indeed, until 
       
  1762     now we have only used the insecure local connection, 
       
  1763     which can only be used as long as both the client and
       
  1764     the server run on the same machine. This section will
       
  1765     explain how to start the <code>ScanDirAgent</code> so 
       
  1766     that a real secure RMIConnectorServer is started at bootstrap.
       
  1767     </p>
       
  1768     <p>To achieve this we will: <a href="#management.properties"
       
  1769         >provide our own management.properties</a>, <a 
       
  1770         href="#password-access">create our own password and access files</a>,
       
  1771         <a href="#keystore-truststore">provide a keystore and truststore</a>,
       
  1772         <a href="#start-secure-agent">start the ScanDirAgent with the
       
  1773         appropriate system properties</a>.
       
  1774     </ul>
       
  1775     <h3>Configuring the JVM Agent for Secure Remote Connection</h3>
       
  1776     <ul>
       
  1777         <p>The easiest way to <a name="management.properties">configure the 
       
  1778             JVM Agent</a> for Secure Remote 
       
  1779            Connection is to use your own <a
       
  1780            href="http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#properties"
       
  1781            title="This page describes the properties you can put in your management.properties file"
       
  1782            >management.properties</a> file.
       
  1783            In this example, we have copied the default 
       
  1784            <code>$JRE/lib/management/management.properties</code>
       
  1785            file to the example's <code>src/etc</code> directory and
       
  1786            modified it in <a href="src/etc/management.properties"
       
  1787            title="our modified management.properties"
       
  1788            >this way</a>:
       
  1789            <ul>
       
  1790                <li>We have set the RMI port to <u>4545</u> - this is just a 
       
  1791                    random port number we have picked up. Feel free to use your 
       
  1792                    own value suited to your environment.
       
  1793                <pre># For setting the JMX RMI agent port use the following line
       
  1794 com.sun.management.jmxremote.port=<b>4545</b></pre>
       
  1795                </li>
       
  1796                <li>We have <u>switched on</u> SSL <u>mutual authentication</u>
       
  1797                <pre># For RMI monitoring with SSL client authentication use the following line
       
  1798 com.sun.management.jmxremote.ssl.<b>need.client.auth</b>=<b>true</b></pre>
       
  1799                </li>
       
  1800                <li>We have also <u>secured the RMI Registry</u> with SSL
       
  1801                <pre># For using an SSL/TLS <b>protected</b> RMI Registry use the following line
       
  1802 com.sun.management.jmxremote.<b>registry.ssl</b>=<b>true</b></pre>
       
  1803                </li>
       
  1804                <li>We have provided <a 
       
  1805                 href="src/etc/password.properties">our own password file</a>
       
  1806                <pre># For a non-default password file location use the following line
       
  1807 com.sun.management.jmxremote.password.file=<i>src/etc/password.properties</i></pre>
       
  1808                </li>
       
  1809                <li>We have provided <a 
       
  1810                 href="src/etc/access.properties">our own access file</a>
       
  1811                <pre># For a non-default password file location use the following line
       
  1812 com.sun.management.jmxremote.access.file=<i>src/etc/access.properties</i></pre>
       
  1813                </li>
       
  1814            </ul>
       
  1815            <p>You will note that we haven't provided any value
       
  1816               for the other security properties, like 
       
  1817               <code>com.sun.management.jmxremote.authenticate=true</code>,
       
  1818               because these properties already default to a value
       
  1819               which enables security by default. 
       
  1820               Note however that protecting the RMI Registry with SSL
       
  1821               improves the application security, but only as long as
       
  1822               mutual authentication is also switched on. Otherwise, just
       
  1823               anybody would be able to connect to the registry and 
       
  1824               get the RMIServer stub.
       
  1825            </p>
       
  1826            <p>We do recommend that you <u>use the most secure configuration
       
  1827               when you deploy a JMX agent</u> - which means <u>switching on
       
  1828               SSL protection for the RMI registry</u> <b>and</b> <u>requiring
       
  1829               mutual authentication</u>, as we show in this example.
       
  1830            </p>
       
  1831            <p>We will use the <code>com.sun.management.config.file</code>
       
  1832            system property to pass our <a 
       
  1833            href="src/etc/management.properties">management.properties</a>
       
  1834            file to the <code>ScanDirAgent</code>.
       
  1835            </p>
       
  1836     </ul>
       
  1837     
       
  1838     <h3>Creating a password and access file</h3>
       
  1839     <ul>
       
  1840         <p>As explained above, we have created our own
       
  1841         <a href="src/etc/password.properties">password file</a> 
       
  1842         and <a href="src/etc/access.properties">access file</a> 
       
  1843         for <a name="password-access">access control and authorization</a>.
       
  1844         </p>
       
  1845         <p>In the password file, we have defined two logins: 
       
  1846            <i>guest</i> and <i>admin</i>. The password for 
       
  1847            <i>guest</i> is <i>guestpasswd</i> and the password
       
  1848            for <i>admin</i> is <i>adminpasswd</i>.
       
  1849         </p>
       
  1850         <p>In the access file, we have mapped these two logins
       
  1851         to access rights: the <i>admin</i> login has <i>read-write</i>
       
  1852         access, while the <i>guest</i> login only has <i>read-only</i>.
       
  1853         </p>
       
  1854         <p>Before starting the <code>ScanDirAgent</code>, you will
       
  1855            need to restrict access permission to the password file, 
       
  1856            in such a way that nobody but you can read it. Otherwise, the
       
  1857            JVM Agent will refuse to start the JMXConnectorServer, as it will
       
  1858            fear that security can be compromised if other parties can
       
  1859            have read access to the password file. How to restrict
       
  1860            read access to the password file is explained in detail
       
  1861            <a href="http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#PasswordAccessFiles"
       
  1862            title="Using Password and Access Files"
       
  1863            >here</a>.
       
  1864         </p>
       
  1865         <p>As we have seen above, the location
       
  1866            of our access and password files is configured in our own <a 
       
  1867            href="src/etc/management.properties">management.properties</a>
       
  1868            file.
       
  1869         </p>
       
  1870     </ul>
       
  1871     <h3>Keystore and Truststore</h3>
       
  1872     <ul>
       
  1873         <p>Using SSL with mutual authentication means that both
       
  1874            client and server will need a <a name="keystore-truststore"
       
  1875            >keystore and a truststore</a>
       
  1876            to store their own certificates, and the certificates of
       
  1877            the parties they trust. Usually, client and server will 
       
  1878            have their own keystore and truststore. 
       
  1879         </p>
       
  1880         <p>For the sake of simplicity - and to get you started
       
  1881         without the tedious necessity of creating your own keystore
       
  1882         and truststore, we are providing a dummy keystore and 
       
  1883         truststore, containing a certificate self-signed by duke.
       
  1884         The password for our keystore is <i>password</i>, and the
       
  1885         password for our truststore is <i>trustword</i>.
       
  1886         We suggest that you first get the example running with the
       
  1887         keystore and truststore we are providing before attempting 
       
  1888         to use your own keystore and truststore.
       
  1889         </p>
       
  1890         <p>A secure application will obviously need to use its own
       
  1891         keystore and truststore, <b><u>and should not rely on the keystore
       
  1892         and truststore we are providing here!</u></b>
       
  1893         </p>
       
  1894         <p>How to create your own keystore and truststore, is explained
       
  1895         in <a
       
  1896 href="http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#SSL_enabled"
       
  1897 title="Monitoring and Management Using JMX"
       
  1898         >here</a>.          
       
  1899         As shown <a href="#start-secure-agent">later</a>, 
       
  1900         we will need to use <a 
       
  1901         href="http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html#SSL_enabled"
       
  1902         >system properties</a> to pass our truststore
       
  1903         and keystore to the <code>ScanDirAgent</code>.
       
  1904         </p>
       
  1905     </ul>
       
  1906     <h3>Starting a Secure <i>scandir</i> agent</h3>
       
  1907     <ul>
       
  1908         <p>To start a <a name="start-secure-agent"
       
  1909         >secure <i>scandir</i> agent</a>, go to the
       
  1910         <i>scandir</i> example root directory and type the
       
  1911         following command:</p>
       
  1912         <p>On Unix Systems:
       
  1913 <pre>ant jar
       
  1914 java \
       
  1915     -Djava.util.logging.config.file=logging.properties \
       
  1916     -Djavax.net.ssl.keyStore=keystore \
       
  1917     -Djavax.net.ssl.keyStorePassword=password \
       
  1918     -Djavax.net.ssl.trustStore=truststore \
       
  1919     -Djavax.net.ssl.trustStorePassword=trustword \
       
  1920     -Dcom.sun.management.config.file=src/etc/management.properties \
       
  1921     -Dscandir.config.file=src/etc/testconfig.xml \
       
  1922     -jar dist/jmx-scandir.jar</pre>
       
  1923         </p>
       
  1924          <p>On Windows Systems:
       
  1925 <p><code>ant jar<br>
       
  1926 java 
       
  1927     &nbsp;-Djava.util.logging.config.file=logging.properties
       
  1928     &nbsp;-Djavax.net.ssl.keyStore=keystore
       
  1929     &nbsp;-Djavax.net.ssl.keyStorePassword=password
       
  1930     &nbsp;-Djavax.net.ssl.trustStore=truststore
       
  1931     &nbsp;-Djavax.net.ssl.trustStorePassword=trustword
       
  1932     &nbsp;-Dcom.sun.management.config.file=src\etc\management.properties
       
  1933     &nbsp;-Dscandir.config.file=src\etc\testconfig.xml
       
  1934     &nbsp;-jar&nbsp;dist\jmx-scandir.jar</code></p>
       
  1935          </p>
       
  1936     <p>If you start jconsole now, you will see that you
       
  1937        are still able to connect to the agent using the 
       
  1938        local connection. However, if you try to connect
       
  1939        through the remote connector, using 
       
  1940        <a href="docfiles/remote-connection.jpg">localhost:4545</a>, 
       
  1941        the connection will <a href="docfiles/remote-connection-failed.jpg"
       
  1942        >fail</a>, even if you provide a correct login/password
       
  1943        pair. Indeed, since the JMXConnectorServer is now protected with SSL,
       
  1944        jconsole must also be configured with the appropriate SSL parameters
       
  1945        so that it can authenticate the server and get authenticated by the
       
  1946        server too as the SSL configuration of the server requires mutual
       
  1947        authentication.
       
  1948     </p>
       
  1949     <p>The next section will discuss how to connect to the 
       
  1950     secure agent.
       
  1951     </p>
       
  1952    </ul>
       
  1953    
       
  1954   <h2><a name="h2-Connecting">Connecting to the Secure JMX Application</a></h2>
       
  1955     <ul>
       
  1956     <p>We will now see how to connect to the secure agent,
       
  1957        using jconsole, and using a programmatic client.
       
  1958     </p>
       
  1959     </ul>
       
  1960     
       
  1961     <h3>Using jconsole to connect to the secure agent</h3>
       
  1962     <ul>
       
  1963     <p>The only special thing you need to do in order to
       
  1964         be able to connect to your secure agent with
       
  1965         jconsole, is to give it a keystore (containing
       
  1966         its client certificate) and a truststore (containing
       
  1967         the certificates of the servers it can trust).
       
  1968         In our example, we use the same keystore/truststore
       
  1969         pair on the client and server side - but this is
       
  1970         not what a real application would do.
       
  1971         Indeed a real application would have different 
       
  1972         certificates for the client and the server, and 
       
  1973         thus use different keystores (and probably truststores).
       
  1974         More information on SSL authentication can be obtained from the <a
       
  1975         href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#HowSSLWorks"
       
  1976         title="How SSL Works"
       
  1977         >Java<sup>TM</sup> Secure Socket Extension (JSSE) Reference Guide</a>.
       
  1978     </p>
       
  1979     <p>To start jconsole with our provided keystore and
       
  1980     truststore, go to the scandir example root directory and 
       
  1981     type in the following command:
       
  1982     <p><code>jconsole 
       
  1983     &nbsp;-J-Djava.util.logging.config.file=logging.properties 
       
  1984     &nbsp;-J-Djavax.net.ssl.keyStore=keystore 
       
  1985     &nbsp;-J-Djavax.net.ssl.keyStorePassword=password 
       
  1986     &nbsp;-J-Djavax.net.ssl.trustStore=truststore 
       
  1987     &nbsp;-J-Djavax.net.ssl.trustStorePassword=trustword</code></p>
       
  1988     </p>
       
  1989     <p>The <code>-J-Djava.util.logging.config.file=logging.properties</code>
       
  1990        flag is not mandatory, but passing a <code>logging.properties</code>
       
  1991        may help you debug connection problems if anything goes wrong.
       
  1992     </p>
       
  1993     <p>In jconsole connection window, choose to connect to a 
       
  1994        remote process, using the address <i>localhost:4545</i>
       
  1995        and the guest login:
       
  1996     </p>
       
  1997     <p><center><a href="docfiles/remote-connection.jpg"
       
  1998        ><img src="docfiles/remote-connection.jpg"
       
  1999         alt="jconsole connection window"/></a></center>
       
  2000     </p>
       
  2001     <p>You will see that the agent will let view all the
       
  2002        MBeans and their attributes, but will reject any
       
  2003        attribute modification or remote method invocation.
       
  2004     </p>
       
  2005     <hr>
       
  2006     <p><u>Note:</u> if jconsole fails to connect and show
       
  2007     you <a href="docfiles/remote-connection-failed.jpg">this screen</a>
       
  2008     you have probably misspelled some of the properties on jconsole
       
  2009     command line, or you didn't start jconsole from the 
       
  2010     scandir example root directory where our <code>truststore</code>
       
  2011     and <code>keystore</code> files are located. This article - <a 
       
  2012     href="http://blogs.sun.com/roller/page/jmxetc?entry=troubleshooting_connection_problems_in_jconsole"
       
  2013     title="Troubleshooting connection problems in JConsole"
       
  2014     >Troubleshooting connection problems in JConsole</a> - may help
       
  2015     you figure out what is going wrong.
       
  2016     </p>
       
  2017     <hr>
       
  2018     </ul>
       
  2019     
       
  2020     <h3>Writing a programmatic client to connect to the secure agent</h3>
       
  2021     <ul>
       
  2022         <p>
       
  2023         In this section we will show the steps involved in writing 
       
  2024         a programmatic client that will connect to our secure agent.
       
  2025         </p>
       
  2026    <p>The <a 
       
  2027 href="dist/javadoc/com/sun/jmx/examples/scandir/ScanDirClient.html" 
       
  2028 title="The ScanDirClient class is a very short example of secure programatic client"
       
  2029      >ScanDirClient</a> is an example class that shows how a
       
  2030     programmatic client can connect to a secured <i>scandir</i> application.
       
  2031     This class contains a <code>main</code> method which creates and
       
  2032     configures a <code>JMXConnector</code> client to connect with
       
  2033     the secured <i>scandir</i> agent. 
       
  2034     </p>
       
  2035     <p>The secure client differs only from a non secure client in
       
  2036     so far as it needs to use SSL RMI Factories and credentials to
       
  2037     connect to the secure agent. The steps required mainly involve:
       
  2038        <ul>
       
  2039            <li>Creating an empty environment map:
       
  2040            <pre>            
       
  2041             // Create an environment map to hold connection properties
       
  2042             // like credentials etc... We will later pass this map
       
  2043             // to the JMX Connector.
       
  2044             //
       
  2045             System.out.println("\nInitialize the environment map");
       
  2046             final Map&lt;String,Object> env = new HashMap&lt;String,Object>();
       
  2047            </pre>
       
  2048            </li>
       
  2049            <li>Putting the client's credentials in that map:
       
  2050            <i>(here the client will log in as <b>guest</b>)</i>
       
  2051            <pre>            
       
  2052             // Provide the credentials required by the server
       
  2053             // to successfully perform user authentication
       
  2054             //
       
  2055             final String[] credentials = new String[] { "guest" , "guestpasswd" };
       
  2056             env.put("jmx.remote.credentials", credentials);
       
  2057            </pre>
       
  2058            </li>
       
  2059            <li>Providing an <code>SslRMIClientSocketFactory</code> to interact
       
  2060            with the secure RMI Registry:
       
  2061            <pre>            
       
  2062             // Provide the SSL/TLS-based RMI Client Socket Factory required
       
  2063             // by the JNDI/RMI Registry Service Provider to communicate with
       
  2064             // the SSL/TLS-protected RMI Registry
       
  2065             //
       
  2066             env.put("com.sun.jndi.rmi.factory.socket",
       
  2067                     new SslRMIClientSocketFactory());
       
  2068            </pre>
       
  2069            </li>
       
  2070            <li>Creating a JMXConnector and connecting with the
       
  2071                secure server:
       
  2072            <pre>
       
  2073             // Create the RMI connector client and
       
  2074             // connect it to the secure RMI connector server.
       
  2075             // args[0] is the server's host - localhost
       
  2076             // args[1] is the secure server port - 4545
       
  2077             //
       
  2078             System.out.println("\nCreate the RMI connector client and " +
       
  2079                     "connect it to the RMI connector server");
       
  2080             final JMXServiceURL url = new JMXServiceURL(
       
  2081                     "service:jmx:rmi:///jndi/rmi://"+args[0]+":"+args[1]+ 
       
  2082                     "/jmxrmi");
       
  2083             final JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
       
  2084            </pre>
       
  2085            </li>
       
  2086        </ul>
       
  2087        <p>For this to work, we also need to start the <code>ScanDirClient</code>
       
  2088        with the appropriate system properties that will point to our 
       
  2089        <code>keystore</code> and <code>truststore</code>. To start the secure 
       
  2090        client, go to the <i>scandir</i> example root directory and type
       
  2091        the following command:
       
  2092        <p><code>ant jar<br>
       
  2093 java 
       
  2094     &nbsp;-Djava.util.logging.config.file=logging.properties 
       
  2095     &nbsp;-Djavax.net.ssl.keyStore=keystore
       
  2096     &nbsp;-Djavax.net.ssl.keyStorePassword=password
       
  2097     &nbsp;-Djavax.net.ssl.trustStore=truststore
       
  2098     &nbsp;-Djavax.net.ssl.trustStorePassword=trustword
       
  2099     &nbsp;-classpath&nbsp;dist/jmx-scandir.jar
       
  2100      &nbsp;com.sun.jmx.examples.scandir.ScanDirClient&nbsp;localhost&nbsp;4545
       
  2101        </code></p>
       
  2102        </p>
       
  2103        <p>You should be seeing this trace:
       
  2104 <center><table width="90%" border="0" bgcolor="#eeeeee">
       
  2105 <tr><td>
       
  2106 <pre>
       
  2107 Initialize the environment map
       
  2108 
       
  2109 Create the RMI connector client and connect it to the RMI connector server
       
  2110 Connecting to: service:jmx:rmi:///jndi/rmi://localhost:4545/jmxrmi
       
  2111 
       
  2112 Get the MBeanServerConnection
       
  2113 
       
  2114 Get ScanDirConfigMXBean from ScanManagerMXBean
       
  2115 
       
  2116 Get 'Configuration' attribute on ScanDirConfigMXBean
       
  2117 
       
  2118 Configuration:
       
  2119 
       
  2120 &lt;ScanManager xmlns="jmx:com.sun.jmx.examples.scandir.config" name="testconfig">
       
  2121     &lt;InitialResultLogConfig>
       
  2122         &lt;LogFileMaxRecords>2048&lt;/LogFileMaxRecords>
       
  2123         &lt;LogFileName>build/scandir.log&lt;/LogFileName>
       
  2124         &lt;MemoryMaxRecords>128&lt;/MemoryMaxRecords>
       
  2125     &lt;/InitialResultLogConfig>
       
  2126     &lt;DirectoryScannerList>
       
  2127         &lt;DirectoryScanner name="scan-build">
       
  2128             &lt;Actions>NOTIFY LOGRESULT&lt;/Actions>
       
  2129             &lt;ExcludeFiles/>
       
  2130             &lt;IncludeFiles>
       
  2131                 &lt;FileFilter>
       
  2132                     &lt;FilePattern>.*\.class&lt;/FilePattern>
       
  2133                     &lt;SizeExceedsMaxBytes>4096&lt;/SizeExceedsMaxBytes>
       
  2134                 &lt;/FileFilter>
       
  2135             &lt;/IncludeFiles>
       
  2136             &lt;RootDirectory>build&lt;/RootDirectory>
       
  2137         &lt;/DirectoryScanner>
       
  2138     &lt;/DirectoryScannerList>
       
  2139 &lt;/ScanManager>
       
  2140 
       
  2141 Invoke 'close' on ScanManagerMXBean
       
  2142 
       
  2143 Got expected security exception: java.lang.SecurityException: Access denied! 
       
  2144 Invalid access level for requested MBeanServer operation.
       
  2145 
       
  2146 Close the connection to the server
       
  2147 
       
  2148 Bye! Bye!
       
  2149 </pre>
       
  2150 </td></tr></table></center>
       
  2151     <p>If the <code>ScanDirClient</code> fails to connect with 
       
  2152        the secure agent, then this article - <a 
       
  2153     href="http://blogs.sun.com/roller/page/jmxetc?entry=troubleshooting_connection_problems_in_jconsole"
       
  2154     title="Troubleshooting connection problems in JConsole"
       
  2155     >Troubleshooting connection problems in JConsole</a> - may help
       
  2156     you figure out what is going wrong. Indeed the connection steps
       
  2157     performed by the <code>ScanDirClient</code> are very similar to
       
  2158     those performed by <code>jconsole</code>, and the problems you
       
  2159     could encounter are identical. Just remember that 
       
  2160    <code>jconsole</code> needs the extra <code>-J</code> flag to pass
       
  2161    system properties to the VM, which is not needed with regular
       
  2162    <code>java</code> launcher invocations.
       
  2163     </p>
       
  2164     </ul>
       
  2165     
       
  2166     <h2><a name="h2-Conclusion">Conclusion</a></h2>
       
  2167     <ul>
       
  2168     <p>
       
  2169         In this document, we have presented an advanced 
       
  2170         JMX example, and shown how to run a secure 
       
  2171         JMX agent in a production environment. 
       
  2172         We have also shown how to connect to such a 
       
  2173         secure agent with both jconsole and a programmatic 
       
  2174         client. We have also discuss various JMX 
       
  2175         design-patterns and best practices. 
       
  2176         Readers who would wish to learn more about JMX, and
       
  2177         Monitoring and Management of the JVM, are invited
       
  2178         to follow the links given in reference below.
       
  2179     </p>
       
  2180     </ul>
       
  2181   <h2><a name="h2-References">References</a></h2>
       
  2182   <ol>
       
  2183      <li><a href="http://java.sun.com/products/JavaManagement/best-practices.html"
       
  2184         >JMX Best Practices</a>: This document describes best practices that
       
  2185       have been identified for modeling using the JMX API. </li>
       
  2186      <li><a href="http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html"
       
  2187       >Monitoring and Management Using JMX</a>: How to enable, configure, and 
       
  2188       connect to the JVM JMX agent.</li> 
       
  2189      <li><a name="JConsole"><a 
       
  2190 href="http://java.sun.com/javase/6/docs/technotes/guides/management/jconsole.html"
       
  2191 >Using JConsole</a>: JConsole is a JMX-Compliant monitoring tool which allows
       
  2192      you to interact graphically with your own MBeans.
       
  2193      </li>
       
  2194      <li><a href="http://java.sun.com/javase/6/docs/technotes/guides/management/"
       
  2195      >Monitoring and Management for the Java Platform</a>: The Java Platform 
       
  2196       Standard Edition (Java SE) 6 provides comprehensive monitoring and 
       
  2197       management support for the Java platform. </li>
       
  2198      <li><a href="http://java.sun.com/products/JavaManagement/community/jmx_blogs.html"
       
  2199          >List of JMX-related Blogs</a>: This page provides links to the 
       
  2200           different web logs written by members of the Sun team working on the 
       
  2201           JMX API.</li>
       
  2202      <li><a
       
  2203         href="http://java.sun.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#HowSSLWorks"
       
  2204         title="The JSSE Reference Guide"
       
  2205         >Java<sup>TM</sup> Secure Socket Extension (JSSE) Reference Guide</a>:
       
  2206         comprehensive documentation about the Java<sup>TM</sup> Secure Socket 
       
  2207         Extension (JSSE)
       
  2208      </li>
       
  2209      <li><a href="http://java.sun.com/javase/6/docs/"
       
  2210          >Java SE 6 Documentation Index</a>: This document covers the
       
  2211           Java<sup>TM</sup> Platform, Standard Edition 6 JDK.</li>
       
  2212   </ol>
       
  2213   <p>
       
  2214   <hr>
       
  2215   <p>
       
  2216   </body>
       
  2217 </html>