1 /*
   2  * Copyright (c) 2005, 2015, 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 6296433 6283873
  27  * @summary Test that inter-MXBean references work as expected.
  28  * @author Eamonn McManus
  29  * @modules java.management
  30  * @run clean MXBeanRefTest
  31  * @run build MXBeanRefTest
  32  * @run main MXBeanRefTest
  33  */
  34 
  35 import java.lang.reflect.Proxy;
  36 import java.lang.reflect.UndeclaredThrowableException;
  37 import javax.management.Attribute;
  38 import javax.management.InstanceAlreadyExistsException;
  39 import javax.management.JMX;
  40 import javax.management.MBeanServer;
  41 import javax.management.MBeanServerDelegate;
  42 import javax.management.MBeanServerFactory;
  43 import javax.management.MBeanServerInvocationHandler;
  44 import javax.management.ObjectName;
  45 import javax.management.openmbean.OpenDataException;
  46 
  47 public class MXBeanRefTest {
  48     public static void main(String[] args) throws Exception {
  49         MBeanServer mbs = MBeanServerFactory.createMBeanServer();
  50         ObjectName productName = new ObjectName("d:type=Product,n=1");
  51         ObjectName product2Name = new ObjectName("d:type=Product,n=2");
  52         ObjectName moduleName = new ObjectName("d:type=Module");
  53         mbs.registerMBean(product, productName);
  54         mbs.registerMBean(product2, product2Name);
  55         mbs.registerMBean(module, moduleName);
  56         ModuleMXBean moduleProxy =
  57                 JMX.newMXBeanProxy(mbs, moduleName, ModuleMXBean.class);
  58 
  59         ObjectName on;
  60         on = (ObjectName) mbs.getAttribute(moduleName, "Product");
  61         check("ObjectName attribute value", on.equals(productName));
  62 
  63         ProductMXBean productProxy = moduleProxy.getProduct();
  64         MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
  65                 Proxy.getInvocationHandler(productProxy);
  66         check("ObjectName in proxy", mbsih.getObjectName().equals(productName));
  67 
  68         mbs.setAttribute(moduleName, new Attribute("Product", product2Name));
  69         ProductMXBean product2Proxy = module.getProduct();
  70         mbsih = (MBeanServerInvocationHandler)
  71                 Proxy.getInvocationHandler(product2Proxy);
  72         check("Proxy after setAttribute",
  73                 mbsih.getObjectName().equals(product2Name));
  74 
  75         moduleProxy.setProduct(productProxy);
  76         ProductMXBean productProxyAgain = module.getProduct();
  77         mbsih = (MBeanServerInvocationHandler)
  78                 Proxy.getInvocationHandler(productProxyAgain);
  79         check("Proxy after proxied set",
  80                 mbsih.getObjectName().equals(productName));
  81 
  82         MBeanServer mbs2 = MBeanServerFactory.createMBeanServer();
  83         ProductMXBean productProxy2 =
  84                 JMX.newMXBeanProxy(mbs2, productName, ProductMXBean.class);
  85         try {
  86             moduleProxy.setProduct(productProxy2);
  87             check("Proxy for wrong MBeanServer worked but shouldn't", false);
  88         } catch (Exception e) {
  89             if (e instanceof UndeclaredThrowableException &&
  90                     e.getCause() instanceof OpenDataException)
  91                 check("Proxy for wrong MBeanServer correctly rejected", true);
  92             else {
  93                 e.printStackTrace(System.out);
  94                 check("Proxy for wrong MBeanServer got wrong exception", false);
  95             }
  96         }
  97 
  98         // Test 6283873
  99         ObjectName dup = new ObjectName("a:b=c");
 100         mbs.registerMBean(new MBeanServerDelegate(), dup);
 101         try {
 102             mbs.registerMBean(new ProductImpl(), dup);
 103             check("Duplicate register succeeded but should fail", false);
 104         } catch (InstanceAlreadyExistsException e) {
 105             check("Got correct exception from duplicate name", true);
 106         } catch (Exception e) {
 107             e.printStackTrace(System.out);
 108             check("Got wrong exception from duplicate name", false);
 109         }
 110 
 111         if (failure != null)
 112             throw new Exception("TEST FAILED: " + failure);
 113         System.out.println("TEST PASSED");
 114     }
 115 
 116     private static void check(String what, boolean ok) {
 117         if (ok)
 118             System.out.println("OK: " + what);
 119         else {
 120             System.out.println("FAILED: " + what);
 121             failure = what;
 122         }
 123     }
 124 
 125     public static interface ProductMXBean {
 126         ModuleMXBean[] getModules();
 127     }
 128 
 129     public static interface ModuleMXBean {
 130         ProductMXBean getProduct();
 131         void setProduct(ProductMXBean p);
 132     }
 133 
 134     public static class ProductImpl implements ProductMXBean {
 135         public ModuleMXBean[] getModules() {
 136             return modules;
 137         }
 138     }
 139 
 140     public static class ModuleImpl implements ModuleMXBean {
 141         public ModuleImpl(ProductMXBean p) {
 142             setProduct(p);
 143         }
 144 
 145         public ProductMXBean getProduct() {
 146             return prod;
 147         }
 148 
 149         public void setProduct(ProductMXBean p) {
 150             this.prod = p;
 151         }
 152 
 153         private ProductMXBean prod;
 154     }
 155 
 156     private static final ProductMXBean product = new ProductImpl();
 157     private static final ProductMXBean product2 = new ProductImpl();
 158     private static final ModuleMXBean module = new ModuleImpl(product);
 159     private static final ModuleMXBean[] modules = new ModuleMXBean[] {module};
 160     private static String failure;
 161 }