1 /*
2  * Copyright (c) 2006, 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 /* This test essentially duplicates the functionality of MXBeanTest.java.
25  * See LeakTest.java for an explanation.
26  */
27 
28 import java.lang.reflect.Field;
29 import java.lang.reflect.InvocationHandler;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Proxy;
33 import java.util.HashMap;
34 import java.util.Map;
35 import javax.management.InstanceAlreadyExistsException;
36 import javax.management.JMX;
37 import javax.management.MBeanRegistrationException;
38 import javax.management.MBeanServer;
39 import javax.management.MBeanServerFactory;
40 import javax.management.MalformedObjectNameException;
41 import javax.management.NotCompliantMBeanException;
42 import javax.management.ObjectName;
43 
44 public class RandomMXBeanTest {
45     public static interface StupidMXBean {
46         public int ZERO = Integer.parseInt("0");
getZero()47         public int getZero();
identity(int x)48         public int identity(int x);
49     }
50 
51     public static class StupidImpl implements StupidMXBean {
getZero()52         public int getZero() {
53             return 0;
54         }
55 
identity(int x)56         public int identity(int x) {
57             return x;
58         }
59     }
60 
61     public static interface ReferMXBean {
getStupid()62         public StupidMXBean getStupid();
63     }
64 
65     public static class ReferImpl implements ReferMXBean {
66         private final StupidMXBean stupid;
67 
ReferImpl(StupidMXBean stupid)68         ReferImpl(StupidMXBean stupid) {
69             this.stupid = stupid;
70         }
71 
getStupid()72         public StupidMXBean getStupid() {
73             return stupid;
74         }
75     }
76 
77     private static class WrapInvocationHandler implements InvocationHandler {
78         private final Object wrapped;
79 
WrapInvocationHandler(Object wrapped)80         WrapInvocationHandler(Object wrapped) {
81             this.wrapped = wrapped;
82         }
83 
invoke(Object proxy, Method method, Object[] args)84         public Object invoke(Object proxy, Method method, Object[] args)
85         throws Throwable {
86             return method.invoke(wrapped, args);
87         }
88     }
89 
90     private static class DullInvocationHandler implements InvocationHandler {
91         private static Map<Class<?>, Object> zeroMap =
92                 new HashMap<Class<?>, Object>();
93         static {
zeroMap.put(byte.class, (byte) 0)94             zeroMap.put(byte.class, (byte) 0);
zeroMap.put(int.class, 0)95             zeroMap.put(int.class, 0);
zeroMap.put(short.class, (short) 0)96             zeroMap.put(short.class, (short) 0);
zeroMap.put(long.class, 0L)97             zeroMap.put(long.class, 0L);
zeroMap.put(float.class, 0F)98             zeroMap.put(float.class, 0F);
zeroMap.put(double.class, 0.0)99             zeroMap.put(double.class, 0.0);
zeroMap.put(boolean.class, false)100             zeroMap.put(boolean.class, false);
zeroMap.put(char.class, B)101             zeroMap.put(char.class, '\0');
102         }
103 
zeroFor(Class<?> c)104         public static Object zeroFor(Class<?> c) {
105             if (c.isPrimitive())
106                 return zeroMap.get(c);
107             else
108                 return null;
109         }
110 
invoke(Object proxy, Method method, Object[] args)111         public Object invoke(Object proxy, Method method, Object[] args)
112         throws Throwable {
113             Class<?> retType = method.getReturnType();
114             if (!retType.isPrimitive())
115                 return null;
116             return zeroMap.get(retType);
117         }
118     }
119 
main(String[] args)120     public static void main(String[] args) throws Exception {
121         MBeanServer mbs = MBeanServerFactory.newMBeanServer();
122         ObjectName name = new ObjectName("a:b=c");
123         StupidMXBean stupid = new StupidImpl();
124         mbs.registerMBean(stupid, name);
125         ObjectName referName = new ObjectName("a:c=d");
126         mbs.registerMBean(new ReferImpl(stupid), referName);
127         System.out.println(mbs.getMBeanInfo(name));
128         StupidMXBean stupid2 = (StupidMXBean)
129                 Proxy.newProxyInstance(StupidMXBean.class.getClassLoader(),
130                     new Class<?>[] {StupidMXBean.class},
131                     new WrapInvocationHandler(stupid));
132         ObjectName stupidName2 = new ObjectName("a:d=e");
133         mbs.registerMBean(stupid2, stupidName2);
134         Field zero = StupidMXBean.class.getField("ZERO");
135         System.out.println("Zero field = " + zero.get(null));
136         test(mbs, MerlinMXBean.class);
137         test(mbs, TigerMXBean.class);
138 
139         StupidMXBean proxy = JMX.newMXBeanProxy(mbs, name, StupidMXBean.class);
140         System.out.println("Zero = " + proxy.getZero());
141         System.out.println("One = " + proxy.identity(1));
142         ReferMXBean referProxy =
143                 JMX.newMXBeanProxy(mbs, referName, ReferMXBean.class);
144         StupidMXBean stupidProxy2 = referProxy.getStupid();
145         System.out.println("Same proxy: " + (proxy == stupidProxy2));
146         Method[] methods = StupidMXBean.class.getMethods();
147         for (Method method : methods) {
148             if (method.getParameterTypes().length == 0)
149                 method.invoke(proxy, new Object[0]);
150         }
151     }
152 
test(MBeanServer mbs, Class<T> c)153     private static <T> void test(MBeanServer mbs, Class<T> c) throws Exception {
154         System.out.println("Testing " + c.getName());
155         T merlin = c.cast(
156             Proxy.newProxyInstance(c.getClassLoader(),
157                 new Class<?>[] {c},
158                 new DullInvocationHandler()));
159         ObjectName merlinName = new ObjectName("a:type=" + c.getName());
160         mbs.registerMBean(merlin, merlinName);
161         System.out.println(mbs.getMBeanInfo(merlinName));
162         T merlinProxy = JMX.newMXBeanProxy(mbs, merlinName, c);
163         Method[] merlinMethods = c.getMethods();
164         for (Method m : merlinMethods) {
165             Class<?>[] types = m.getParameterTypes();
166             Object[] params = new Object[types.length];
167             for (int i = 0; i < types.length; i++)
168                 params[i] = DullInvocationHandler.zeroFor(types[i]);
169             System.out.println("Invoking " + m.getName());
170             m.invoke(merlinProxy, (Object[]) params);
171         }
172     }
173 }
174