1 /* 2 * Copyright (c) 2006, 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 6486655 27 * @summary Test that attributes and operations appear in the same order 28 * in MBeanInfo as they did in the Standard MBean or MXBean Interface. 29 * @author Eamonn McManus 30 * @modules java.management 31 */ 32 33 /* 34 * For more background on this test, see: 35 * http://weblogs.java.net/blog/emcmanus/archive/2006/11/notes_on_unspec.html 36 */ 37 38 import java.lang.management.ManagementFactory; 39 import java.lang.reflect.Method; 40 import java.math.BigInteger; 41 import java.util.ArrayList; 42 import java.util.Collections; 43 import java.util.List; 44 import javax.management.MBeanAttributeInfo; 45 import javax.management.MBeanInfo; 46 import javax.management.MBeanOperationInfo; 47 import javax.management.MBeanServer; 48 import javax.management.ObjectName; 49 import javax.management.StandardMBean; 50 51 public class FeatureOrderTest { 52 private static boolean failed; 53 54 public static interface OrderMXBean { 55 public int getMercury(); 56 57 public String getVenus(); 58 public void setVenus(String x); 59 60 public BigInteger getEarth(); 61 public void setEarth(BigInteger x); 62 63 public boolean isMars(); 64 65 public double getJupiter(); 66 67 public byte getSaturn(); 68 69 public short getUranus(); 70 public void setUranus(short x); 71 72 public long getNeptune(); 73 74 // No more Pluto! Yay! 75 76 public void neptune(); 77 public void uranus(int x); 78 public int saturn(int x, int y); 79 public short jupiter(int x, long y, double z); 80 public void mars(boolean x); 81 public BigInteger earth(); 82 public double earth(double x); // http://www.imdb.com/title/tt0064519/ 83 public String venus(); 84 public int mercury(); 85 } 86 87 public static interface OrderMBean extends OrderMXBean {} 88 89 public static class OrderImpl implements OrderMXBean { 90 public int getMercury() { 91 return 0; 92 } 93 94 public String getVenus() { 95 return null; 96 } 97 98 public void setVenus(String x) { 99 } 100 101 public BigInteger getEarth() { 102 return null; 103 } 104 105 public void setEarth(BigInteger x) { 106 } 107 108 public boolean isMars() { 109 return true; 110 } 111 112 public double getJupiter() { 113 return 0; 114 } 115 116 public byte getSaturn() { 117 return 0; 118 } 119 120 public short getUranus() { 121 return 0; 122 } 123 124 public void setUranus(short x) { 125 } 126 127 public long getNeptune() { 128 return 0; 129 } 130 131 public void neptune() { 132 } 133 134 public void uranus(int x) { 135 } 136 137 public int saturn(int x, int y) { 138 return 0; 139 } 140 141 public short jupiter(int x, long y, double z) { 142 return 0; 143 } 144 145 public void mars(boolean x) { 146 } 147 148 public BigInteger earth() { 149 return null; 150 } 151 152 public double earth(double x) { 153 return 0; 154 } 155 156 public String venus() { 157 return null; 158 } 159 160 public int mercury() { 161 return 0; 162 } 163 } 164 165 public static class Order extends OrderImpl implements OrderMBean {} 166 167 private static final boolean[] booleans = {false, true}; 168 169 public static void main(String[] args) throws Exception { 170 // Build the lists of attributes and operations that we would expect 171 // if they are derived by reflection and preserve the reflection order 172 List<String> expectedAttributeNames = new ArrayList<String>(); 173 List<String> expectedOperationNames = new ArrayList<String>(); 174 for (Method m : OrderMXBean.class.getMethods()) { 175 String name = m.getName(); 176 String attrName = null; 177 if (name.startsWith("get") && !name.equals("get") && 178 m.getParameterTypes().length == 0 && 179 m.getReturnType() != void.class) 180 attrName = name.substring(3); 181 else if (name.startsWith("is") && !name.equals("is") && 182 m.getParameterTypes().length == 0 && 183 m.getReturnType() == boolean.class) 184 attrName = name.substring(2); 185 else if (name.startsWith("set") && !name.equals("set") && 186 m.getReturnType() == void.class && 187 m.getParameterTypes().length == 1) 188 attrName = name.substring(3); 189 if (attrName != null) { 190 if (!expectedAttributeNames.contains(attrName)) 191 expectedAttributeNames.add(attrName); 192 } else 193 expectedOperationNames.add(name); 194 } 195 196 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 197 for (boolean mxbean : booleans) { 198 for (boolean withStandardMBean : booleans) { 199 String testName = "MXBean: " + mxbean + "; " + 200 "using javax.management.StandardMBean: " + 201 withStandardMBean; 202 System.out.println("Test case: " + testName); 203 Object mbean; 204 if (mxbean) { 205 if (withStandardMBean) { 206 mbean = new StandardMBean( 207 new OrderImpl(), OrderMXBean.class, true); 208 } else 209 mbean = new OrderImpl(); 210 } else { 211 if (withStandardMBean) 212 mbean = new StandardMBean(new Order(), OrderMBean.class); 213 else 214 mbean = new Order(); 215 } 216 ObjectName name = new ObjectName( 217 ":mxbean=" + mxbean + "," + "withStandardMBean=" + 218 withStandardMBean); 219 mbs.registerMBean(mbean, name); 220 221 /* Make sure we are testing what we think. */ 222 MBeanInfo mbi = mbs.getMBeanInfo(name); 223 boolean isWithStandardMBean = 224 mbs.isInstanceOf(name, StandardMBean.class.getName()); 225 System.out.println("classname " +mbi.getClassName()); 226 String mxbeanField = 227 (String) mbi.getDescriptor().getFieldValue("mxbean"); 228 boolean isMXBean = "true".equalsIgnoreCase(mxbeanField); 229 230 if (mxbean != isMXBean) 231 throw new Exception("Test error: MXBean mismatch"); 232 if (withStandardMBean != isWithStandardMBean) 233 throw new Exception("Test error: StandardMBean mismatch"); 234 235 // Check that order of attributes and operations matches 236 MBeanAttributeInfo[] mbais = mbi.getAttributes(); 237 checkEqual(expectedAttributeNames.size(), mbais.length, 238 "number of attributes"); 239 List<String> attributeNames = new ArrayList<String>(); 240 for (MBeanAttributeInfo mbai : mbais) 241 attributeNames.add(mbai.getName()); 242 checkEqual(expectedAttributeNames, attributeNames, 243 "order of attributes"); 244 245 MBeanOperationInfo[] mbois = mbi.getOperations(); 246 checkEqual(expectedOperationNames.size(), mbois.length, 247 "number of operations"); 248 List<String> operationNames = new ArrayList<String>(); 249 for (MBeanOperationInfo mboi : mbois) 250 operationNames.add(mboi.getName()); 251 checkEqual(expectedOperationNames, operationNames, 252 "order of operations"); 253 System.out.println(); 254 } 255 } 256 257 if (failed) 258 throw new Exception("TEST FAILED"); 259 System.out.println("TEST PASSED"); 260 } 261 262 private static void checkEqual(Object expected, Object actual, String what) { 263 if (expected.equals(actual)) 264 System.out.println("OK: " + what + " matches"); 265 else { 266 System.out.println("FAILED: " + what + " differs:"); 267 System.out.println(" expected: " + expected); 268 System.out.println(" actual: " + actual); 269 failed = true; 270 } 271 } 272 }