Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/monitoring/share/CustomMBeanServer.java
40948 views
/*1* Copyright (c) 2003, 2021, 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*/2223package nsk.monitoring.share;2425import java.util.*;26import java.io.*;27import java.lang.reflect.*;28import java.lang.management.*;29import javax.management.*;30import javax.management.loading.*;31import nsk.share.*;3233/**34* The <code>CustomMBeanServer</code> implemenets the35* {@link javax.management.MBeanServer MBeanServer} interface to provide36* minimal funcionality for JSR-174 testing.37* <p>Insignificant methods that are not used just throw {@link TestBug TestBug}38* with "not implemented" message. If this exception is caught during test39* execution, the corresponding method must be implemented.40*/4142public class CustomMBeanServer implements MBeanServer {4344// Name of the system property, which specifies class name of MBean server45final static String SERVER_BUILDER_PROPERTY46= "javax.management.builder.initial";4748// Class name of MBeanServer builder that creates CustomMBeanServer49final static String CUSTOM_SERVER_BUILDER50= CustomMBeanServerBuilder.class.getCanonicalName();5152// Default MBeanServer builder53final static String DEFAULT_SERVER_BUILDER = "";5455// Internal trace level56private final static int TRACE_ALL = 10;5758// Prefix to print while logging59private final static String LOG_PREFIX = "CustomMBeanServer> ";6061private final static String BROADCASTER_ITNF_NAME =62"javax.management.NotificationBroadcaster";6364private final static String DYNAMICMBEAN_ITNF_NAME =65"javax.management.DynamicMBean";6667// Private variables68private String defaultDomain;69private CustomMBeanRegistration register = new CustomMBeanRegistration();70private Log.Logger log;71private Hashtable<ObjectName, ObjectKeeper> registeredMBeans = new Hashtable<ObjectName, ObjectKeeper>();72// StandardMBean view of registered MBeans73private Map<ObjectName, DynamicMBean> registeredMBeansStd = new HashMap<ObjectName, DynamicMBean>();7475// Inner class to connect ObjectInstance and Object76class ObjectKeeper {77ObjectInstance instance;78Object object;7980ObjectKeeper(ObjectInstance instance, Object object) {81this.instance = instance;82this.object = object;83}84}8586/**87* Creates a new <code>CustomMBeanServer</code> object.88*89* @param defaultDomain default domain of the new MBeanServer90*/91public CustomMBeanServer(String defaultDomain) {92this.defaultDomain = defaultDomain;93}9495/**96* Instantiates and registers an MBean in the MBean server.97*98* @see javax.management.MBeanServer#createMBean(String, ObjectName)99*/100public ObjectInstance createMBean(String className, ObjectName name)101throws ReflectionException,102InstanceAlreadyExistsException,103MBeanRegistrationException,104MBeanException,105NotCompliantMBeanException {106throw new TestBug("not implemented");107}108109/**110* Instantiates and registers an MBean in the MBean server.111*112* @see javax.management.MBeanServer#createMBean(String, ObjectName,113* Object[], String[])114*/115public ObjectInstance createMBean(String className, ObjectName name,116Object[] params, String[] signature)117throws ReflectionException,118InstanceAlreadyExistsException,119MBeanRegistrationException,120MBeanException,121NotCompliantMBeanException {122throw new TestBug("not implemented");123}124125/**126* Instantiates and registers an MBean in the MBean server.127*128* @see javax.management.MBeanServer#createMBean(String, ObjectName,129* ObjectName)130*/131public ObjectInstance createMBean(String className, ObjectName name,132ObjectName loaderName)133throws ReflectionException,134InstanceAlreadyExistsException,135MBeanRegistrationException,136MBeanException,137NotCompliantMBeanException,138InstanceNotFoundException {139throw new TestBug("not implemented");140}141142/**143* Instantiates and registers an MBean in the MBean server.144*145* @see javax.management.MBeanServer#createMBean(String, ObjectName,146* ObjectName, Object[], String[])147*/148public ObjectInstance createMBean(String className, ObjectName name,149ObjectName loaderName, Object[] params,150String[] signature)151throws ReflectionException,152InstanceAlreadyExistsException,153MBeanRegistrationException,154MBeanException,155NotCompliantMBeanException,156InstanceNotFoundException {157throw new TestBug("not implemented");158}159160/**161* Registers a pre-existing object as an MBean with the MBean server162*163* @see javax.management.MBeanServer#registerMBean(Object, ObjectName)164*/165public ObjectInstance registerMBean(Object object, ObjectName name)166throws InstanceAlreadyExistsException,167MBeanRegistrationException,168NotCompliantMBeanException {169ObjectName newName = null;170171try {172newName = register.preRegister(this, name);173} catch (Exception e) {174register.postRegister(Boolean.valueOf(false));175throw new MBeanRegistrationException(e);176}177178// The log object may not be initialized by that time, so try179// to check it180if (log != null)181log.trace(TRACE_ALL, "[registerMBean] " + newName);182183if (isRegistered(newName)) {184register.postRegister(Boolean.valueOf(false));185throw new InstanceAlreadyExistsException("already registered");186}187188ObjectInstance instance = null;189try {190instance = new ObjectInstance(newName, object.getClass().getName());191} catch (IllegalArgumentException e) {192throw new RuntimeOperationsException(e);193}194registeredMBeans.put(newName, new ObjectKeeper(instance, object));195register.postRegister(Boolean.valueOf(true));196return instance;197}198199/**200* Unregisters an MBean from the MBean server.201*202* @see javax.management.MBeanServer#unregisterMBean(ObjectName)203*/204public void unregisterMBean(ObjectName name)205throws InstanceNotFoundException,206MBeanRegistrationException {207throw new TestBug("not implemented");208}209210/**211* Gets the <code>ObjectInstance</code> for a given MBean registered with212* the MBean server.213*214* @see javax.management.MBeanServer#getObjectInstance(ObjectName)215*/216public ObjectInstance getObjectInstance(ObjectName name)217throws InstanceNotFoundException {218throw new TestBug("not implemented");219}220221/**222* Gets MBeans controlled by the MBean server.223*224* @see javax.management.MBeanServer#queryMBeans(ObjectName, QueryExp)225*/226public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {227if ( (name != null) || (query != null) )228throw new TestBug("not implemented");229230HashSet<ObjectInstance> result = new HashSet<ObjectInstance>();231Enumeration enumeration = registeredMBeans.elements();232while (enumeration.hasMoreElements()) {233ObjectKeeper keeper = (ObjectKeeper) enumeration.nextElement();234result.add(keeper.instance);235}236return result;237}238239/**240* Gets the names of MBeans controlled by the MBean server.241*242* @see javax.management.MBeanServer#queryNames(ObjectName, QueryExp)243*/244public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {245if (query != null)246throw new TestBug("not implemented");247248HashSet<ObjectName> result = new HashSet<ObjectName>();249Enumeration enumeration = registeredMBeans.elements();250while (enumeration.hasMoreElements()) {251ObjectKeeper keeper = (ObjectKeeper) enumeration.nextElement();252ObjectName obj = keeper.instance.getObjectName();253if ((name == null) || (name.apply(obj))) {254result.add(obj);255}256}257return result;258}259260/**261* Checks whether an MBean, identified by its object name, is262* already registered with the MBean server.263*264* @see javax.management.MBeanServer#isRegistered(ObjectName)265*/266public boolean isRegistered(ObjectName name) {267return registeredMBeans.containsKey(name);268}269270/**271* Returns the number of MBeans registered in the MBean server.272*273* @see javax.management.MBeanServer#getMBeanCount()274*/275public Integer getMBeanCount() {276throw new TestBug("not implemented");277}278279/**280* Gets the value of a specific attribute of a named MBean.281*282* @see javax.management.MBeanServer#getAttribute(ObjectName, String)283*/284public Object getAttribute(ObjectName name, String attribute)285throws MBeanException,286AttributeNotFoundException,287InstanceNotFoundException,288ReflectionException {289290if (log != null)291log.trace(TRACE_ALL, "[getAttribute] " + name + "> " + attribute);292293DynamicMBean mbean = getObject(name);294Object result = mbean.getAttribute(attribute);295if (result instanceof List) {296List list = (List) result;297Object[] arr = new Object[list.size()];298int i = 0;299for (Object o : list)300arr[i++] = o;301return arr;302}303return result;304}305306/**307* Gets the values of several attributes of a named MBean.308*309* @see javax.management.MBeanServer#getAttributes(ObjectName, String[])310*/311public AttributeList getAttributes(ObjectName name, String[] attributes)312throws InstanceNotFoundException,313ReflectionException {314throw new TestBug("not implemented");315}316317/**318* Sets the value of a specific attribute of a named MBean.319*320* @see javax.management.MBeanServer#setAttribute(ObjectName, Attribute)321*/322public void setAttribute(ObjectName name, Attribute attribute)323throws InstanceNotFoundException,324AttributeNotFoundException,325InvalidAttributeValueException,326MBeanException,327ReflectionException {328329if (log != null)330log.trace(TRACE_ALL, "[setAttribute] " + name + "> " + attribute);331332DynamicMBean mbean = getObject(name);333mbean.setAttribute(attribute);334}335336/**337* Sets the values of several attributes of a named MBean.338*339* @see javax.management.MBeanServer#setAttributes(ObjectName,340* AttributeList)341*/342public AttributeList setAttributes(ObjectName name,343AttributeList attributes)344throws InstanceNotFoundException,345ReflectionException {346throw new TestBug("not implemented");347}348349/**350* Invokes an operation on an MBean.351*352* @see javax.management.MBeanServer#invoke(ObjectName, String,353* Object[], String[])354*/355public Object invoke(ObjectName name, String operationName,356Object[] params, String[] signature)357throws InstanceNotFoundException,358MBeanException,359ReflectionException {360361if (log != null)362log.trace(TRACE_ALL, "[invoke] " + name + "> "363+ operationName);364return invokeObjectMethod(name, operationName, params, signature);365}366367/**368* Returns the default domain used for naming the MBean.369*370* @see javax.management.MBeanServer#getDefaultDomain()371*/372public String getDefaultDomain() {373throw new TestBug("not implemented");374}375376/**377* Returns the list of domains in which any MBean is currently378* registered.379*380* @see javax.management.MBeanServer#getDomains()381*/382public String[] getDomains() {383throw new TestBug("not implemented");384}385386/**387* Adds a listener to a registered MBean.388*389* @see javax.management.MBeanServer#addNotificationListener(ObjectName,390* NotificationListener, NotificationFilter, Object)391*/392public void addNotificationListener(ObjectName name,393NotificationListener listener,394NotificationFilter filter,395Object handback) throws InstanceNotFoundException {396getNotificationBroadcaster(name).addNotificationListener(listener, filter, handback);397}398399/**400* Adds a listener to a registered MBean.401*402* @see javax.management.MBeanServer#addNotificationListener(ObjectName,403* ObjectName, NotificationFilter, Object)404*/405public void addNotificationListener(ObjectName name, ObjectName listener,406NotificationFilter filter,407Object handback)408throws InstanceNotFoundException {409throw new TestBug("not implemented");410}411412/**413* Removes a listener from a registered MBean.414*415* @see javax.management.MBeanServer#removeNotificationListener(ObjectName,416* ObjectName)417*/418public void removeNotificationListener(ObjectName name, ObjectName listener)419throws InstanceNotFoundException, ListenerNotFoundException {420throw new TestBug("not implemented");421}422423/**424* Removes a listener from a registered MBean.425*426* @see javax.management.MBeanServer#removeNotificationListener(ObjectName,427* ObjectName, NotificationFilter, Object)428*/429public void removeNotificationListener(ObjectName name,430ObjectName listener,431NotificationFilter filter,432Object handback)433throws InstanceNotFoundException,434ListenerNotFoundException {435throw new TestBug("not implemented");436}437438/**439* Removes a listener from a registered MBean.440*441* @see javax.management.MBeanServer#removeNotificationListener(ObjectName,442* NotificationListener)443*/444public void removeNotificationListener(ObjectName name,445NotificationListener listener)446throws InstanceNotFoundException,447ListenerNotFoundException {448throw new TestBug("not implemented");449}450451/**452* Removes a listener from a registered MBean.453*454* @see javax.management.MBeanServer#removeNotificationListener(ObjectName,455* NotificationListener, NotificationFilter, Object)456*/457public void removeNotificationListener(ObjectName name,458NotificationListener listener,459NotificationFilter filter,460Object handback)461throws InstanceNotFoundException,462ListenerNotFoundException {463}464465/**466* This method discovers the attributes and operations that an467* MBean exposes for management.468*469* @see javax.management.MBeanServer#getMBeanInfo(ObjectName)470*/471public MBeanInfo getMBeanInfo(ObjectName name)472throws InstanceNotFoundException,473IntrospectionException,474ReflectionException {475throw new TestBug("not implemented");476}477478/**479* Returns true if the MBean specified is an instance of the480* specified class, false otherwise.481*482* @see javax.management.MBeanServer#isInstanceOf(ObjectName, String)483*/484public boolean isInstanceOf(ObjectName name, String className)485throws InstanceNotFoundException {486// DynamicMBean mbean = getObject(name);487// MBeanInfo info = mbean.getMBeanInfo();488// return info.getClassName().compareTo(className) == 0;489490DynamicMBean mbean = getObject(name);491MBeanInfo info = mbean.getMBeanInfo();492String infoClassName = info.getClassName();493494if (log != null) {495log.trace(TRACE_ALL, "[isInstanceOf] name=" + name);496log.trace(TRACE_ALL, "[isInstanceOf] className=" + className);497}498499if (infoClassName.equals(className)) {500if (log != null)501log.trace(TRACE_ALL, "[isInstanceOf] infoClassName is equal className. return true");502return true;503}504505try {506ClassLoader cl = mbean.getClass().getClassLoader();507Class<?> classNameClass = loadClass(className,cl);508if (classNameClass == null) {509if (log != null)510log.trace(TRACE_ALL, "[isInstanceOf] classNameClass is null. return false");511return false;512}513514if (classNameClass.isInstance(mbean)) {515if (log != null)516log.trace(TRACE_ALL, "[isInstanceOf] mbean is instance of classNameClass. return true");517return true;518}519520Class<?> instanceClass = loadClass(infoClassName,cl);521if (instanceClass == null) {522if (log != null)523log.trace(TRACE_ALL, "[isInstanceOf] instanceClass is null. return false");524return false;525}526527boolean isAssignable = classNameClass.isAssignableFrom(instanceClass);528if (log != null)529log.trace(TRACE_ALL, "[isInstanceOf] classNameClass is assignable="+isAssignable);530return isAssignable;531} catch (ReflectionException e) {532if (log != null) {533log.trace(TRACE_ALL, "[isInstanceOf] "+e.getMessage());534e.printStackTrace(log.getOutStream());535}536return false;537} catch (Exception e) {538/* Could be SecurityException or ClassNotFoundException */539if (log != null) {540log.trace(TRACE_ALL, "[isInstanceOf] "+e.getMessage());541e.printStackTrace(log.getOutStream());542}543return false;544}545546}547548/**549* Load a class with the specified loader, or with this object550* class loader if the specified loader is null.551**/552static Class loadClass(String className, ClassLoader loader)553throws ReflectionException {554555Class theClass = null;556if (className == null) {557throw new RuntimeOperationsException(new558IllegalArgumentException("The class name cannot be null"),559"Exception occured during object instantiation");560}561try {562if (loader == null)563loader = CustomMBeanServer.class.getClassLoader();564if (loader != null) {565theClass = Class.forName(className, false, loader);566} else {567theClass = Class.forName(className);568}569} catch (ClassNotFoundException e) {570throw new ReflectionException(e,571"The MBean class could not be loaded by the context classloader");572}573return theClass;574}575576577/**578* Instantiates an object using the list of all class loaders579* registered in the MBean server's.580*581* @see javax.management.MBeanServer#instantiate(String)582*/583public Object instantiate(String className)584throws ReflectionException,585MBeanException {586throw new TestBug("not implemented");587}588589/**590* Instantiates an object using the list of all class loaders591* registered in the MBean server's.592*593* @see javax.management.MBeanServer#instantiate(String, ObjectName)594*/595public Object instantiate(String className, ObjectName loaderName)596throws ReflectionException,597MBeanException,598InstanceNotFoundException {599throw new TestBug("not implemented");600}601602/**603* Instantiates an object using the list of all class loaders604* registered in the MBean server's.605*606* @see javax.management.MBeanServer#instantiate(String, Object[],607* String[])608*/609public Object instantiate(String className, Object[] params,610String[] signature)611throws ReflectionException,612MBeanException {613throw new TestBug("not implemented");614}615616/**617* Instantiates an object using the list of all class loaders618* registered in the MBean server's.619*620* @see javax.management.MBeanServer#instantiate(String, ObjectName,621* Object[], String[])622*/623public Object instantiate(String className, ObjectName loaderName,624Object[] params, String[] signature)625throws ReflectionException,626MBeanException,627InstanceNotFoundException {628throw new TestBug("not implemented");629}630631/**632* De-serializes a byte array in the context of the class loader633* of an MBean.634*635* @see javax.management.MBeanServer#deserialize(ObjectName, byte[])636*/637public ObjectInputStream deserialize(ObjectName name, byte[] data)638throws InstanceNotFoundException,639OperationsException {640throw new TestBug("not implemented");641}642643/**644* De-serializes a byte array in the context of the class loader645* of an MBean.646*647* @see javax.management.MBeanServer#deserialize(String, byte[])648*/649public ObjectInputStream deserialize(String className, byte[] data)650throws OperationsException,651ReflectionException {652throw new TestBug("not implemented");653}654655/**656* De-serializes a byte array in the context of the class loader657* of an MBean.658*659* @see javax.management.MBeanServer#deserialize(String, ObjectName, byte[])660*/661public ObjectInputStream deserialize(String className,662ObjectName loaderName,663byte[] data)664throws InstanceNotFoundException,665OperationsException,666ReflectionException {667throw new TestBug("not implemented");668}669670/**671* Return the {@link java.lang.ClassLoader} that was used for672* loading the class of the named MBean.673*674* @see javax.management.MBeanServer#getClassLoaderFor(ObjectName)675*/676public ClassLoader getClassLoaderFor(ObjectName mbeanName)677throws InstanceNotFoundException {678throw new TestBug("not implemented");679}680681/**682* Return the named {@link java.lang.ClassLoader}.683*684* @see javax.management.MBeanServer#getClassLoader(ObjectName)685*/686public ClassLoader getClassLoader(ObjectName loaderName)687throws InstanceNotFoundException {688throw new TestBug("not implemented");689}690691/**692* Return the named {@link java.lang.ClassLoader}.693*694* @see javax.management.MBeanServer#getClassLoader(ObjectName)695*/696public ClassLoaderRepository getClassLoaderRepository() {697throw new TestBug("not implemented");698}699700/**701* Initializes {@link Log <code>Log</code>} object.702*703* @param log a new <code>Log</code> object.704*/705public void setLog(Log log) {706this.log = new Log.Logger(log, LOG_PREFIX + "> ");707}708709// **********************************************************************710//711// Private methods712//713// **********************************************************************714715/**716* Gets the object reference for a given MBean registered with the MBean717* server.718*719* @param name The object name of the MBean.720*721* @return The MBean object, specified by <code>name</code>.722*723* @throws InstanceNotFoundException The MBean specified is not registered724* in the MBean server.725*/726private DynamicMBean getObject(ObjectName name) throws InstanceNotFoundException {727DynamicMBean mbean = registeredMBeansStd.get(name);728if (mbean == null) {729ObjectKeeper objKeeper = registeredMBeans.get(name);730if (objKeeper == null)731throw new InstanceNotFoundException();732Object object = objKeeper.object;733if (object instanceof DynamicMBean)734mbean = (DynamicMBean) object;735else736mbean = new StandardMBean(object, getMBeanInterface(object), true);737registeredMBeansStd.put(name, mbean);738}739return mbean;740/*741ObjectKeeper objKeeper = (ObjectKeeper) registeredMBeans.get(name);742743if (objKeeper == null)744throw new InstanceNotFoundException();745746Class superOfMBeans = null;747try {748superOfMBeans = Class.forName(DYNAMICMBEAN_ITNF_NAME);749} catch (ClassNotFoundException e) {750throw new InstanceNotFoundException();751}752753if (superOfMBeans.isAssignableFrom(objKeeper.object.getClass())) {754return (DynamicMBean )objKeeper.object;755}756757return null;758*/759}760761/**762* Obtain NotificationBroadcaster for given MBean registered with the MBean763* server.764*765* @param name The object name of the MBean.766*767* @return The MBean object, specified by <code>name</code>.768*769* @throws InstanceNotFoundException if MBean specified is not registered770* in the MBean server.771*/772private NotificationBroadcaster getNotificationBroadcaster(ObjectName name) throws InstanceNotFoundException {773ObjectKeeper objKeeper = (ObjectKeeper) registeredMBeans.get(name);774if (objKeeper == null)775throw new InstanceNotFoundException();776Object mbean = objKeeper.object;777if (mbean instanceof NotificationBroadcaster)778return (NotificationBroadcaster) mbean;779throw new InstanceNotFoundException();780}781782/**783* Invoke the method784*/785private Object invokeObjectMethod(ObjectName name, String methodName,786Object[] params, String[] signature) throws InstanceNotFoundException,787MBeanException,788ReflectionException {789790if (log != null)791log.trace(TRACE_ALL, "[invokeObjectMethod] " + name + "> "792+ methodName);793794DynamicMBean mbean = getObject(name);795return mbean.invoke(methodName, params, signature);796}797798private Class getInterface(Class cl, String prefix) {799Class[] interfaces = cl.getInterfaces();800if (interfaces == null || interfaces.length == 0)801return null;802for (Class c : interfaces) {803if (c.getName().startsWith(prefix))804return c;805c = getInterface(c, prefix);806if (c != null)807return c;808}809return null;810}811812/**813* Discover MBean interface of the bean.814*815* Note: this is very specialized for java.lang.management816* and java.util.logging tests.817* It is generally not correct for any MBean.818*819* @param object the bean820* @return interface class821*/822private Class getMBeanInterface(Object object) throws InstanceNotFoundException {823String className = object.getClass().getName();824Class<?> iface = null;825if (className.startsWith("java.lang.management"))826iface = getInterface(object.getClass(), "java.lang.management");827else if (className.startsWith("java.util.logging"))828iface = getInterface(object.getClass(), "java.util.logging");829else if (className.startsWith("sun.management"))830iface = getInterface(object.getClass(), "java.lang.management");831if (iface != null)832return iface;833Class<?>[] interfaces = object.getClass().getInterfaces();834System.out.println(object);835System.out.println(object.getClass());836System.out.println(interfaces.length);837for (Class<?> c : interfaces) {838System.out.println(c.getName());839}840throw new TestBug("No suitable implemented interface found for: " + object + " class: " + object.getClass());841}842}843844845