/* * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @bug 6486655 * @summary Test that attributes and operations appear in the same order * in MBeanInfo as they did in the Standard MBean or MXBean Interface. * @author Eamonn McManus */ /* * For more background on this test, see: * http://weblogs.java.net/blog/emcmanus/archive/2006/11/notes_on_unspec.html */ import java.lang.management.ManagementFactory; import java.lang.reflect.Method; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.management.MBeanAttributeInfo; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.StandardMBean; public class FeatureOrderTest { private static boolean failed; public static interface OrderMXBean { public int getMercury(); public String getVenus(); public void setVenus(String x); public BigInteger getEarth(); public void setEarth(BigInteger x); public boolean isMars(); public double getJupiter(); public byte getSaturn(); public short getUranus(); public void setUranus(short x); public long getNeptune(); // No more Pluto! Yay! public void neptune(); public void uranus(int x); public int saturn(int x, int y); public short jupiter(int x, long y, double z); public void mars(boolean x); public BigInteger earth(); public double earth(double x); // http://www.imdb.com/title/tt0064519/ public String venus(); public int mercury(); } public static interface OrderMBean extends OrderMXBean {} public static class OrderImpl implements OrderMXBean { public int getMercury() { return 0; } public String getVenus() { return null; } public void setVenus(String x) { } public BigInteger getEarth() { return null; } public void setEarth(BigInteger x) { } public boolean isMars() { return true; } public double getJupiter() { return 0; } public byte getSaturn() { return 0; } public short getUranus() { return 0; } public void setUranus(short x) { } public long getNeptune() { return 0; } public void neptune() { } public void uranus(int x) { } public int saturn(int x, int y) { return 0; } public short jupiter(int x, long y, double z) { return 0; } public void mars(boolean x) { } public BigInteger earth() { return null; } public double earth(double x) { return 0; } public String venus() { return null; } public int mercury() { return 0; } } public static class Order extends OrderImpl implements OrderMBean {} private static final boolean[] booleans = {false, true}; public static void main(String[] args) throws Exception { // Build the lists of attributes and operations that we would expect // if they are derived by reflection and preserve the reflection order List expectedAttributeNames = new ArrayList(); List expectedOperationNames = new ArrayList(); for (Method m : OrderMXBean.class.getMethods()) { String name = m.getName(); String attrName = null; if (name.startsWith("get") && !name.equals("get") && m.getParameterTypes().length == 0 && m.getReturnType() != void.class) attrName = name.substring(3); else if (name.startsWith("is") && !name.equals("is") && m.getParameterTypes().length == 0 && m.getReturnType() == boolean.class) attrName = name.substring(2); else if (name.startsWith("set") && !name.equals("set") && m.getReturnType() == void.class && m.getParameterTypes().length == 1) attrName = name.substring(3); if (attrName != null) { if (!expectedAttributeNames.contains(attrName)) expectedAttributeNames.add(attrName); } else expectedOperationNames.add(name); } MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); for (boolean mxbean : booleans) { for (boolean withStandardMBean : booleans) { String testName = "MXBean: " + mxbean + "; " + "using javax.management.StandardMBean: " + withStandardMBean; System.out.println("Test case: " + testName); Object mbean; if (mxbean) { if (withStandardMBean) { mbean = new StandardMBean( new OrderImpl(), OrderMXBean.class, true); } else mbean = new OrderImpl(); } else { if (withStandardMBean) mbean = new StandardMBean(new Order(), OrderMBean.class); else mbean = new Order(); } ObjectName name = new ObjectName( ":mxbean=" + mxbean + "," + "withStandardMBean=" + withStandardMBean); mbs.registerMBean(mbean, name); /* Make sure we are testing what we think. */ MBeanInfo mbi = mbs.getMBeanInfo(name); boolean isWithStandardMBean = mbs.isInstanceOf(name, StandardMBean.class.getName()); System.out.println("classname " +mbi.getClassName()); String mxbeanField = (String) mbi.getDescriptor().getFieldValue("mxbean"); boolean isMXBean = "true".equalsIgnoreCase(mxbeanField); if (mxbean != isMXBean) throw new Exception("Test error: MXBean mismatch"); if (withStandardMBean != isWithStandardMBean) throw new Exception("Test error: StandardMBean mismatch"); // Check that order of attributes and operations matches MBeanAttributeInfo[] mbais = mbi.getAttributes(); checkEqual(expectedAttributeNames.size(), mbais.length, "number of attributes"); List attributeNames = new ArrayList(); for (MBeanAttributeInfo mbai : mbais) attributeNames.add(mbai.getName()); checkEqual(expectedAttributeNames, attributeNames, "order of attributes"); MBeanOperationInfo[] mbois = mbi.getOperations(); checkEqual(expectedOperationNames.size(), mbois.length, "number of operations"); List operationNames = new ArrayList(); for (MBeanOperationInfo mboi : mbois) operationNames.add(mboi.getName()); checkEqual(expectedOperationNames, operationNames, "order of operations"); System.out.println(); } } if (failed) throw new Exception("TEST FAILED"); System.out.println("TEST PASSED"); } private static void checkEqual(Object expected, Object actual, String what) { if (expected.equals(actual)) System.out.println("OK: " + what + " matches"); else { System.out.println("FAILED: " + what + " differs:"); System.out.println(" expected: " + expected); System.out.println(" actual: " + actual); failed = true; } } }