0N/A/*
2362N/A * Copyright (c) 2003, 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 4874819
0N/A * @summary Test that MBeanInfo classes no longer throw an
0N/A * IllegalArgumentException when attribute names, operation names, and
0N/A * Java type names do not strictly follow the expected Java syntax.
0N/A * @author Eamonn McManus, Daniel Fuchs
0N/A * @run clean SimpleModelMBeanCommand
0N/A * @run build SimpleModelMBeanCommand
0N/A * @run main/othervm/policy=policy SimpleModelMBeanCommand
0N/A */
0N/A
0N/Aimport java.lang.reflect.*;
0N/Aimport java.util.*;
0N/Aimport javax.management.*;
0N/Aimport javax.management.modelmbean.*;
0N/A
0N/Apublic class SimpleModelMBeanCommand {
0N/A
0N/A public static class Resource {
0N/A public int getNumber() {
0N/A return number;
0N/A }
0N/A
0N/A public void setNumber(int n) {
0N/A number = n;
0N/A }
0N/A
0N/A public int addOne(int x) {
0N/A return x + 1;
0N/A }
0N/A
0N/A public Object[] getArray() {
0N/A return (Object[]) array.clone();
0N/A }
0N/A
0N/A // doesn't look like an attribute so not seen by caching logic
0N/A public void tweakArray(Object[] array) {
0N/A this.array = (Object[]) array.clone();
0N/A }
0N/A
0N/A private int number = 1234;
0N/A private Object[] array = {"hello", "world"};
0N/A }
0N/A
0N/A public static void main(String[] args) {
0N/A int errorCount = 0;
0N/A for (int i = 0; i < NTESTS; i++) {
0N/A try {
0N/A System.out.println("Test " + i + ":");
0N/A test(i);
0N/A } catch (Throwable e) {
0N/A errorCount++;
0N/A boolean first = true;
0N/A do {
0N/A System.err.println(first ? "Exception:" : "Caused by:");
0N/A first = false;
0N/A e.printStackTrace();
0N/A Throwable nexte;
0N/A nexte = e.getCause();
0N/A if (nexte == null) { // old JMX
0N/A if (e instanceof MBeanException)
0N/A nexte = ((MBeanException) e).getTargetException();
0N/A }
0N/A e = nexte;
0N/A } while (e != null);
0N/A }
0N/A }
0N/A if (errorCount == 0) {
0N/A System.out.println("All ModelMBean tests successfuly passed");
0N/A System.out.println("Bye! Bye!");
0N/A // JTReg doesn't like System.exit(0);
0N/A return;
0N/A } else {
0N/A System.err.println("ERROR: " + errorCount + " tests failed");
0N/A System.exit(errorCount);
0N/A }
0N/A
0N/A }
0N/A
0N/A private static void test(int testno) throws Exception {
0N/A // com.sun.jmx.trace.TraceImplementation.init(2);
0N/A Resource resource = new Resource();
0N/A Class resourceClass = Resource.class;
0N/A Class rmmbClass = RequiredModelMBean.class;
0N/A Method setManagedResource =
0N/A rmmbClass.getMethod("setManagedResource",
0N/A new Class[] {Object.class,
0N/A String.class});
0N/A Method sendNotification =
0N/A rmmbClass.getMethod("sendNotification",
0N/A new Class[] {Notification.class});
0N/A Method addAttributeChangeNL =
0N/A rmmbClass.getMethod("addAttributeChangeNotificationListener",
0N/A new Class[] {NotificationListener.class,
0N/A String.class,
0N/A Object.class});
0N/A Method getArray = resourceClass.getMethod("getArray", new Class[0]);
0N/A Method getNumber = resourceClass.getMethod("getNumber", new Class[0]);
0N/A Method setNumber =
0N/A resourceClass.getMethod("setNumber", new Class[] {Integer.TYPE});
0N/A Method tweakArray =
0N/A resourceClass.getMethod("tweakArray",
0N/A new Class[] {Object[].class});
0N/A Method addOne =
0N/A resourceClass.getMethod("addOne", new Class[] {Integer.TYPE});
0N/A MBeanServer mbs = MBeanServerFactory.newMBeanServer();
0N/A ObjectName on = new ObjectName("a:b=c");
0N/A Descriptor attrDescr = new DescriptorSupport();
0N/A attrDescr.setField("name", "Array");
0N/A attrDescr.setField("descriptorType", "attribute");
0N/A attrDescr.setField("getMethod", "getArray");
0N/A ModelMBeanAttributeInfo attrInfo =
0N/A new ModelMBeanAttributeInfo("Array", "array attr", getArray,
0N/A null, attrDescr);
0N/A Descriptor attrDescr2 = new DescriptorSupport();
0N/A attrDescr2.setField("name", "Number");
0N/A attrDescr2.setField("descriptorType", "attribute");
0N/A attrDescr2.setField("getMethod", "getNumber");
0N/A attrDescr2.setField("setMethod", "setNumber");
0N/A ModelMBeanAttributeInfo attrInfo2 =
0N/A new ModelMBeanAttributeInfo("Number", "number attr", getNumber,
0N/A setNumber, attrDescr2);
0N/A Descriptor attrDescr3 = new DescriptorSupport();
0N/A attrDescr3.setField("name", "Local");
0N/A attrDescr3.setField("descriptorType", "attribute");
0N/A attrDescr3.setField("currencyTimeLimit", "" + Integer.MAX_VALUE);
0N/A ModelMBeanAttributeInfo attrInfo3 =
0N/A new ModelMBeanAttributeInfo("Local", "java.lang.String",
0N/A "local attr", true, true, false,
0N/A attrDescr3);
0N/A Descriptor attrDescr4 = new DescriptorSupport();
0N/A attrDescr4.setField("name", "Local2");
0N/A attrDescr4.setField("descriptorType", "attribute");
0N/A ModelMBeanAttributeInfo attrInfo4 =
0N/A new ModelMBeanAttributeInfo("Local2", "java.lang.String",
0N/A "local attr 2", true, true, false,
0N/A attrDescr4);
0N/A ModelMBeanAttributeInfo[] attrs =
0N/A new ModelMBeanAttributeInfo[] {attrInfo, attrInfo2, attrInfo3,
0N/A attrInfo4};
0N/A ModelMBeanOperationInfo operInfo =
0N/A new ModelMBeanOperationInfo("getArray descr", getArray);
0N/A ModelMBeanOperationInfo operInfo2 =
0N/A new ModelMBeanOperationInfo("getNumber descr", getNumber);
0N/A ModelMBeanOperationInfo operInfo3 =
0N/A new ModelMBeanOperationInfo("addOne descr", addOne);
0N/A ModelMBeanOperationInfo operInfo4 =
0N/A new ModelMBeanOperationInfo("setNumber descr", setNumber);
0N/A ModelMBeanOperationInfo operInfo5 =
0N/A new ModelMBeanOperationInfo("tweakArray descr", tweakArray);
0N/A ModelMBeanOperationInfo operInfoSetManagedResource =
0N/A new ModelMBeanOperationInfo("setManagedResource descr",
0N/A setManagedResource);
0N/A ModelMBeanOperationInfo operInfoSendNotification =
0N/A new ModelMBeanOperationInfo("sendNotification descr",
0N/A sendNotification);
0N/A ModelMBeanOperationInfo operInfoAddAttributeChangeNL =
0N/A new ModelMBeanOperationInfo("AddAttributeChangeNL descr",
0N/A addAttributeChangeNL);
0N/A ModelMBeanOperationInfo[] opers =
0N/A new ModelMBeanOperationInfo[] {operInfo, operInfo2, operInfo3,
0N/A operInfo4, operInfo5,
0N/A operInfoSetManagedResource,
0N/A operInfoSendNotification,
0N/A operInfoAddAttributeChangeNL};
0N/A ModelMBeanInfo info =
0N/A new ModelMBeanInfoSupport(Resource.class.getName(),
0N/A "Resourcish resource",
0N/A attrs, null, opers, null,
0N/A null);
0N/A mbs.createMBean(RequiredModelMBean.class.getName(),
0N/A on,
0N/A new Object[] {info},
0N/A new String[] {ModelMBeanInfo.class.getName()});
0N/A mbs.invoke(on, "setManagedResource",
0N/A new Object[] {resource, "objectReference"},
0N/A new String[] {"java.lang.Object", "java.lang.String"});
0N/A switch (testno) {
0N/A case 0:
0N/A /* Check that we can get an attribute of type Object[] */
0N/A Object[] objs = (Object[]) mbs.getAttribute(on, "Array");
0N/A for (int i = 0; i < objs.length; i++)
0N/A System.out.println(objs[i]);
0N/A break;
0N/A case 1:
0N/A /* Check that we can get an attribute of type int */
0N/A Integer n = (Integer) mbs.getAttribute(on, "Number");
0N/A System.out.println(n);
0N/A break;
0N/A case 2:
0N/A /* Check that we can call an operation that returns int */
0N/A Integer n1 =
0N/A (Integer) mbs.invoke(on, "addOne",
0N/A new Integer[] {new Integer(1233)},
0N/A new String[] {"int"});
0N/A System.out.println(n1);
0N/A break;
0N/A case 3:
0N/A /* Check that we don't get an exception if you sendNotification
0N/A without any listeners. */
0N/A Notification notif = new Notification("type", "source", 123L);
0N/A mbs.invoke(on, "sendNotification", new Object[] {notif},
0N/A new String[] {"javax.management.Notification"});
0N/A System.out.println("Successfully sent notification");
0N/A break;
0N/A case 4:
0N/A /* Check that we can call addAttributeChangeNotificationListener
0N/A with null attribute. */
0N/A NotificationListener listener = new NotificationListener() {
0N/A public void handleNotification(Notification notif,
0N/A Object handback) {
0N/A System.out.println("Got notif: " + notif +
0N/A " with handback: " + handback);
0N/A }
0N/A };
0N/A mbs.invoke(on, "addAttributeChangeNotificationListener",
0N/A new Object[] {listener, null, "the-handback"},
0N/A new String[] {
0N/A "javax.management.NotificationListener",
0N/A "java.lang.String",
0N/A "java.lang.Object",
0N/A });
0N/A mbs.setAttribute(on, new Attribute("Number", new Integer(4321)));
0N/A System.out.println("Attribute value now: " +
0N/A mbs.getAttribute(on, "Number"));
0N/A break;
0N/A case 5:
0N/A /* Check that the default caching behaviour is not to cache. */
0N/A Object[] firstGot = (Object[]) mbs.getAttribute(on, "Array");
0N/A System.out.println("First got: " + Arrays.asList(firstGot));
0N/A ModelMBeanInfo mmbi = (ModelMBeanInfo) mbs.getMBeanInfo(on);
0N/A System.out.println(mmbi.getDescriptor("Array", "attribute"));
0N/A mbs.invoke(on, "tweakArray", new Object[] {new Object[] {"x"}},
0N/A new String[] {Object[].class.getName()});
0N/A Object[] secondGot = (Object[]) mbs.getAttribute(on, "Array");
0N/A System.out.println("Second got: " + Arrays.asList(secondGot));
0N/A if (secondGot.length != 1)
0N/A throw new Exception("Got value: " + Arrays.asList(secondGot));
0N/A break;
0N/A case 6:
0N/A /* Check that attributes without getters or setters work.
0N/A The value is stored in the descriptor. This test includes
0N/A an explicit currencyTimeLimit attribute. */
0N/A mbs.setAttribute(on, new Attribute("Local", "string value"));
0N/A ModelMBeanInfo mmbi2 = (ModelMBeanInfo) mbs.getMBeanInfo(on);
0N/A System.out.println(mmbi2.getDescriptor("Local", "attribute"));
0N/A Object gotback = mbs.getAttribute(on, "Local");
0N/A if (!"string value".equals(gotback))
0N/A throw new Exception("Got value: " + gotback);
0N/A break;
0N/A case 7:
0N/A /* Check that attributes without getters or setters work.
0N/A The value is stored in the descriptor. This test does
0N/A not have an explicit currencyTimeLimit attribute. */
0N/A mbs.setAttribute(on, new Attribute("Local2", "thing value"));
0N/A ModelMBeanInfo mmbi3 = (ModelMBeanInfo) mbs.getMBeanInfo(on);
0N/A System.out.println(mmbi3.getDescriptor("Local2", "attribute"));
0N/A Object gotback2 = mbs.getAttribute(on, "Local2");
0N/A if (!"thing value".equals(gotback2))
0N/A throw new Exception("Got value: " + gotback2);
0N/A break;
0N/A default:
0N/A System.err.println("UNKNOWN TEST NUMBER " + testno);
0N/A break;
0N/A }
0N/A }
0N/A
0N/A private static final int NTESTS = 8;
0N/A
0N/A}