1 /*
   2  * Copyright (c) 2005, 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 5043762
  27  * @summary Attribute existence check fails if
  28  * RequiredModelMBean.addAttributeChangeNotificationListener
  29  * is called with a non-existent attribute name and there are
  30  * no other attributes.
  31  * @author Yves Joan
  32  * @author Eamonn McManus
  33  * @run clean AddAttributeChangeNotificationListenerTest
  34  * @run build AddAttributeChangeNotificationListenerTest
  35  * @run main AddAttributeChangeNotificationListenerTest
  36  */
  37 
  38 import java.lang.reflect.Method;
  39 import javax.management.AttributeChangeNotification;
  40 import javax.management.MBeanException;
  41 import javax.management.MBeanServer;
  42 import javax.management.MBeanServerFactory;
  43 import javax.management.Notification;
  44 import javax.management.NotificationListener;
  45 import javax.management.ObjectName;
  46 import javax.management.RuntimeOperationsException;
  47 import javax.management.modelmbean.*;
  48 
  49 /**
  50  * We do invoke addAttributeChangeNotificationListener to add
  51  * a listener on an attribute not defined in the ModelMBeanInfo
  52  * of the RequiredModelMBean instance used.
  53  */
  54 public class AddAttributeChangeNotificationListenerTest {
  55 
  56     public static void main(String args[] ) {
  57         AddAttributeChangeNotificationListenerTest test =
  58             new AddAttributeChangeNotificationListenerTest();
  59 
  60         try {
  61             test.run(args);
  62         } catch(Exception e) {
  63             System.out.println("FAIL");
  64             e.printStackTrace();
  65             System.exit(1);
  66         }
  67 
  68         System.out.println("PASS");
  69     }
  70 
  71     private void run( String[] args) throws Exception {
  72         int errCount = 0;
  73         String testName = "AddAttributeChangeNotificationListenerTest0001";
  74         ObjectName modelMBeanObjectName = null;
  75         ModelMBeanInfo modelMBeanInfo = null;
  76         MBeanServer mbeanserver = MBeanServerFactory.newMBeanServer();
  77         String modelMBeanName = "RequiredModelMBean";
  78         String modelMBeanClassName =
  79             "javax.management.modelmbean.RequiredModelMBean";
  80 
  81         modelMBeanObjectName =
  82             new ObjectName("AddAttributeChangeNotificationListenerTest:type=" +
  83             modelMBeanName);
  84 
  85         System.out.println("Build a ModelMBeanInfo without attribute State");
  86         modelMBeanInfo = createModelMBeanInfo();
  87 
  88         System.out.println("Create and register a RequiredModelMBean " +
  89             "with that MBeanInfo");
  90         Object[] params = { modelMBeanInfo };
  91         String[] sig = { "javax.management.modelmbean.ModelMBeanInfo" };
  92         mbeanserver.createMBean(modelMBeanClassName,
  93             modelMBeanObjectName,
  94             params,
  95             sig);
  96 
  97         ModelMBeanListener aListener = new ModelMBeanListener();
  98 
  99         // add an attribute change listener
 100         System.out.println("Add an attribute change listener for State");
 101         try {
 102             mbeanserver.invoke(modelMBeanObjectName,
 103                 "addAttributeChangeNotificationListener",
 104                 (new Object[] {aListener, "State", null}),
 105                     (new String[] {"javax.management.NotificationListener",
 106                         "java.lang.String",
 107                         "java.lang.Object"}));
 108                         System.out.println("NOK: Did not get expected " +
 109                             "RuntimeOperationsException");
 110                         errCount++;
 111         } catch (Exception e) {
 112             if (e instanceof MBeanException)
 113                 e = ((MBeanException) e).getTargetException();
 114             if (e instanceof RuntimeOperationsException) {
 115                 RuntimeOperationsException roe =
 116                     (RuntimeOperationsException) e;
 117                 Exception target = roe.getTargetException();
 118                 System.out.println("OK: Got expected RuntimeOperationsException");
 119 
 120                 if ( target instanceof IllegalArgumentException ) {
 121                     System.out.println("OK: Got expected " +
 122                         "wrapped IllegalArgumentException");
 123                 } else {
 124                     System.out.println("NOK: Got wrapped "
 125                         + target
 126                         + " as we expect IllegalArgumentException");
 127                     errCount++;
 128                 }
 129             } else {
 130                 System.out.println("NOK: Got "
 131                     + e
 132                     + " as we expect RuntimeOperationsException");
 133                 errCount++;
 134             }
 135         }
 136 
 137         if ( errCount != 0 )
 138             throw new Exception(errCount
 139                 + " error(s) occured");
 140     }
 141 
 142     /**
 143      * Returns a ModelMBeanInfo with two operations:
 144      * setManagedResource
 145      * addAttributeChangeNotificationListener
 146      */
 147     private ModelMBeanInfo createModelMBeanInfo() throws Exception {
 148         // operation setManagedResource
 149         String descriptionOp1Set = "ManagedResource description setter";
 150         Class[] paramsSet1 = {Class.forName("java.lang.Object"),
 151             Class.forName("java.lang.String")};
 152             Method oper1Set =
 153                 RequiredModelMBean.class.getMethod("setManagedResource",
 154                 paramsSet1);
 155             ModelMBeanOperationInfo operation1Set =
 156                 new  ModelMBeanOperationInfo(descriptionOp1Set,
 157                 oper1Set);
 158 
 159             // operation addAttributeChangeNotificationListener
 160             String descriptionop2Set =
 161                 "addAttributeChangeNotificationListener description";
 162             Class [] paramsSet2 =
 163             {Class.forName("javax.management.NotificationListener"),
 164                  Class.forName("java.lang.String"),
 165                  Class.forName("java.lang.Object")};
 166                  Method oper2Set =
 167                      RequiredModelMBean.class.getMethod(
 168                      "addAttributeChangeNotificationListener",
 169                      paramsSet2);
 170                  ModelMBeanOperationInfo operation2Set =
 171                      new  ModelMBeanOperationInfo(descriptionop2Set,
 172                      oper2Set);
 173 
 174                  // define ModelMBeanInfo
 175                  String className = "ModelMBeansInfo";
 176                  String descriptionmodel = "Model MBean Test";
 177                  ModelMBeanAttributeInfo[] attributes = null;
 178                  ModelMBeanOperationInfo[] operations = {
 179                      operation1Set,
 180                          operation2Set
 181                  };
 182                  ModelMBeanNotificationInfo[] notifications = null;
 183                  ModelMBeanConstructorInfo[] constructors = null;
 184 
 185                  ModelMBeanInfoSupport modelMBeanInfo =
 186                      new ModelMBeanInfoSupport(className,
 187                      descriptionmodel,
 188                      attributes,
 189                      constructors,
 190                      operations,
 191                      notifications);
 192                  return modelMBeanInfo;
 193     }
 194 
 195     public static class ModelMBeanListener implements NotificationListener {
 196 
 197         public ModelMBeanListener() {
 198             tally = 0;
 199         }
 200 
 201         public void handleNotification(Notification acn, Object handback) {
 202             tally++;
 203         }
 204 
 205         public int getCount() {
 206             return tally;
 207         }
 208 
 209         public int setCount(int newTally) {
 210             tally = newTally;
 211             return tally;
 212         }
 213 
 214         private int tally = 0;
 215 
 216     }
 217 }