Path: blob/master/test/jdk/javax/management/mxbean/MXBeanLoadingTest1.java
41149 views
/*1* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 805886526* @summary Checks correct collection of MXBean's class after unregistration27* @requires vm.opt.final.ClassUnloading28* @author Olivier Lagneau29*30* @library /lib/testlibrary31*32* @run main/othervm/timeout=300 MXBeanLoadingTest133*/3435import java.lang.ref.WeakReference;36import java.net.URL;37import java.util.Arrays;38import java.util.Map;39import javax.management.Attribute;40import javax.management.JMX;41import javax.management.MBeanAttributeInfo;42import javax.management.MBeanInfo;43import javax.management.MBeanOperationInfo;44import javax.management.MBeanServer;45import javax.management.MBeanServerFactory;46import javax.management.MXBean;47import javax.management.ObjectName;48import javax.management.loading.PrivateMLet;49import javax.management.openmbean.CompositeData;50import javax.management.openmbean.CompositeDataSupport;51import javax.management.openmbean.CompositeType;52import javax.management.openmbean.OpenType;53import javax.management.openmbean.SimpleType;5455public class MXBeanLoadingTest1 {5657public static void main(String[] args) throws Exception {58MXBeanLoadingTest1 test = new MXBeanLoadingTest1();59test.run((Map<String, Object>)null);60}616263public void run(Map<String, Object> args) {6465System.out.println("MXBeanLoadingTest1::run: Start") ;6667try {68System.out.println("We ensure no reference is retained on MXBean class"69+ " after it is unregistered. We take time to perform"70+ " some little extra check of Descriptors, MBean*Info.");7172ClassLoader myClassLoader = MXBeanLoadingTest1.class.getClassLoader();73if(myClassLoader == null)74throw new RuntimeException("Test Failed : Null Classloader for test");75URL url = myClassLoader.getResource(76MXBeanLoadingTest1.class.getCanonicalName()77.replace(".", "/") + ".class");78String clsLoadPath = url.toURI().toString().79replaceAll(MXBeanLoadingTest1.class.getSimpleName()80+ ".class", "");8182URL[] urls = new URL[]{new URL(clsLoadPath)};83PrivateMLet mlet = new PrivateMLet(urls, null, false);84Class<?> shadowClass = mlet.loadClass(TestMXBean.class.getName());8586if (shadowClass == TestMXBean.class) {87String message = "(ERROR) MLet got original TestMXBean, not shadow";88System.out.println(message);89throw new RuntimeException(message);90}91shadowClass = null;9293MBeanServer mbs = MBeanServerFactory.createMBeanServer();94ObjectName mletName = new ObjectName("x:type=mlet");95mbs.registerMBean(mlet, mletName);9697ObjectName testName = new ObjectName("x:type=test");98mbs.createMBean(Test.class.getName(), testName, mletName);99100// That test fails because the MXBean instance is accessed via101// a delegate OpenMBean which has102ClassLoader testLoader = mbs.getClassLoaderFor(testName);103104if (testLoader != mlet) {105System.out.println("MLet " + mlet);106String message = "(ERROR) MXBean's class loader is not MLet: "107+ testLoader;108System.out.println(message);109throw new RuntimeException(message);110}111testLoader = null;112113114// Cycle get/set/get of the attribute of type Luis.115// We check the set is effective.116CompositeData cd_B = (CompositeData)mbs.getAttribute(testName, "B");117CompositeType compType_B = cd_B.getCompositeType();118119CompositeDataSupport cds_B =120new CompositeDataSupport(compType_B,121new String[]{"something"},122new Object[]{Integer.valueOf(13)});123Attribute myAtt = new Attribute("B", cds_B);124mbs.setAttribute(testName, myAtt);125126CompositeData cd_B2 = (CompositeData)mbs.getAttribute(testName, "B");127128if ( ((Integer)cd_B2.get("something")).intValue() != 13 ) {129String message = "(ERROR) The setAttribute of att B did not work;"130+ " expect Luis.something = 13 but got "131+ cd_B2.get("something");132System.out.println(message);133throw new RuntimeException(message);134}135136MBeanInfo info = mbs.getMBeanInfo(testName);137String mxbeanField =138(String)info.getDescriptor().getFieldValue(JMX.MXBEAN_FIELD);139140if ( mxbeanField == null || ! mxbeanField.equals("true")) {141String message = "(ERROR) Improper mxbean field value "142+ mxbeanField;143System.out.println(message);144throw new RuntimeException(message);145}146147// Check the 2 attributes.148MBeanAttributeInfo[] attrs = info.getAttributes();149150if ( attrs.length == 2 ) {151for (MBeanAttributeInfo mbai : attrs) {152String originalTypeFieldValue =153(String)mbai.getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);154OpenType<?> openTypeFieldValue =155(OpenType<?>)mbai.getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);156157if ( mbai.getName().equals("A") ) {158if ( !mbai.isReadable() || !mbai.isWritable()159|| mbai.isIs()160|| !mbai.getType().equals("int") ) {161String message = "(ERROR) Unexpected MBeanAttributeInfo for A "162+ mbai;163System.out.println(message);164throw new RuntimeException(message);165}166167if ( ! originalTypeFieldValue.equals("int") ) {168String message = "(ERROR) Unexpected originalType in Descriptor for A "169+ originalTypeFieldValue;170System.out.println(message);171throw new RuntimeException(message);172}173174if ( ! openTypeFieldValue.equals(SimpleType.INTEGER) ) {175String message = "(ERROR) Unexpected openType in Descriptor for A "176+ originalTypeFieldValue;177System.out.println(message);178throw new RuntimeException(message);179}180} else if ( mbai.getName().equals("B") ) {181if ( !mbai.isReadable() || !mbai.isWritable()182|| mbai.isIs()183|| !mbai.getType().equals("javax.management.openmbean.CompositeData") ) {184String message = "(ERROR) Unexpected MBeanAttributeInfo for B "185+ mbai;186System.out.println(message);187throw new RuntimeException(message);188}189190if ( ! originalTypeFieldValue.equals(Luis.class.getName()) ) {191String message = "(ERROR) Unexpected originalType in Descriptor for B "192+ originalTypeFieldValue;193System.out.println(message);194throw new RuntimeException(message);195}196197if ( ! openTypeFieldValue.equals(compType_B) ) {198String message = "(ERROR) Unexpected openType in Descriptor for B "199+ compType_B;200System.out.println(message);201throw new RuntimeException(message);202}203} else {204String message = "(ERROR) Unknown attribute name";205System.out.println(message);206throw new RuntimeException(message);207}208}209} else {210String message = "(ERROR) Unexpected MBeanAttributeInfo array"211+ Arrays.deepToString(attrs);212System.out.println(message);213throw new RuntimeException(message);214}215216// Check the MXBean operation.217MBeanOperationInfo[] ops = info.getOperations();218// The impact is ACTION_INFO as for a standard MBean it is UNKNOWN,219// logged 6320104.220if (ops.length != 1 || !ops[0].getName().equals("bogus")221|| ops[0].getSignature().length > 0222|| !ops[0].getReturnType().equals("void")) {223String message = "(ERROR) Unexpected MBeanOperationInfo array "224+ Arrays.deepToString(ops);225System.out.println(message);226throw new RuntimeException(message);227}228229String originalTypeFieldValue =230(String)ops[0].getDescriptor().getFieldValue(JMX.ORIGINAL_TYPE_FIELD);231OpenType<?> openTypeFieldValue =232(OpenType<?>)ops[0].getDescriptor().getFieldValue(JMX.OPEN_TYPE_FIELD);233234if ( ! originalTypeFieldValue.equals("void") ) {235String message = "(ERROR) Unexpected originalType in Descriptor for bogus "236+ originalTypeFieldValue;237System.out.println(message);238throw new RuntimeException(message);239}240241if ( ! openTypeFieldValue.equals(SimpleType.VOID) ) {242String message = "(ERROR) Unexpected openType in Descriptor for bogus "243+ originalTypeFieldValue;244System.out.println(message);245throw new RuntimeException(message);246}247248// Check there is 2 constructors.249if (info.getConstructors().length != 2) {250String message = "(ERROR) Wrong number of constructors " +251"in introspected bean: " +252Arrays.asList(info.getConstructors());253System.out.println(message);254throw new RuntimeException(message);255}256257// Check MXBean class name.258if (!info.getClassName().endsWith("Test")) {259String message = "(ERROR) Wrong info class name: " +260info.getClassName();261System.out.println(message);262throw new RuntimeException(message);263}264265mbs.unregisterMBean(testName);266mbs.unregisterMBean(mletName);267268WeakReference<PrivateMLet> mletRef =269new WeakReference<PrivateMLet>(mlet);270mlet = null;271272System.out.println("MXBean registered and unregistered, waiting for " +273"garbage collector to collect class loader");274275for (int i = 0; i < 10000 && mletRef.get() != null; i++) {276System.gc();277Thread.sleep(1);278}279280if (mletRef.get() == null)281System.out.println("(OK) class loader was GC'd");282else {283String message = "(ERROR) Class loader was not GC'd";284System.out.println(message);285throw new RuntimeException(message);286}287} catch(Exception e) {288Utils.printThrowable(e, true) ;289throw new RuntimeException(e);290}291292System.out.println("MXBeanLoadingTest1::run: Done without any error") ;293}294295296// I agree the use of the MXBean annotation and the MXBean suffix for the297// interface name are redundant but however harmless.298//299@MXBean(true)300public static interface TestMXBean {301public void bogus();302public int getA();303public void setA(int a);304public Luis getB();305public void setB(Luis mi);306}307308309public static class Test implements TestMXBean {310private Luis luis = new Luis() ;311public Test() {}312public Test(int x) {}313314public void bogus() {}315public int getA() {return 0;}316public void setA(int a) {}317public Luis getB() {return this.luis;}318public void setB(Luis luis) {this.luis = luis;}319}320321322public static class Luis {323private int something = 0;324public Luis() {}325public int getSomething() {return something;}326public void setSomething(int v) {something = v;}327public void doNothing() {}328}329}330331332