jdk/src/share/classes/javax/management/MXBean.java
author xdono
Wed, 02 Jul 2008 12:55:45 -0700
changeset 715 f16baef3a20e
parent 687 874e25a9844a
child 834 dc74d4ddc28e
permissions -rw-r--r--
6719955: Update copyright year Summary: Update copyright year for files that have been modified in 2008 Reviewed-by: ohair, tbell
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 687
diff changeset
     2
 * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.management;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.lang.annotation.Documented;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.lang.annotation.ElementType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.lang.annotation.Retention;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.lang.annotation.RetentionPolicy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.lang.annotation.Target;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
// remaining imports are for Javadoc
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.beans.ConstructorProperties;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.io.InvalidObjectException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.lang.management.MemoryUsage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.lang.reflect.UndeclaredThrowableException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import javax.management.openmbean.ArrayType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import javax.management.openmbean.CompositeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import javax.management.openmbean.CompositeDataInvocationHandler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import javax.management.openmbean.CompositeDataSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import javax.management.openmbean.CompositeDataView;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import javax.management.openmbean.CompositeType;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
    47
import javax.management.openmbean.MXBeanMapping;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
    48
import javax.management.openmbean.MXBeanMappingClass;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
    49
import javax.management.openmbean.MXBeanMappingFactory;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
    50
