1 /*
   2  * Copyright (c) 2004, 2008, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 5035217 6766173
  27  * @summary Test that MBean's RuntimeException is wrapped in
  28  * RuntimeMBeanException and (for Standard MBeans) that checked exceptions
  29  * are wrapped in MBeanException
  30  * @author Eamonn McManus
  31  * @compile MBeanExceptionTest.java
  32  * @run main MBeanExceptionTest
  33  */
  34 
  35 import java.util.Collections;
  36 import java.util.Set;
  37 import javax.management.Attribute;
  38 import javax.management.AttributeList;
  39 import javax.management.DynamicMBean;
  40 import javax.management.MBeanException;
  41 import javax.management.MBeanInfo;
  42 import javax.management.MBeanServer;
  43 import javax.management.MBeanServerFactory;
  44 import javax.management.ObjectName;
  45 import javax.management.RuntimeMBeanException;
  46 import javax.management.StandardMBean;
  47 
  48 public class MBeanExceptionTest {
  49     public static void main(String[] args) throws Exception {
  50         System.out.println("Test that if an MBean throws RuntimeException " +
  51                            "it is wrapped in RuntimeMBeanException,");
  52         System.out.println("and if a Standard MBean throws Exception " +
  53                            "it is wrapped in MBeanException");
  54         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
  55         Object standard = new Except();
  56         ObjectName standardName = new ObjectName(":name=Standard MBean");
  57         Object standardMBean =
  58             new StandardMBean(new Except(), ExceptMBean.class);
  59         ObjectName standardMBeanName =
  60             new ObjectName(":name=Instance of StandardMBean");
  61         Object dynamic = new DynamicExcept();
  62         ObjectName dynamicName = new ObjectName(":name=Dynamic MBean");
  63         mbs.registerMBean(standard, standardName);
  64         mbs.registerMBean(standardMBean, standardMBeanName);
  65         mbs.registerMBean(dynamic, dynamicName);
  66         int failures = 0;
  67         failures += test(mbs, standardName, true);
  68         failures += test(mbs, standardMBeanName, true);
  69         failures += test(mbs, dynamicName, false);
  70 
  71         final boolean[] booleans = {false, true};
  72 
  73         for (boolean runtimeX : booleans) {
  74             Class<? extends Exception> excC =
  75                     runtimeX ? RuntimeMBeanException.class : MBeanException.class;
  76             String excS =
  77                     runtimeX ? "a RuntimeMBeanException" : "an MBeanException";
  78             String mbsS = "a plain MBeanServer";
  79             System.out.println(
  80                     "Test that, with " + mbsS + ", " + excS + " is wrapped " +
  81                     "in " + excS);
  82             // E.g. "Test that, with a plain MBeanServer, an MBeanException
  83             // is wrapped in an MBeanException".
  84             try {
  85                 mbs.createMBean(
  86                         Except.class.getName(), new ObjectName(":name=Oops"),
  87                         new Object[] {runtimeX},
  88                         new String[] {boolean.class.getName()});
  89                 System.out.println(
  90                         "FAIL: createMBean succeeded but should not have");
  91                 failures++;
  92             } catch (Exception e) {
  93                 if (!excC.isInstance(e)) {
  94                     System.out.println(
  95                             "FAIL: expected " + excC.getName() + " from " +
  96                             "createMBean, got " + e);
  97                     failures++;
  98                 } else {
  99                     Throwable cause = e.getCause();
 100                     if (!excC.isInstance(cause)) {
 101                         System.out.println(
 102                                 "FAIL: expected " + excC.getName() +
 103                                 " as cause of " + excC.getName() +
 104                                 ", got " + e);
 105                         failures++;
 106                     } else
 107                         System.out.println("...ok");
 108                 }
 109             }
 110         }
 111 
 112         if (failures == 0)
 113             System.out.println("Test passed");
 114         else {
 115             System.out.println("TEST FAILED: " + failures + " failure(s)");
 116             System.exit(1);
 117         }
 118     }
 119 
 120     private static int test(MBeanServer mbs, ObjectName name,
 121                             boolean testChecked)
 122             throws Exception {
 123         System.out.println("--------" + name + "--------");
 124 
 125         int failures = 0;
 126         final String[] ops = {"getAttribute", "setAttribute", "invoke"};
 127         final int GET = 0, SET = 1, INVOKE = 2;
 128         final String[] targets = {"UncheckedException", "CheckedException"};
 129         final int UNCHECKED = 0, CHECKED = 1;
 130 
 131         for (int i = 0; i < ops.length; i++) {
 132             for (int j = 0; j < targets.length; j++) {
 133 
 134                 if (j == CHECKED && !testChecked)
 135                     continue;
 136 
 137                 String target = targets[j];
 138                 String what = ops[i] + "/" + target;
 139                 System.out.println(what);
 140 
 141                 try {
 142                     switch (i) {
 143                     case GET:
 144                         mbs.getAttribute(name, target);
 145                         break;
 146                     case SET:
 147                         mbs.setAttribute(name, new Attribute(target, "x"));
 148                         break;
 149                     case INVOKE:
 150                         mbs.invoke(name, target, null, null);
 151                         break;
 152                     default:
 153                         throw new AssertionError();
 154                     }
 155                     System.out.println("failure: " + what + " returned!");
 156                     failures++;
 157                 } catch (RuntimeMBeanException e) {
 158                     if (j == CHECKED) {
 159                         System.out.println("failure: RuntimeMBeanException " +
 160                                            "when checked expected: " + e);
 161                         failures++;
 162                     } else {
 163                         Throwable cause = e.getCause();
 164                         if (cause == theUncheckedException)
 165                             System.out.println("ok: " + what);
 166                         else {
 167                             System.out.println("failure: " + what +
 168                                                " wrapped " + cause);
 169                             failures++;
 170                         }
 171                     }
 172                 } catch (MBeanException e) {
 173                     if (j == UNCHECKED) {
 174                         System.out.println("failure: checked exception " +
 175                                            "when unchecked expected: " + e);
 176                         failures++;
 177                     } else {
 178                         Throwable cause = e.getCause();
 179                         if (cause == theCheckedException)
 180                             System.out.println("ok: " + what);
 181                         else {
 182                             System.out.println("failure: " + what +
 183                                                " wrapped " + cause);
 184                             failures++;
 185                         }
 186                     }
 187                 } catch (Throwable t) {
 188                     System.out.println("failure: " + what + " threw: " + t);
 189                     while ((t = t.getCause()) != null)
 190                         System.out.println("  ... " + t);
 191                     failures++;
 192                 }
 193             }
 194         }
 195 
 196         return failures;
 197     }
 198 
 199     public static interface ExceptMBean {
 200         public String getUncheckedException();
 201         public void setUncheckedException(String x);
 202         public void UncheckedException();
 203         public String getCheckedException() throws Exception;
 204         public void setCheckedException(String x) throws Exception;
 205         public void CheckedException() throws Exception;
 206     }
 207 
 208     public static class Except implements ExceptMBean {
 209         public Except() {}
 210 
 211         public Except(boolean runtimeX) throws MBeanException {
 212             if (runtimeX)
 213                 throw new RuntimeMBeanException(new RuntimeException(), "Bang");
 214             else
 215                 throw new MBeanException(new Exception(), "Bang");
 216         }
 217 
 218         public String getUncheckedException() {
 219             throw theUncheckedException;
 220         }
 221         public void setUncheckedException(String x) {
 222             throw theUncheckedException;
 223         }
 224         public void UncheckedException() {
 225             throw theUncheckedException;
 226         }
 227         public String getCheckedException() throws Exception {
 228             throw theCheckedException;
 229         }
 230         public void setCheckedException(String x) throws Exception {
 231             throw theCheckedException;
 232         }
 233         public void CheckedException() throws Exception {
 234             throw theCheckedException;
 235         }
 236     }
 237 
 238     public static class DynamicExcept implements DynamicMBean {
 239         public Object getAttribute(String attrName)
 240                 throws MBeanException {
 241             if (attrName.equals("UncheckedException"))
 242                 throw theUncheckedException;
 243             else
 244                 throw new AssertionError();
 245         }
 246         public void setAttribute(Attribute attr)
 247                 throws MBeanException {
 248             String attrName = attr.getName();
 249             if (attrName.equals("UncheckedException"))
 250                 throw theUncheckedException;
 251             else
 252                 throw new AssertionError();
 253         }
 254         public Object invoke(String opName, Object[] params, String[] sig)
 255                 throws MBeanException {
 256             assert params == null && sig == null;
 257             if (opName.equals("UncheckedException"))
 258                 throw theUncheckedException;
 259             else
 260                 throw new AssertionError();
 261         }
 262         public AttributeList getAttributes(String[] names) {
 263             assert false;
 264             return null;
 265         }
 266         public AttributeList setAttributes(AttributeList attrs) {
 267             assert false;
 268             return null;
 269         }
 270         public MBeanInfo getMBeanInfo() {
 271             try {
 272                 return new StandardMBean(new Except(), ExceptMBean.class)
 273                     .getMBeanInfo();
 274             } catch (Exception e) {
 275                 assert false;
 276                 return null;
 277             }
 278         }
 279     }
 280 
 281     private static final Exception theCheckedException =
 282         new Exception("The checked exception that should be seen");
 283     private static final RuntimeException theUncheckedException =
 284         new UnsupportedOperationException("The unchecked exception " +
 285                                           "that should be seen");
 286 }