0N/A/*
2362N/A * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * @test
0N/A * @bug 6320211
0N/A * @summary Check that java.lang.management MXBeans have the same behavior
0N/A * as user MXBeans
0N/A * @author Eamonn McManus
0N/A * @run main/othervm MXBeanBehavior
0N/A */
0N/A
0N/Aimport java.lang.management.*;
0N/Aimport java.lang.reflect.*;
0N/Aimport java.util.*;
0N/Aimport javax.management.*;
0N/A
0N/Apublic class MXBeanBehavior {
0N/A public static void main(String[] args) throws Exception {
0N/A MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
0N/A
0N/A /* Test that all the MBeans in the java.* and com.sun.management*
0N/A domains are MXBeans with the appropriate behavior. */
0N/A Set<ObjectName> names = mbs.queryNames(new ObjectName("java.*:*"),
0N/A null);
0N/A names.addAll(mbs.queryNames(new ObjectName("com.sun.management*:*"),
0N/A null));
0N/A for (ObjectName name : names)
0N/A test(mbs, name);
0N/A
0N/A /* Now do some rudimentary testing of inter-MXBean references.
0N/A It should be possible for a user MXBean to return e.g. the
0N/A CompilationMXBean from the platform from an attribute of
0N/A type CompilationMXBean, and have the MXBean infrastructure
0N/A map this into that MXBean's standard ObjectName. It should
0N/A also be possible for a proxy for this user MXBean to have
0N/A this attribute's value mapped back into a CompilationMXBean
0N/A instance, which however will be another proxy rather than
0N/A the original object. Finally, it should be possible to set
0N/A the attribute in the user's MXBean through a proxy, giving
0N/A the real CompilationMXBean as an argument, and have this be
0N/A translated into that MXBean's standard ObjectName. The
0N/A user's MXBean will receive a proxy in this case, though we
0N/A don't check that. */
0N/A ObjectName refName = new ObjectName("d:type=CompilationRef");
0N/A mbs.registerMBean(new CompilationImpl(), refName);
0N/A CompilationRefMXBean refProxy =
0N/A JMX.newMXBeanProxy(mbs, refName, CompilationRefMXBean.class);
0N/A refProxy.getCompilationMXBean();
0N/A refProxy.setCompilationMXBean(ManagementFactory.getCompilationMXBean());
0N/A ObjectName on =
0N/A (ObjectName) mbs.getAttribute(refName, "CompilationMXBean");
0N/A checkEqual(on, new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME),
0N/A "Referenced object name");
0N/A mbs.setAttribute(refName, new Attribute("CompilationMXBean", on));
0N/A
0N/A System.out.println("TEST PASSED");
0N/A }
0N/A
0N/A /* Check the behavior of this MXBean to ensure that it conforms to
0N/A what is expected of all MXBeans as detailed in
0N/A javax.management.MXBean. Its MBeanInfo should have a
0N/A Descriptor with the fields mxbean and interfaceClassName, and
0N/A furthermore we know that our implementation sets immutableInfo
0N/A here. Each attribute should have Descriptor with the fields
0N/A openType and originalType that have appropriate values. We
0N/A don't currently check operations though the same considerations
0N/A would apply there. (If the MBeanInfo and MBeanAttributeInfo
0N/A tests pass we can reasonably suppose that this MXBean will
0N/A behave the same as all other MXBeans, so MBeanOperationInfo,
0N/A MBeanNotificationInfo, and MBeanConstructorInfo will be covered
0N/A by generic MXBean tests.
0N/A */
0N/A private static void test(MBeanServer mbs, ObjectName name) throws Exception {
0N/A System.out.println("Testing: " + name);
0N/A
0N/A MBeanInfo mbi = mbs.getMBeanInfo(name);
0N/A Descriptor mbid = mbi.getDescriptor();
0N/A Object[] values = mbid.getFieldValues("immutableInfo",
0N/A "interfaceClassName",
0N/A "mxbean");
0N/A checkEqual(values[0], "true", name + " immutableInfo field");
0N/A checkEqual(values[2], "true", name + " mxbean field");
0N/A String interfaceClassName = (String) values[1];
0N/A if (!mbs.isInstanceOf(name, interfaceClassName)) {
0N/A throw new RuntimeException(name + " not instance of " +
0N/A interfaceClassName);
0N/A }
0N/A Class interfaceClass = Class.forName(interfaceClassName);
0N/A for (MBeanAttributeInfo mbai : mbi.getAttributes()) {
0N/A Descriptor mbaid = mbai.getDescriptor();
0N/A Object[] avalues = mbaid.getFieldValues("openType",
0N/A "originalType");
0N/A if (avalues[0] == null || avalues[1] == null) {
0N/A throw new RuntimeException("Null attribute descriptor fields: " +
0N/A Arrays.toString(avalues));
0N/A }
0N/A if (mbai.isReadable()) {
0N/A String mname = (mbai.isIs() ? "is" : "get") + mbai.getName();
0N/A Method m = interfaceClass.getMethod(mname);
0N/A Type t = m.getGenericReturnType();
0N/A String ret =
0N/A (t instanceof Class) ? ((Class) t).getName() : t.toString();
0N/A if (!ret.equals(avalues[1])) {
0N/A final String msg =
0N/A name + " attribute " + mbai.getName() + " has wrong " +
0N/A "originalType: " + avalues[1] + " vs " + ret;
0N/A throw new RuntimeException(msg);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static void checkEqual(Object x, Object y, String what) {
0N/A final boolean eq;
0N/A if (x == y)
0N/A eq = true;
0N/A else if (x == null)
0N/A eq = false;
0N/A else
0N/A eq = x.equals(y);
0N/A if (!eq)
0N/A throw new RuntimeException(what + " should be " + y + ", is " + x);
0N/A }
0N/A
0N/A public static interface CompilationRefMXBean {
0N/A public CompilationMXBean getCompilationMXBean();
0N/A public void setCompilationMXBean(CompilationMXBean mxb);
0N/A }
0N/A
0N/A public static class CompilationImpl implements CompilationRefMXBean {
0N/A public CompilationMXBean getCompilationMXBean() {
0N/A return ManagementFactory.getCompilationMXBean();
0N/A }
0N/A
0N/A public void setCompilationMXBean(CompilationMXBean mxb) {
0N/A if (mxb == ManagementFactory.getCompilationMXBean())
0N/A return;
0N/A MBeanServerInvocationHandler mbsih = (MBeanServerInvocationHandler)
0N/A Proxy.getInvocationHandler(mxb);
0N/A ObjectName expectedName;
0N/A try {
0N/A expectedName =
0N/A new ObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
0N/A } catch (MalformedObjectNameException e) {
0N/A throw new RuntimeException(e);
0N/A }
0N/A checkEqual(mbsih.getObjectName(), expectedName,
0N/A "Proxy name in setCompilationMXBean");
0N/A }
0N/A }
0N/A}