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