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 5042004
  27  * @summary Check that MBeans with the same class have identical MBeanInfo
  28  * unless they are NotificationBroadcasters
  29  * @author Eamonn McManus
  30  * @run clean IdenticalMBeanInfoTest
  31  * @run build IdenticalMBeanInfoTest
  32  * @run main IdenticalMBeanInfoTest
  33  */
  34 
  35 import javax.management.*;
  36 
  37 /* What we test here is not required by the spec.  It is an
  38    optimization that can save a considerable amount of memory when
  39    there are many MBeans of the same type.  There is no reason why two
  40    Standard MBeans of the same type should have different MBeanInfo
  41    objects, unless they are NotificationBroadcasters and return
  42    different arrays from getNotificationInfo().  Note that two MBeans
  43    that share the same MBean interface but are of different classes
  44    cannot have the same MBeanInfo because the MBeanInfo includes the
  45    implementation class name.  */
  46 public class IdenticalMBeanInfoTest {
  47     private static String failure = null;
  48 
  49     public static interface WhatsitMBean {
  50         public int getReadOnly();
  51         public int getReadWrite();
  52         public void setReadWrite(int x);
  53         public int op(int x, int y);
  54     }
  55 
  56     public static class Whatsit implements WhatsitMBean {
  57         public Whatsit() {}
  58         public Whatsit(int irrelevant) {}
  59 
  60         public int getReadOnly() { return 0; }
  61         public int getReadWrite() { return 0; }
  62         public void setReadWrite(int x) {}
  63         public int op(int x, int y) { return 0; }
  64     }
  65 
  66     public static interface BroadcasterMBean extends WhatsitMBean {
  67     }
  68 
  69     public static class Broadcaster extends Whatsit
  70             implements BroadcasterMBean, NotificationBroadcaster {
  71         private static int nextId = 1;
  72         private int id = nextId++;
  73 
  74         public void addNotificationListener(NotificationListener l,
  75                                             NotificationFilter f,
  76                                             Object h) {}
  77 
  78         public void removeNotificationListener(NotificationListener l) {}
  79 
  80         public MBeanNotificationInfo[] getNotificationInfo() {
  81             return new MBeanNotificationInfo[] {
  82                 new MBeanNotificationInfo(new String[] {"type" + id},
  83                                           "something",
  84                                           "a something")
  85             };
  86         }
  87     }
  88 
  89     public static void main(String[] args) throws Exception {
  90         MBeanServer mbs = MBeanServerFactory.createMBeanServer();
  91         ObjectName on1 = new ObjectName("d:type=Whatsit,number=1");
  92         ObjectName on2 = new ObjectName("d:type=Whatsit,number=2");
  93         ObjectName on3 = new ObjectName("d:type=Whatsit,number=3");
  94         ObjectName on4 = new ObjectName("d:type=Whatsit,number=4");
  95         ObjectName on5 = new ObjectName("d:type=Whatsit,number=5");
  96 
  97         mbs.registerMBean(new Whatsit(), on1);
  98         mbs.createMBean(Whatsit.class.getName(), on2);
  99         DynamicMBean mbean =
 100             new StandardMBean(new Whatsit(), WhatsitMBean.class);
 101         mbs.registerMBean(mbean, on3);
 102         mbs.registerMBean(new Broadcaster(), on4);
 103         mbs.createMBean(Broadcaster.class.getName(), on5);
 104         MBeanInfo mbi1 = mbs.getMBeanInfo(on1);
 105         MBeanInfo mbi2 = mbs.getMBeanInfo(on2);
 106         MBeanInfo mbi3 = mbs.getMBeanInfo(on3);
 107         MBeanInfo mbi4 = mbs.getMBeanInfo(on4);
 108         MBeanInfo mbi5 = mbs.getMBeanInfo(on5);
 109 
 110         if (mbi1 != mbi2) {
 111             fail("Two MBeans of the same class should have identical " +
 112                  "MBeanInfo");
 113         }
 114 
 115         if (mbi2 != mbi3) {
 116             if (true)
 117                 System.out.println("IGNORING StandardMBean(...) failure");
 118             else
 119                 fail("Plain Standard MBean should have identical MBeanInfo " +
 120                      "to StandardMBean(...) with same class as resource");
 121         }
 122 
 123         if (mbi4 == mbi5 || mbi4.equals(mbi5)) {
 124             fail("Two MBeans of the same class should NOT have identical " +
 125                  "MBeanInfo if they are NotificationBroadcasters and "+
 126                  "do not return the same MBeanNotificationInfo[]");
 127         }
 128 
 129         if (failure == null) {
 130             System.out.println("Test passed");
 131             return;
 132         }
 133 
 134         throw new Exception("TEST FAILED: " + failure);
 135     }
 136 
 137     private static void fail(String why) {
 138         System.out.println("FAILURE: " + why);
 139         failure = why;
 140     }
 141 }