jdk/src/share/classes/javax/management/GenericMBeanException.java
changeset 4156 acaa49a2768a
parent 4155 460e37d40f12
child 4159 9e3aae7675f1
equal deleted inserted replaced
4155:460e37d40f12 4156:acaa49a2768a
     1 /*
       
     2  * Copyright 2008 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package javax.management;
       
    27 
       
    28 import javax.management.openmbean.CompositeData;
       
    29 
       
    30 /**
       
    31  * <p>A customizable exception that has an optional error code string and
       
    32  * payload.  By using this exception in an MBean, you can avoid requiring
       
    33  * clients of the MBean to have custom exception classes.</p>
       
    34  *
       
    35  * <p>An instance of this class has an optional {@linkplain #getErrorCode()
       
    36  * error code}, and an optional {@linkplain #getUserData() payload} known as
       
    37  * {@code userData}.  This allows you to distinguish between different
       
    38  * sorts of exception while still using this class for all of them.</p>
       
    39  *
       
    40  * <p>To produce a suitable {@code userData}, it is often simplest to use
       
    41  * the MXBean framework.  For example, suppose you want to convey a severity
       
    42  * and a subsystem with your exception, which are respectively an int and a
       
    43  * String.  You could define a class like this:</p>
       
    44  *
       
    45  * <pre>
       
    46  * public class ExceptionDetails {
       
    47  *     private final int severity;
       
    48  *     private final String subsystem;
       
    49  *
       
    50  *     {@link java.beans.ConstructorProperties &#64;ConstructorProperties}(<!--
       
    51  * -->{"severity", "subsystem"})
       
    52  *     public ExceptionDetails(int severity, String subsystem) {
       
    53  *         this.severity = severity;
       
    54  *         this.subsystem = subsystem;
       
    55  *     }
       
    56  *
       
    57  *     public int getSeverity() {
       
    58  *         return severity;
       
    59  *     }
       
    60  *
       
    61  *     public String getSubsystem() {
       
    62  *         return subsystem;
       
    63  *     }
       
    64  * }
       
    65  * </pre>
       
    66  *
       
    67  * <p>Then you can get the MXBean framework to transform {@code ExceptionDetails}
       
    68  * into {@link CompositeData} like this:</p>
       
    69  *
       
    70  * <pre>
       
    71  * static final <!--
       
    72  * -->{@link javax.management.openmbean.MXBeanMapping MXBeanMapping} <!--
       
    73  * -->exceptionDetailsMapping = <!--
       
    74  * -->{@link javax.management.openmbean.MXBeanMappingFactory#DEFAULT
       
    75  *     MXBeanMappingFactory.DEFAULT}.mappingForType(
       
    76  *         ExceptionDetails.class, MXBeanMappingFactory.DEFAULT);
       
    77  *
       
    78  * public static GenericMBeanException newGenericMBeanException(
       
    79  *         String message, String errorCode, int severity, String subsystem) {
       
    80  *     ExceptionDetails details = new ExceptionDetails(severity, subsystem);
       
    81  *     CompositeData userData = (CompositeData)
       
    82  *             exceptionDetailsMapping.toOpenValue(details);
       
    83  *     return new GenericMBeanException(
       
    84  *             message, errorCode, userData, (Throwable) null);
       
    85  * }
       
    86  *
       
    87  * ...
       
    88  *     throw newGenericMBeanException(message, errorCode, 25, "foosystem");
       
    89  * </pre>
       
    90  *
       
    91  * <p>A client that knows the {@code ExceptionDetails} class can convert
       
    92  * back from the {@code userData} of a {@code GenericMBeanException}
       
    93  * that was generated as above:</p>
       
    94  *
       
    95  * <pre>
       
    96  * ...
       
    97  *     try {
       
    98  *         mbeanProxy.foo();
       
    99  *     } catch (GenericMBeanException e) {
       
   100  *         CompositeData userData = e.getUserData();
       
   101  *         ExceptionDetails details = (ExceptionDetails)
       
   102  *                 exceptionDetailsMapping.fromOpenValue(userData);
       
   103  *         System.out.println("Exception Severity: " + details.getSeverity());
       
   104  *     }
       
   105  * ...
       
   106  * </pre>
       
   107  *
       
   108  * <p>The Descriptor field <a href="Descriptor.html#exceptionErrorCodes"><!--
       
   109  * -->exceptionErrorCodes</a> can be used to specify in the
       
   110  * {@link MBeanOperationInfo} for an operation what the possible
       
   111  * {@linkplain #getErrorCode() error codes} are when that operation throws
       
   112  * {@code GenericMBeanException}.  It can also be used in an {@link
       
   113  * MBeanConstructorInfo} or {@link MBeanAttributeInfo} to specify what the
       
   114  * possible error codes are for {@code GenericMBeanException} when invoking
       
   115  * that constructor or getting that attribute, respectively.  The field
       
   116  * <a href="Descriptor.html#setExceptionErrorCodes"><!--
       
   117  * -->setExceptionErrorCodes</a> can be used to specify what the possible
       
   118  * error codes are when setting an attribute.</p>
       
   119  *
       
   120  * <p>You may want to use the {@link DescriptorKey &#64;DescriptorKey} facility
       
   121  * to define annotations that allow you to specify the error codes.  If you
       
   122  * define...</p>
       
   123  *
       
   124  * <pre>
       
   125  * {@link java.lang.annotation.Documented &#64;Documented}
       
   126  * {@link java.lang.annotation.Target &#64;Target}(ElementType.METHOD)
       
   127  * {@link java.lang.annotation.Retention &#64;Retention}(RetentionPolicy.RUNTIME)
       
   128  * public &#64;interface ErrorCodes {
       
   129  *     &#64;DescriptorKey("exceptionErrorCodes")
       
   130  *     String[] value();
       
   131  * }
       
   132  * </pre>
       
   133  *
       
   134  * <p>...then you can write MBean interfaces like this...</p>
       
   135  *
       
   136  * <pre>
       
   137  * public interface FooMBean {  // or FooMXBean
       
   138  *     &#64;ErrorCodes({"com.example.bad", "com.example.worse"})
       
   139  *     public void foo() throws GenericMBeanException;
       
   140  * }
       
   141  * </pre>
       
   142  *
       
   143  * <p>The Descriptor field <a href="Descriptor.html#exceptionUserDataTypes"><!--
       
   144  * -->exceptionUserDataTypes</a> can be used to specify in the
       
   145  * {@link MBeanOperationInfo} for an operation what the possible types of
       
   146  * {@linkplain #getUserData() userData} are when that operation throws
       
   147  * {@code GenericMBeanException}.  It is an array of
       
   148  * {@link javax.management.openmbean.CompositeType CompositeType} values
       
   149  * describing the possible {@link CompositeData} formats.  This field can also be used
       
   150  * in an {@link MBeanConstructorInfo} or {@link MBeanAttributeInfo} to specify
       
   151  * the possible types of user data for {@code GenericMBeanException} when
       
   152  * invoking that constructor or getting that attribute, respectively.  The
       
   153  * field
       
   154  * <a href="Descriptor.html#setExceptionUserDataTypes">setExceptionUserDataTypes</a>
       
   155  * can be used to specify the possible types of user data for exceptions when
       
   156  * setting an attribute.  If a Descriptor has both {@code exceptionErrorCodes}
       
   157  * and {@code exceptionUserDataTypes} then the two arrays should be the
       
   158  * same size; each pair of corresponding elements describes one kind
       
   159  * of exception.  Similarly for {@code setExceptionErrorCodes} and {@code
       
   160  * setExceptionUserDataTypes}.
       
   161  *
       
   162  *
       
   163  * <h4>Serialization</h4>
       
   164  *
       
   165  * <p>For compatibility reasons, instances of this class are serialized as
       
   166  * instances of {@link MBeanException}.  Special logic in that class converts
       
   167  * them back to instances of this class at deserialization time.  If the
       
   168  * serialized object is deserialized in an earlier version of the JMX API
       
   169  * that does not include this class, then it will appear as just an {@code
       
   170  * MBeanException} and the error code or userData will not be available.</p>
       
   171  *
       
   172  * @since 1.7
       
   173  */
       
   174 public class GenericMBeanException extends MBeanException {
       
   175     private static final long serialVersionUID = -1560202003985932823L;
       
   176 
       
   177     /**
       
   178      * <p>Constructs a new {@code GenericMBeanException} with the given
       
   179      * detail message.  This constructor is
       
   180      * equivalent to {@link #GenericMBeanException(String, String,
       
   181      * CompositeData, Throwable) GenericMBeanException(message, "",
       
   182      * null, null)}.</p>
       
   183      *
       
   184      * @param message the exception detail message.
       
   185      */
       
   186     public GenericMBeanException(String message) {
       
   187         this(message, "", null, null);
       
   188     }
       
   189 
       
   190     /**
       
   191      * <p>Constructs a new {@code GenericMBeanException} with the given
       
   192      * detail message and cause.  This constructor is
       
   193      * equivalent to {@link #GenericMBeanException(String, String,
       
   194      * CompositeData, Throwable) GenericMBeanException(message, "",
       
   195      * null, cause)}.</p>
       
   196      *
       
   197      * @param message the exception detail message.
       
   198      * @param cause the cause of this exception.  Can be null.
       
   199      */
       
   200     public GenericMBeanException(String message, Throwable cause) {
       
   201         this(message, "", null, cause);
       
   202     }
       
   203 
       
   204     /**
       
   205      * <p>Constructs a new {@code GenericMBeanException} with the given
       
   206      * detail message, error code, and user data.  This constructor is
       
   207      * equivalent to {@link #GenericMBeanException(String, String,
       
   208      * CompositeData, Throwable) GenericMBeanException(message, errorCode,
       
   209      * userData, null)}.</p>
       
   210      *
       
   211      * @param message the exception detail message.
       
   212      * @param errorCode the exception error code.  Specifying a null value
       
   213      * is equivalent to specifying an empty string.  It is recommended to use
       
   214      * the same reverse domain name convention as package names, for example
       
   215      * "com.example.foo.UnexpectedFailure".  There is no requirement that the
       
   216      * error code be a syntactically valid Java identifier.
       
   217      * @param userData extra information about the exception.  Can be null.
       
   218      */
       
   219     public GenericMBeanException(
       
   220             String message, String errorCode, CompositeData userData) {
       
   221         this(message, errorCode, userData, null);
       
   222     }
       
   223 
       
   224     /**
       
   225      * <p>Constructs a new {@code GenericMBeanException} with the given
       
   226      * detail message, error code, user data, and cause.</p>
       
   227      *
       
   228      * @param message the exception detail message.
       
   229      * @param errorCode the exception error code.  Specifying a null value
       
   230      * is equivalent to specifying an empty string.  It is recommended to use
       
   231      * the same reverse domain name convention as package names, for example
       
   232      * "com.example.foo.UnexpectedFailure".  There is no requirement that the
       
   233      * error code be a syntactically valid Java identifier.
       
   234      * @param userData extra information about the exception.  Can be null.
       
   235      * @param cause the cause of this exception.  Can be null.
       
   236      */
       
   237     public GenericMBeanException(
       
   238             String message, String errorCode, CompositeData userData,
       
   239             Throwable cause) {
       
   240         super(message, (errorCode == null) ? "" : errorCode, userData, cause);
       
   241     }
       
   242 
       
   243     /**
       
   244      * <p>Returns the error code of this exception.</p>
       
   245      *
       
   246      * @return the error code.  This value is never null.
       
   247      */
       
   248     public String getErrorCode() {
       
   249         return errorCode;
       
   250     }
       
   251 
       
   252     /**
       
   253      * <p>Returns the userData of this exception.</p>
       
   254      *
       
   255      * @return the userData.  Can be null.
       
   256      */
       
   257     public CompositeData getUserData() {
       
   258         return userData;
       
   259     }
       
   260 
       
   261     /**
       
   262      * <p>Instances of this class are serialized as instances of
       
   263      * {@link MBeanException}.  {@code MBeanException} has private fields that can
       
   264      * not be set by its public constructors.  They can only be set in objects
       
   265      * returned by this method.  When an {@code MBeanException} instance is
       
   266      * deserialized, if those fields are present then its {@code readResolve}
       
   267      * method will substitute a {@code GenericMBeanException} equivalent to
       
   268      * this one.</p>
       
   269      */
       
   270     Object writeReplace() {
       
   271         MBeanException x = new MBeanException(
       
   272                 getMessage(), errorCode, userData, getCause());
       
   273         x.setStackTrace(this.getStackTrace());
       
   274         return x;
       
   275     }
       
   276 }