import javax.management.openmbean.MXBeanMappingFactoryClass;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import javax.management.openmbean.OpenDataException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import javax.management.openmbean.OpenMBeanInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import javax.management.openmbean.OpenType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import javax.management.openmbean.SimpleType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import javax.management.openmbean.TabularData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import javax.management.openmbean.TabularDataSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import javax.management.openmbean.TabularType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    <p>Annotation to mark an interface explicitly as being an MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    interface, or as not being an MXBean interface.  By default, an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    interface is an MXBean interface if its name ends with {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    MXBean}, as in {@code SomethingMXBean}.  The following interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    are MXBean interfaces:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public interface WhatsitMXBean {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    &#64;MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    public interface Whatsit1Interface {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    &#64;MXBean(true)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    public interface Whatsit2Interface {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    <p>The following interfaces are not MXBean interfaces:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    public interface Whatsit3Interface{}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    &#64;MXBean(false)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    public interface MisleadingMXBean {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
    85
    <h3 id="MXBean-spec">MXBean specification</h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    <p>The MXBean concept provides a simple way to code an MBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
      that only references a predefined set of types, the ones defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
      by {@link javax.management.openmbean}.  In this way, you can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
      sure that your MBean will be usable by any client, including
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
      remote clients, without any requirement that the client have
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
      access to <em>model-specific classes</em> representing the types
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
      of your MBeans.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    <p>The concepts are easier to understand by comparison with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
      Standard MBean concept.  Here is how a managed object might be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
      represented as a Standard MBean, and as an MXBean:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
public interface MemoryPool<b>MBean</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    String getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    MemoryUsage getUsage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
public interface MemoryPool<b>MXBean</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    String getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    MemoryUsage getUsage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    // ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    <p>As you can see, the definitions are very similar.  The only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
      difference is that the convention for naming the interface is to use
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
      <code><em>Something</em>MXBean</code> for MXBeans, rather than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
      <code><em>Something</em>MBean</code> for Standard MBeans.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    <p>In this managed object, there is an attribute called
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
      <code>Usage</code> of type {@link MemoryUsage}.  The point of an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
      attribute like this is that it gives a coherent snapshot of a set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
      of data items.  For example, it might include the current amount
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
      of used memory in the memory pool, and the current maximum of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
      memory pool.  If these were separate items, obtained with separate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
      {@link MBeanServer#getAttribute getAttribute} calls, then we could
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
      get values seen at different times that were not consistent.  We
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
      might get a <code>used</code> value that was greater than the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
      <code>max</code> value.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    <p>So, we might define <code>MemoryUsage</code> like this:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
public class MemoryUsage <b>implements Serializable</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    // standard JavaBean conventions with getters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    public MemoryUsage(long init, long used,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                       long committed, long max) {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    long getInit() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    long getUsed() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    long getCommitted() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    long getMax() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
public class MemoryUsage {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    // standard JavaBean conventions with getters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    <b>&#64;ConstructorProperties({"init", "used", "committed", "max"})</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    public MemoryUsage(long init, long used,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                       long committed, long max) {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    long getInit() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    long getUsed() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    long getCommitted() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    long getMax() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    <p>The definitions are the same in the two cases, except
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
      that with the MXBean, <code>MemoryUsage</code> no longer needs to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
      be marked <code>Serializable</code> (though it can be).  On
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
      the other hand, we have added a {@code @ConstructorProperties} annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
      to link the constructor parameters to the corresponding getters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
      We will see more about this below.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    <p><code>MemoryUsage</code> is a <em>model-specific class</em>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
      With Standard MBeans, a client of the MBean Server cannot access the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
      <code>Usage</code> attribute if it does not know the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
      <code>MemoryUsage</code>.  Suppose the client is a generic console
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
      based on JMX technology.  Then the console would have to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
      configured with the model-specific classes of every application it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
      might connect to.  The problem is even worse for clients that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
      not written in the Java language.  Then there may not be any way
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
      to tell the client what a <code>MemoryUsage</code> looks like.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    <p>This is where MXBeans differ from Standard MBeans.  Although we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
      define the management interface in almost exactly the same way,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
      the MXBean framework <em>converts</em> model-specific classes into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
      standard classes from the Java platform.  Using arrays and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
      {@link javax.management.openmbean.CompositeData CompositeData} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
      {@link javax.management.openmbean.TabularData TabularData} classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
      from the standard {@link javax.management.openmbean} package, it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
      is possible to build data structures of arbitrary complexity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
      using only standard classes.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    <p>This becomes clearer if we compare what the clients of the two
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
      models might look like:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
String name = (String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    mbeanServer.{@link MBeanServer#getAttribute
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    getAttribute}(objectName, "Name");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
<b>MemoryUsage</b> usage = (<b>MemoryUsage</b>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    mbeanServer.getAttribute(objectName, "Usage");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
<b>long used = usage.getUsed();</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
String name = (String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    mbeanServer.{@link MBeanServer#getAttribute
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    getAttribute}(objectName, "Name");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
<b>{@link CompositeData}</b> usage = (<b>CompositeData</b>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    mbeanServer.getAttribute(objectName, "Usage");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
<b>long used = (Long) usage.{@link CompositeData#get get}("used");</b>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    <p>For attributes with simple types like <code>String</code>, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
      code is the same.  But for attributes with complex types, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
      Standard MBean code requires the client to know the model-specific
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
      class <code>MemoryUsage</code>, while the MXBean code requires no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
      non-standard classes.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    <p>The client code shown here is slightly more complicated for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
      MXBean client.  But, if the client does in fact know the model,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
      here the interface <code>MemoryPoolMXBean</code> and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
      class <code>MemoryUsage</code>, then it can construct a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
      <em>proxy</em>.  This is the recommended way to interact with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
      managed objects when you know the model beforehand, regardless
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
      of whether you are using Standard MBeans or MXBeans:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
MemoryPool<b>MBean</b> proxy =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    JMX.<b>{@link JMX#newMBeanProxy(MBeanServerConnection, ObjectName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
              Class) newMBeanProxy}</b>(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        mbeanServer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        objectName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        MemoryPool<b>MBean</b>.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
String name = proxy.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
MemoryUsage usage = proxy.getUsage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
long used = usage.getUsed();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
MemoryPool<b>MXBean</b> proxy =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
    JMX.<b>{@link JMX#newMXBeanProxy(MBeanServerConnection, ObjectName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
              Class) newMXBeanProxy}</b>(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        mbeanServer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        objectName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        MemoryPool<b>MXBean</b>.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
String name = proxy.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
MemoryUsage usage = proxy.getUsage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
long used = usage.getUsed();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    <p>Implementing the MemoryPool object works similarly for both
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
      Standard MBeans and MXBeans.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
public class MemoryPool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        implements MemoryPool<b>MBean</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    public String getName() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    public MemoryUsage getUsage() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    // ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
public class MemoryPool
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        implements MemoryPool<b>MXBean</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    public String getName() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    public MemoryUsage getUsage() {...}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    // ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    <p>Registering the MBean in the MBean Server works in the same way
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
      in both cases:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        <th>Standard MBean</th><th>MXBean</th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    MemoryPool<b>MBean</b> pool = new MemoryPool();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    mbeanServer.{@link MBeanServer#registerMBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    registerMBean}(pool, objectName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        <td><pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
    MemoryPool<b>MXBean</b> pool = new MemoryPool();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    mbeanServer.{@link MBeanServer#registerMBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
    registerMBean}(pool, objectName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
          </pre></td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   321
    <h2 id="mxbean-def">Definition of an MXBean</h2>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    <p>An MXBean is a kind of MBean.  An MXBean object can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
      registered directly in the MBean Server, or it can be used as an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
      argument to {@link StandardMBean} and the resultant MBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
      registered in the MBean Server.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    <p>When an object is registered in the MBean Server using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
      {@code registerMBean} or {@code createMBean} methods of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
      {@link MBeanServer} interface, the object's class is examined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
      to determine what type of MBean it is:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
      <li>If the class implements the interface {@link DynamicMBean}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        then the MBean is a Dynamic MBean.  Note that the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        {@code StandardMBean} implements this interface, so this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        case applies to a Standard MBean or MXBean created using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        the class {@code StandardMBean}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
      <li>Otherwise, if the class matches the Standard MBean naming
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        conventions, then the MBean is a Standard MBean.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
      <li>Otherwise, it may be an MXBean.  The set of interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        implemented by the object is examined for interfaces that:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
          <li>have a class name <code><em>S</em>MXBean</code> where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            <code><em>S</em></code> is any non-empty string, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            do not have an annotation {@code @MXBean(false)}; and/or</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
          <li>have an annotation {@code @MXBean(true)}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            or just {@code @MXBean}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
        </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        If there is exactly one such interface, or if there is one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        such interface that is a subinterface of all the others, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        the object is an MXBean.  The interface in question is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        <em>MXBean interface</em>.  In the example above, the MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        interface is {@code MemoryPoolMXBean}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
      <li>If none of these conditions is met, the MBean is invalid and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        the attempt to register it will generate {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        NotCompliantMBeanException}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
    </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    <p>Every Java type that appears as the parameter or return type of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
      method in an MXBean interface must be <em>convertible</em> using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
      the rules below.  Additionally, parameters must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
      <em>reconstructible</em> as defined below.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    <p>An attempt to construct an MXBean that does not conform to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
      above rules will produce an exception.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   374
    <h2 id="naming-conv">Naming conventions</h2>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    <p>The same naming conventions are applied to the methods in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
      MXBean as in a Standard MBean:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
      <li>A method <code><em>T</em> get<em>N</em>()</code>, where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        <code><em>T</em></code> is a Java type (not <code>void</code>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        and <code><em>N</em></code> is a non-empty string, specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        that there is a readable attribute called
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        <code><em>N</em></code>.  The Java type and Open type of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        attribute are determined by the mapping rules below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        The method {@code final Class getClass()} inherited from {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        Object} is ignored when looking for getters.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
      <li>A method <code>boolean is<em>N</em>()</code> specifies that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        there is a readable attribute called <code><em>N</em></code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        with Java type <code>boolean</code> and Open type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        <code>SimpleType.Boolean</code>.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
      <li>A method <code>void set<em>N</em>(<em>T</em> x)</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        specifies that there is a writeable attribute called
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        <code><em>N</em></code>.  The Java type and Open type of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        attribute are determined by the mapping rules below.  (Of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        course, the name <code>x</code> of the parameter is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        irrelevant.)</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
      <li>Every other method specifies that there is an operation with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        the same name as the method.  The Java type and Open type of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        return value and of each parameter are determined by the mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        rules below.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    </ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    <p>The rules for <code>get<em>N</em></code> and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
      <code>is<em>N</em></code> collectively define the notion of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
      <em>getter</em>.  The rule for <code>set<em>N</em></code> defines
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
      the notion of a <em>setter</em>.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    <p>It is an error for there to be two getters with the same name, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
      two setters with the same name.  If there is a getter and a setter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
      for the same name, then the type <code><em>T</em></code> in both
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
      must be the same.  In this case the attribute is read/write.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
      there is only a getter or only a setter, the attribute is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
      read-only or write-only respectively.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   420
    <h2 id="mapping-rules">Type mapping rules</h2>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    <p>An MXBean is a kind of Open MBean, as defined by the {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
      javax.management.openmbean} package.  This means that the types of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
      attributes, operation parameters, and operation return values must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
      all be describable using <em>Open Types</em>, that is the four
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
      standard subclasses of {@link javax.management.openmbean.OpenType}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
      MXBeans achieve this by mapping Java types into Open Types.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    <p>For every Java type <em>J</em>, the MXBean mapping is described
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
      by the following information:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
      <li>The corresponding Open Type, <em>opentype(J)</em>.  This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        an instance of a subclass of {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        javax.management.openmbean.OpenType}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
      <li>The <em>mapped</em> Java type, <em>opendata(J)</em>, which is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        always the same for any given <em>opentype(J)</em>.  This is a Java
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        class.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
      <li>How a value is converted from type <em>J</em> to type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        <em>opendata(J)</em>.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
      <li>How a value is converted from type <em>opendata(J)</em> to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        type <em>J</em>, if it can be.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    <p>For example, for the Java type {@code List<String>}:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
      <li>The Open Type, <em>opentype(</em>{@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        List<String>}<em>)</em>, is {@link ArrayType}<code>(1, </code>{@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
          SimpleType#STRING}<code>)</code>, representing a 1-dimensional
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
          array of <code>String</code>s.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
      <li>The mapped Java type, <em>opendata(</em>{@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        List<String>}<em>)</em>, is {@code String[]}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
      <li>A {@code List<String>} can be converted to a {@code String[]}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
          using {@link List#toArray(Object[]) List.toArray(new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
          String[0])}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
      <li>A {@code String[]} can be converted to a {@code List<String>}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
          using {@link Arrays#asList Arrays.asList}.</li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    <p>If no mapping rules exist to derive <em>opentype(J)</em> from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
      <em>J</em>, then <em>J</em> cannot be the type of a method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
      parameter or return value in an MXBean interface.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    <p>If there is a way to convert <em>opendata(J)</em> back to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
      <em>J</em> then we say that <em>J</em> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
      <em>reconstructible</em>.  All method parameters in an MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
      interface must be reconstructible, because when the MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
      framework is invoking a method it will need to convert those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
      parameters from <em>opendata(J)</em> to <em>J</em>.  In a proxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
      generated by {@link JMX#newMXBeanProxy(MBeanServerConnection,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
      ObjectName, Class) JMX.newMXBeanProxy}, it is the return values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
      of the methods in the MXBean interface that must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
      reconstructible.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    <p>Null values are allowed for all Java types and Open Types,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
      except primitive Java types where they are not possible.  When
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
      converting from type <em>J</em> to type <em>opendata(J)</em> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
      from type <em>opendata(J)</em> to type <em>J</em>, a null value is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
      mapped to a null value.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   482
    <p>In addition to the default type mapping rules, you can specify
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   483
      custom type mappings, as described <a
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   484
      href="#custom">below</a>.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   485
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   486
    <p>The following table summarizes the default type mapping rules.</p>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    <table border="1" cellpadding="5">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
      <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        <th>Java type <em>J</em></th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        <th><em>opentype(J)</em></th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        <th><em>opendata(J)</em></th>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
      </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
      <tbody cellvalign="top">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
          <td>{@code int}, {@code boolean}, etc<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            (the 8 primitive Java types)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
          <td>{@code SimpleType.INTEGER},<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            {@code SimpleType.BOOLEAN}, etc</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
          <td>{@code Integer}, {@code Boolean}, etc<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            (the corresponding boxed types)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
          <td>{@code Integer}, {@code ObjectName}, etc<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
            (the types covered by {@link SimpleType})</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
          <td>the corresponding {@code SimpleType}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
          <td><em>J</em>, the same type</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
          <td>{@code int[]} etc<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            (a one-dimensional array with<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            primitive element type)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
          <td>{@code ArrayType.getPrimitiveArrayType(int[].class)} etc</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
          <td><em>J</em>, the same type</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
          <td><em>E</em>{@code []}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            (an array with non-primitive element type <em>E</em>;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
              this includes {@code int[][]}, where <em>E</em> is {@code int[]})</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
          <td>{@code ArrayType.getArrayType(}<em>opentype(E)</em>{@code )}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
          <td><em>opendata(E)</em>{@code []}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
          <td>{@code List<}<em>E</em>{@code >}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
            {@code Set<}<em>E</em>{@code >}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            {@code SortedSet<}<em>E</em>{@code >} (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
          <td>same as for <em>E</em>{@code []}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
          <td>same as for <em>E</em>{@code []}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
          <td>An enumeration <em>E</em><br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            (declared in Java as {@code enum }<em>E</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            {@code {...}})</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
          <td>{@code SimpleType.STRING}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
          <td>{@code String}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
          <td>{@code Map<}<em>K</em>,<em>V</em>{@code >}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            {@code SortedMap<}<em>K</em>,<em>V</em>{@code >}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
          <td>{@link TabularType}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
          <td>{@link TabularData}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
          <td>An MXBean interface</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
          <td>{@code SimpleType.OBJECTNAME}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
          <td>{@link ObjectName}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        </tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        <tr>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
          <td>Any other type</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
          <td>{@link CompositeType},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            if possible<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            (see below)</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
          <td>{@link CompositeData}</td>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
      </tbody>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    </table>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    <p>The following sections give further details of these rules.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    <h3>Mappings for primitive types</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    <p>The 8 primitive Java types
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
      ({@code boolean}, {@code byte}, {@code short}, {@code int}, {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
      long}, {@code float}, {@code double}, {@code char}) are mapped to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
      corresponding boxed types from {@code java.lang}, namely {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
      Boolean}, {@code Byte}, etc.  The Open Type is the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
      {@code SimpleType}.  Thus, <em>opentype(</em>{@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
      long}<em>)</em> is {@code SimpleType.LONG}, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
      <em>opendata(</em>{@code long}<em>)</em> is {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
      java.lang.Long}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    <p>An array of primitive type such as {@code long[]} can be represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
      directly as an Open Type.  Thus, <em>openType(</em>{@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
      long[]}<em>)</em> is {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
      ArrayType.getPrimitiveArrayType(long[].class)}, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
      <em>opendata(</em>{@code long[]}<em>)</em> is {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
      long[]}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    <p>In practice, the difference between a plain {@code int} and {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
      Integer}, etc, does not show up because operations in the JMX API
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
      are always on Java objects, not primitives.  However, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
      difference <em>does</em> show up with arrays.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    <h3>Mappings for collections ({@code List<}<em>E</em>{@code >} etc)</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    <p>A {@code List<}<em>E</em>{@code >} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
      Set<}<em>E</em>{@code >}, such as {@code List<String>} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        Set<ObjectName>}, is mapped in the same way as an array of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
          same element type, such as {@code String[]} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
          ObjectName[]}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    <p>A {@code SortedSet<}<em>E</em>{@code >} is also mapped in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
      same way as an <em>E</em>{@code []}, but it is only convertible if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
      <em>E</em> is a class or interface that implements {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
      java.lang.Comparable}.  Thus, a {@code SortedSet<String>} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        {@code SortedSet<Integer>} is convertible, but a {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
          SortedSet<int[]>} or {@code SortedSet<List<String>>} is not.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                conversion of a {@code SortedSet} instance will fail with an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                {@code IllegalArgumentException} if it has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                non-null {@link java.util.SortedSet#comparator()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                comparator()}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
    <p>A {@code List<}<em>E</em>{@code >} is reconstructed as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
      {@code java.util.ArrayList<}<em>E</em>{@code >};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
      a {@code Set<}<em>E</em>{@code >} as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
      {@code java.util.HashSet<}<em>E</em>{@code >};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
      a {@code SortedSet<}<em>E</em>{@code >} as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
      {@code java.util.TreeSet<}<em>E</em>{@code >}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
    <h3>Mappings for maps ({@code Map<}<em>K</em>,<em>V</em>{@code >} etc)</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    <p>A {@code Map<}<em>K</em>,<em>V</em>{@code >} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
      SortedMap<}<em>K</em>,<em>V</em>{@code >}, for example {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
      Map<String,ObjectName>}, has Open Type {@link TabularType} and is mapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        to a {@link TabularData}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        The {@code TabularType} has two items called {@code key} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        {@code value}.  The Open Type of {@code key} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        <em>opentype(K)</em>, and the Open Type of {@code value} is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        <em>opentype(V)</em>.  The index of the {@code TabularType} is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        single item {@code key}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    <p>For example, the {@code TabularType} for a {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
      Map<String,ObjectName>} might be constructed with code like
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        this:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
String typeName =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    "java.util.Map&lt;java.lang.String, javax.management.ObjectName&gt;";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
String[] keyValue =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    new String[] {"key", "value"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
OpenType[] openTypes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    new OpenType[] {SimpleType.STRING, SimpleType.OBJECTNAME};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
CompositeType rowType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    new CompositeType(typeName, typeName, keyValue, keyValue, openTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
TabularType tabularType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    new TabularType(typeName, typeName, rowType, new String[] {"key"});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    <p>The {@code typeName} here is determined by the <a href="#type-names">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
      type name rules</a> detailed below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    <p>A {@code SortedMap<}<em>K</em>,<em>V</em>{@code >} is mapped in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
      same way, but it is only convertible if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
      <em>K</em> is a class or interface that implements {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
      java.lang.Comparable}.  Thus, a {@code SortedMap<String,int[]>}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        is convertible, but a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        {@code SortedMap<int[],String>} is not.  The conversion of a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
          {@code SortedMap} instance will fail with an {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
          IllegalArgumentException} if it has a non-null {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
          java.util.SortedMap#comparator() comparator()}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    <p>A {@code Map<}<em>K</em>,<em>V</em>{@code >} is reconstructed as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
      a {@code java.util.HashMap<}<em>K</em>,<em>V</em>{@code >};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
      a {@code SortedMap<}<em>K</em>,<em>V</em>{@code >} as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
      a {@code java.util.TreeMap<}<em>K</em>,<em>V</em>{@code >}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    <p>{@code TabularData} is an interface.  The concrete class that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
      used to represent a {@code Map<}<em>K</em>,<em>V</em>{@code >} as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
      Open Data is {@link TabularDataSupport},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
      or another class implementing {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
      TabularData} that serializes as {@code TabularDataSupport}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   669
    <h3 id="mxbean-map">Mappings for MXBean interfaces</h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    <p>An MXBean interface, or a type referenced within an MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
      interface, can reference another MXBean interface, <em>J</em>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
      Then <em>opentype(J)</em> is {@code SimpleType.OBJECTNAME} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
      <em>opendata(J)</em> is {@code ObjectName}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
    <p>For example, suppose you have two MXBean interfaces like this:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
public interface ProductMXBean {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    public ModuleMXBean[] getModules();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
public interface ModuleMXBean {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
    public ProductMXBean getProduct();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    <p>The object implementing the {@code ModuleMXBean} interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
      returns from its {@code getProduct} method an object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
      implementing the {@code ProductMXBean} interface.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
      {@code ModuleMXBean} object and the returned {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
      ProductMXBean} objects must both be registered as MXBeans in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
      same MBean Server.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    <p>The method {@code ModuleMXBean.getProduct()} defines an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
      attribute called {@code Product}.  The Open Type for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
      attribute is {@code SimpleType.OBJECTNAME}, and the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
      {@code ObjectName} value will be the name under which the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
      referenced {@code ProductMXBean} is registered in the MBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
      Server.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    <p>If you make an MXBean proxy for a {@code ModuleMXBean} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
      call its {@code getProduct()} method, the proxy will map the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
      {@code ObjectName} back into a {@code ProductMXBean} by making
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
      another MXBean proxy.  More formally, when a proxy made with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
      {@link JMX#newMXBeanProxy(MBeanServerConnection, ObjectName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
       Class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
      JMX.newMXBeanProxy(mbeanServerConnection, objectNameX,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
      interfaceX)} needs to map {@code objectNameY} back into {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
      interfaceY}, another MXBean interface, it does so with {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
      JMX.newMXBeanProxy(mbeanServerConnection, objectNameY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
      interfaceY)}.  The implementation may return a proxy that was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
      previously created by a call to {@code JMX.newMXBeanProxy}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
      with the same parameters, or it may create a new proxy.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
    <p>The reverse mapping is illustrated by the following change to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
      {@code ModuleMXBean} interface:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
public interface ModuleMXBean {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    public ProductMXBean getProduct();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
    public void setProduct(ProductMXBean c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    <p>The presence of the {@code setProduct} method now means that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
      {@code Product} attribute is read/write.  As before, the value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
      of this attribute is an {@code ObjectName}.  When the attribute is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
      set, the {@code ObjectName} must be converted into the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
      {@code ProductMXBean} object that the {@code setProduct} method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
      expects.  This object will be an MXBean proxy for the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
      {@code ObjectName} in the same MBean Server.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    <p>If you make an MXBean proxy for a {@code ModuleMXBean} and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
      call its {@code setProduct} method, the proxy will map its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
      {@code ProductMXBean} argument back into an {@code ObjectName}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
      This will only work if the argument is in fact another proxy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
      for a {@code ProductMXBean} in the same {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
      MBeanServerConnection}.  The proxy can have been returned from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
      another proxy (like {@code ModuleMXBean.getProduct()} which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
      returns a proxy for a {@code ProductMXBean}); or it can have
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
      been created by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
      JMX#newMXBeanProxy(MBeanServerConnection, ObjectName, Class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
      JMX.newMXBeanProxy}; or it can have been created using {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
      java.lang.reflect.Proxy Proxy} with an invocation handler that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
      is {@link MBeanServerInvocationHandler} or a subclass.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    <p>If the same MXBean were registered under two different
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
      {@code ObjectName}s, a reference to that MXBean from another
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
      MXBean would be ambiguous.  Therefore, if an MXBean object is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
      already registered in an MBean Server and an attempt is made to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
      register it in the same MBean Server under another name, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
      result is an {@link InstanceAlreadyExistsException}.  Registering
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
      the same MBean object under more than one name is discouraged in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
      general, notably because it does not work well for MBeans that are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
      {@link NotificationBroadcaster}s.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
   758
    <h3 id="composite-map">Mappings for other types</h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    <p>Given a Java class or interface <em>J</em> that does not match the other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
      rules in the table above, the MXBean framework will attempt to map
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
      it to a {@link CompositeType} as follows.  The type name of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
      {@code CompositeType} is determined by the <a href="#type-names">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
      type name rules</a> below.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
    <p>The class is examined for getters using the conventions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
      <a href="#naming-conv">above</a>.  (Getters must be public
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
      instance methods.)  If there are no getters, or if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
      any getter has a type that is not convertible, then <em>J</em> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
      not convertible.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    <p>If there is at least one getter and every getter has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
      convertible type, then <em>opentype(J)</em> is a {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
      CompositeType} with one item for every getter.  If the getter is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
    <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
      <code><em>T</em> get<em>Name</em>()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    then the item in the {@code CompositeType} is called {@code name}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
    and has type <em>opentype(T)</em>.  For example, if the item is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
      <code>String getOwner()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
    then the item is called {@code owner} and has Open Type {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    SimpleType.STRING}.  If the getter is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
      <code>boolean is<em>Name</em>()</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    then the item in the {@code CompositeType} is called {@code name}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
    and has type {@code SimpleType.BOOLEAN}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    <p>Notice that the first character (or code point) is converted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
      lower case.  This follows the Java Beans convention, which for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
      historical reasons is different from the Standard MBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
      convention.  In a Standard MBean or MXBean interface, a method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
      {@code getOwner} defines an attribute called {@code Owner}, while
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
      in a Java Bean or mapped {@code CompositeType}, a method {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
      getOwner} defines a property or item called {@code owner}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    <p>If two methods produce the same item name (for example, {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
      getOwner} and {@code isOwner}, or {@code getOwner} and {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
      getowner}) then the type is not convertible.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
    <p>When the Open Type is {@code CompositeType}, the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
      mapped Java type (<em>opendata(J)</em>) is {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
      CompositeData}.  The mapping from an instance of <em>J</em> to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
      {@code CompositeData} corresponding to the {@code CompositeType}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
      just described is done as follows.  First, if <em>J</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
      implements the interface {@link CompositeDataView}, then that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
      interface's {@link CompositeDataView#toCompositeData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
      toCompositeData} method is called to do the conversion.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
      Otherwise, the {@code CompositeData} is constructed by calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
      the getter for each item and converting it to the corresponding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
      Open Data type.  Thus, a getter such as</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
      {@code List<String> getNames()}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
    <p>will have been mapped to an item with name "{@code names}" and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
      Open Type {@code ArrayType(1, SimpleType.STRING)}.  The conversion
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
      to {@code CompositeData} will call {@code getNames()} and convert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
      the resultant {@code List<String>} into a {@code String[]} for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        item "{@code names}".</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
    <p>{@code CompositeData} is an interface.  The concrete class that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
      used to represent a type as Open Data is {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
      CompositeDataSupport}, or another class implementing {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
      CompositeData} that serializes as {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
      CompositeDataSupport}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    <h4>Reconstructing an instance of Java type <em>J</em> from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
      a {@code CompositeData}</h4>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    <p>If <em>opendata(J)</em> is {@code CompositeData} for a Java type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
      <em>J</em>, then either an instance of <em>J</em> can be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
      reconstructed from a {@code CompositeData}, or <em>J</em> is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
      reconstructible.  If any item in the {@code CompositeData} is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
      reconstructible, then <em>J</em> is not reconstructible either.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    <p>For any given <em>J</em>, the following rules are consulted to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
      determine how to reconstruct instances of <em>J</em> from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
      {@code CompositeData}.  The first applicable rule in the list is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
      the one that will be used.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
    <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
      <li><p>If <em>J</em> has a method<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        {@code public static }<em>J </em>{@code from(CompositeData cd)}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        then that method is called to reconstruct an instance of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        <em>J</em>.</p></li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
      <li><p>Otherwise, if <em>J</em> has at least one public
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        constructor with a {@link ConstructorProperties} annotation, then one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        of those constructors (not necessarily always the same one)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
        will be called to reconstruct an instance of <em>J</em>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        Every such annotation must list as many strings as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        constructor has parameters; each string must name a property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        corresponding to a getter of <em>J</em>; and the type of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
        getter must be the same as the corresponding constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        parameter.  It is not an error for there to be getters that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
        are not mentioned in the {@code ConstructorProperties} annotation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        (these may correspond to information that is not needed to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        reconstruct the object).</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        <p>An instance of <em>J</em> is reconstructed by calling a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        constructor with the appropriate reconstructed items from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        {@code CompositeData}.  The constructor to be called will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
        determined at runtime based on the items actually present in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        the {@code CompositeData}, given that this {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        CompositeData} might come from an earlier version of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        <em>J</em> where not all the items were present.  A
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        constructor is <em>applicable</em> if all the properties named
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
        in its {@code ConstructorProperties} annotation are present as items
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        in the {@code CompositeData}.  If no constructor is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        applicable, then the attempt to reconstruct <em>J</em> fails.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        <p>For any possible combination of properties, it must be the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
        case that either (a) there are no applicable constructors, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        (b) there is exactly one applicable constructor, or (c) one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        the applicable constructors names a proper superset of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
        properties named by each other applicable constructor.  (In
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        other words, there should never be ambiguity over which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        constructor to choose.)  If this condition is not true, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        <em>J</em> is not reconstructible.</p></li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
      <li><p>Otherwise, if <em>J</em> has a public no-arg constructor, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        for every getter in <em>J</em> with type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
        <em>T</em> and name <em>N</em> there is a corresponding setter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
        with the same name and type, then an instance of <em>J</em> is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        constructed with the no-arg constructor and the setters are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
        called with the reconstructed items from the {@code CompositeData}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        to restore the values.  For example, if there is a method<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        {@code public List<String> getNames()}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
          then there must also be a method<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
          {@code public void setNames(List<String> names)}<br>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            for this rule to apply.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        <p>If the {@code CompositeData} came from an earlier version of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
        <em>J</em>, some items might not be present.  In this case,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        the corresponding setters will not be called.</p></li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
      <li><p>Otherwise, if <em>J</em> is an interface that has no methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        other than getters, an instance of <em>J</em> is constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
        using a {@link java.lang.reflect.Proxy} with a {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        CompositeDataInvocationHandler} backed by the {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
        CompositeData} being converted.</p></li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
      <li><p>Otherwise, <em>J</em> is not reconstructible.</p></li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    </ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
    <p>Here are examples showing different ways to code a type {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
      NamedNumber} that consists of an {@code int} and a {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
      String}.  In each case, the {@code CompositeType} looks like this:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
      <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
{@link CompositeType}(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    "NamedNumber",                      // typeName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    "NamedNumber",                      // description
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
    new String[] {"number", "name"},    // itemNames
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    new String[] {"number", "name"},    // itemDescriptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
    new OpenType[] {SimpleType.INTEGER,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
                    SimpleType.STRING}  // itemTypes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
      </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
    <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
      <li>Static {@code from} method:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
          <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
public class NamedNumber {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    public int getNumber() {return number;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    public String getName() {return name;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
    private NamedNumber(int number, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
        this.number = number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        this.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
    <b>public static NamedNumber from(CompositeData cd)</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        return new NamedNumber((Integer) cd.get("number"),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
                               (String) cd.get("name"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    private final int number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
    private final String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
          </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
      </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
      <li>Public constructor with <code>&#64;ConstructorProperties</code> annotation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
          <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
public class NamedNumber {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
    public int getNumber() {return number;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
    public String getName() {return name;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    <b>&#64;ConstructorProperties({"number", "name"})
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
    public NamedNumber(int number, String name)</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        this.number = number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        this.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    private final int number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
    private final String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
          </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
      </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
      <li>Setter for every getter:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
          <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
public class NamedNumber {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    public int getNumber() {return number;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    public void <b>setNumber</b>(int number) {this.number = number;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    public String getName() {return name;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    public void <b>setName</b>(String name) {this.name = name;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    <b>public NamedNumber()</b> {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
    private int number;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    private String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
          </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
        </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
      </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
      <li>Interface with only getters:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
        <blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
          <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
public interface NamedNumber {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    public int getNumber();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    public String getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
          </pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        </blockquote>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
      </li>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
    </ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
    <p>It is usually better for classes that simply represent a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
      collection of data to be <em>immutable</em>.  An instance of an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
      immutable class cannot be changed after it has been constructed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
      Notice that {@code CompositeData} itself is immutable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
      Immutability has many advantages, notably with regard to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
      thread-safety and security.  So the approach using setters should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
      generally be avoided if possible.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
    <h3>Recursive types</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
    <p>Recursive (self-referential) types cannot be used in MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
      interfaces.  This is a consequence of the immutability of {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
      CompositeType}.  For example, the following type could not be the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
      type of an attribute, because it refers to itself:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
public interface <b>Node</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
    public String getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
    public int getPriority();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
    public <b>Node</b> getNext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
</pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    <p>It is always possible to rewrite recursive types like this so
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
      they are no longer recursive.  Doing so may require introducing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
      new types.  For example:</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
    <pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
public interface <b>NodeList</b> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
    public List&lt;Node&gt; getNodes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
public interface Node {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
    public String getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
    public int getPriority();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
</pre>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1046
    <p>Alternatively, you can define a custom mapping for your recursive
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1047
      type; see the next section.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1048
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1049
    <h3 id="custom">Custom MXBean type mappings</h3>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1050
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1051
    <p>You can augment or replace the default type mappings described
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1052
      above with custom mappings.  An example appears in the
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1053
      documentation for {@link MXBeanMapping}.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1054
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1055
    <p>If an MXBean uses custom mappings, then an MXBean proxy for
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1056
      that MXBean must use the same mappings for correct behavior.
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1057
      This requires more careful synchronization between client and
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1058
      server than is necessary with the default mappings.  For example
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1059
      it typically requires the client to have the same implementation
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1060
      of any {@link MXBeanMapping} subclasses as the server.  For this
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1061
      reason, custom mappings should be avoided if possible.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1062
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1063
    <p>Every MXBean has an associated {@link MXBeanMappingFactory}.
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1064
      Call this <code><em>f</em></code>.  Then every type that appears
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1065
      in that MXBean has an associated {@link MXBeanMapping}
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1066
      determined by <code><em>f</em></code>.  If the type is
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1067
      <code><em>J</em></code>, say, then the mapping is {@link
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1068
      MXBeanMappingFactory#mappingForType
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1069
      <em>f</em>.mappingForType}<code>(<em>J</em>,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1070
      <em>f</em>)</code>.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1071
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1072
    <p>The {@code MXBeanMappingFactory} <code><em>f</em></code> for an
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1073
      MXBean is determined as follows.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1074
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1075
    <ul>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1076
      <li><p>If an {@link JMX.MBeanOptions} argument is supplied to
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1077
          the {@link StandardMBean} constructor that makes an MXBean,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1078
          or to the {@link JMX#newMXBeanProxy JMX.newMXBeanProxy}
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1079
          method, and the {@code MBeanOptions} object defines a non-null
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1080
          {@code MXBeanMappingFactory}, then that is the value of
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1081
          <code><em>f</em></code>.</p></li>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1082
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1083
      <li><p>Otherwise, if the MXBean interface has an {@link
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1084
          MXBeanMappingFactoryClass} annotation, then that annotation
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1085
          must identify a subclass of {@code MXBeanMappingFactory}
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1086
          with a no-argument constructor.  Then
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1087
          <code><em>f</em></code> is the result of calling this
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1088
          constructor.  If the class does not have a no-argument
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1089
          constructor, or if calling the constructor produces an
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1090
          exception, then the MXBean is invalid and an attempt to
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1091
          register it in the MBean Server will produce a {@link
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1092
          NotCompliantMBeanException}.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1093
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1094
        <p>This annotation is not inherited from any parent
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1095
          interfaces.  If an MXBean interface has this annotation,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1096
          then usually any MXBean subinterfaces must repeat the same
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1097
          annotation for correct behavior.</p></li>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1098
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1099
      <li><p>Otherwise, if the package in which the MXBean interface
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1100
          appears has an {@code MXBeanMappingFactoryClass} annotation,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1101
          then <code><em>f</em></code> is determined as if that
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1102
          annotation appeared on the MXBean interface.</p></li>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1103
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1104
      <li><p>Otherwise, <code><em>f</em></code> is the default mapping
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1105
          factory, {@link MXBeanMappingFactory#DEFAULT}.</p></li>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1106
    </ul>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1107
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1108
    <p>The default mapping factory recognizes the {@link
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1109
      MXBeanMappingClass} annotation on a class or interface.  If
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1110
      <code><em>J</em></code> is a class or interface that has such an
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1111
      annotation, then the {@code MXBeanMapping} for
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1112
      <code><em>J</em></code> produced by the default mapping factory
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1113
      will be determined by the value of the annotation as described
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1114
      in its {@linkplain MXBeanMappingClass documentation}.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1115
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    <h3>MBeanInfo contents for an MXBean</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    <p>An MXBean is a type of Open MBean.  However, for compatibility
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
      reasons, its {@link MBeanInfo} is not an {@link OpenMBeanInfo}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
      In particular, when the type of an attribute, parameter, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
      operation return value is a primitive type such as {@code int},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
      or is {@code void} (for a return type), then the attribute,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
      parameter, or operation will be represented respectively by an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
      {@link MBeanAttributeInfo}, {@link MBeanParameterInfo}, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
      {@link MBeanOperationInfo} whose {@code getType()} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
      getReturnType()} returns the primitive name ("{@code int}" etc).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
      This is so even though the mapping rules above specify that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
      <em>opendata</em> mapping is the wrapped type ({@code Integer}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
      etc).</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
    <p>The array of public constructors returned by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
      MBeanInfo#getConstructors()} for an MXBean that is directly
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
      registered in the MBean Server will contain all of the public
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
      constructors of that MXBean.  If the class of the MXBean is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
      public then its constructors are not considered public either.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
      The list returned for an MXBean that is constructed using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
      {@link StandardMBean} class is derived in the same way as for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
      Standard MBeans.  Regardless of how the MXBean was constructed,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
      its constructor parameters are not subject to MXBean mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
      rules and do not have a corresponding {@code OpenType}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
    <p>The array of notification types returned by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
      MBeanInfo#getNotifications()} for an MXBean that is directly
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
      registered in the MBean Server will be empty if the MXBean does
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
      not implement the {@link NotificationBroadcaster} interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
      Otherwise, it will be the result of calling {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
      NotificationBroadcaster#getNotificationInfo()} at the time the MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
      was registered.  Even if the result of this method changes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
      subsequently, the result of {@code MBeanInfo.getNotifications()}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
      will not.  The list returned for an MXBean that is constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
      using the {@link StandardMBean} or {@link StandardEmitterMBean}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
      class is derived in the same way as for Standard MBeans.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
    <p>The {@link Descriptor} for all of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
      {@code MBeanAttributeInfo}, {@code MBeanParameterInfo}, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
      {@code MBeanOperationInfo} objects contained in the {@code MBeanInfo}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
      will have a field {@code openType} whose value is the {@link OpenType}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
      specified by the mapping rules above.  So even when {@code getType()}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
      is "{@code int}", {@code getDescriptor().getField("openType")} will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
      be {@link SimpleType#INTEGER}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    <p>The {@code Descriptor} for each of these objects will also have a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
      field {@code originalType} that is a string representing the Java type
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
      that appeared in the MXBean interface.  The format of this string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
      is described in the section <a href="#type-names">Type Names</a>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
      below.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
    <p>The {@code Descriptor} for the {@code MBeanInfo} will have a field
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
      {@code mxbean} whose value is the string "{@code true}".</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1172
    <h3 id="type-names">Type Names</h3>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
    <p>Sometimes the unmapped type <em>T</em> of a method parameter or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    return value in an MXBean must be represented as a string.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
    <em>T</em> is a non-generic type, this string is the value
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    returned by {@link Class#getName()}.  Otherwise it is the value of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
    <em>genericstring(T)</em>, defined as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
    <ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
      <li>If <em>T</em> is a non-generic non-array type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
      <em>genericstring(T)</em> is the value returned by {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
      Class#getName()}, for example {@code "int"} or {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
      "java.lang.String"}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
      <li>If <em>T</em> is an array <em>E[]</em>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
      <em>genericstring(T)</em> is <em>genericstring(E)</em> followed
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
      by {@code "[]"}.  For example, <em>genericstring({@code int[]})</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
      is {@code "int[]"}, and <em>genericstring({@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
      List<String>[][]})</em> is {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
      "java.util.List<java.lang.String>[][]"}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
    <li>Otherwise, <em>T</em> is a parameterized type such as {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
    List<String>} and <em>genericstring(T)</em> consists of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
    following: the fully-qualified name of the parameterized type as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
    returned by {@code Class.getName()}; a left angle bracket ({@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
    "<"}); <em>genericstring(A)</em> where <em>A</em> is the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
    type parameter; if there is a second type parameter <em>B</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
    then {@code ", "} (a comma and a single space) followed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
    <em>genericstring(B)</em>; a right angle bracket ({@code ">"}).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
    </ul>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
    <p>Note that if a method returns {@code int[]}, this will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
      represented by the string {@code "[I"} returned by {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
      Class.getName()}, but if a method returns {@code List<int[]>},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
      this will be represented by the string {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
      "java.util.List<int[]>"}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
    <h3>Exceptions</h3>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
    <p>A problem with mapping <em>from</em> Java types <em>to</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
      Open types is signaled with an {@link OpenDataException}.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
      can happen when an MXBean interface is being analyzed, for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
      example if it references a type like {@link java.util.Random
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
      java.util.Random} that has no getters.  Or it can happen when an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
      instance is being converted (a return value from a method in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
      MXBean or a parameter to a method in an MXBean proxy), for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
      example when converting from {@code SortedSet<String>} to {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
      String[]} if the {@code SortedSet} has a non-null {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
      Comparator}.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
    <p>A problem with mapping <em>to</em> Java types <em>from</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
      Open types is signaled with an {@link InvalidObjectException}.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
      This can happen when an MXBean interface is being analyzed, for
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
      example if it references a type that is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
      <em>reconstructible</em> according to the rules above, in a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
      context where a reconstructible type is required.  Or it can
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
      happen when an instance is being converted (a parameter to a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
      method in an MXBean or a return value from a method in an MXBean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
      proxy), for example from a String to an Enum if there is no Enum
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
      constant with that name.</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
    <p>Depending on the context, the {@code OpenDataException} or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
      {@code InvalidObjectException} may be wrapped in another
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
      exception such as {@link RuntimeMBeanException} or {@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
      UndeclaredThrowableException}.  For every thrown exception,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
      the condition <em>C</em> will be true: "<em>e</em> is {@code
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
      OpenDataException} or {@code InvalidObjectException} (as
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
      appropriate), or <em>C</em> is true of <em>e</em>.{@link
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
      Throwable#getCause() getCause()}".</p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1244
   @see MXBeanMapping
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 2
diff changeset
  1245
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
   @since 1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
@Documented
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
@Retention(RetentionPolicy.RUNTIME)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
@Target(ElementType.TYPE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
public @interface MXBean {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
       True if the annotated interface is an MXBean interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
       @return true if the annotated interface is an MXBean interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
    boolean value() default true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
}