/* * Copyright (c) 1999, 2008, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package javax.management.loading; // Java importimport com.sun.jmx.defaults.JmxProperties; import com.sun.jmx.defaults.ServiceName; import com.sun.jmx.remote.util.EnvHelp; import java.io.Externalizable;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInput;import java.io.ObjectInputStream;import java.io.ObjectOutput;import java.lang.reflect.Constructor;import java.net.MalformedURLException;import java.net.URL;import java.net.URLStreamHandlerFactory;import java.security.AccessController;import java.security.PrivilegedAction;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.logging.Level;import java.util.Map;import java.util.Set;import java.util.StringTokenizer; import javax.management.InstanceAlreadyExistsException;import javax.management.InstanceNotFoundException;import javax.management.MBeanException;import javax.management.MBeanRegistration;import javax.management.MBeanRegistrationException;import javax.management.MBeanServer;import javax.management.NotCompliantMBeanException;import javax.management.ObjectInstance;import javax.management.ObjectName;import javax.management.ReflectionException; import static com.sun.jmx.defaults.JmxProperties.MLET_LIB_DIR;import static com.sun.jmx.defaults.JmxProperties.MLET_LOGGER;import com.sun.jmx.defaults.ServiceName;import javax.management.ServiceNotFoundException; /** * Allows you to instantiate and register one or several MBeans in the MBean server * coming from a remote URL. M-let is a shortcut for management applet. The m-let service does this * by loading an m-let text file, which specifies information on the MBeans to be obtained. * The information on each MBean is specified in a single instance of a tag, called the MLET tag. * The location of the m-let text file is specified by a URL. * <p> * The <CODE>MLET</CODE> tag has the following syntax: * <p> * <<CODE>MLET</CODE><BR> * <CODE>CODE = </CODE><VAR>class</VAR><CODE> | OBJECT = </CODE><VAR>serfile</VAR><BR> * <CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE><BR> * <CODE>[CODEBASE = </CODE><VAR>codebaseURL</VAR><CODE>]</CODE><BR> * <CODE>[NAME = </CODE><VAR>mbeanname</VAR><CODE>]</CODE><BR> * <CODE>[VERSION = </CODE><VAR>version</VAR><CODE>]</CODE><BR> * ><BR> * <CODE>[</CODE><VAR>arglist</VAR><CODE>]</CODE><BR> * <<CODE>/MLET</CODE>> * <p> * where: * <DL> * <DT><CODE>CODE = </CODE><VAR>class</VAR></DT> * <DD> * This attribute specifies the full Java class name, including package name, of the MBean to be obtained. * The compiled <CODE>.class</CODE> file of the MBean must be contained in one of the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> * attribute. Either <CODE>CODE</CODE> or <CODE>OBJECT</CODE> must be present. * </DD> * <DT><CODE>OBJECT = </CODE><VAR>serfile</VAR></DT> * <DD> * This attribute specifies the <CODE>.ser</CODE> file that contains a serialized representation of the MBean to be obtained. * This file must be contained in one of the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> attribute. If the <CODE>.jar</CODE> file contains a directory hierarchy, specify the path of the file within this hierarchy. Otherwise a match will not be found. Either <CODE>CODE</CODE> or <CODE>OBJECT</CODE> must be present. * </DD> * <DT><CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE></DT> * <DD> * This mandatory attribute specifies one or more <CODE>.jar</CODE> files * containing MBeans or other resources used by * the MBean to be obtained. One of the <CODE>.jar</CODE> files must contain the file specified by the <CODE>CODE</CODE> or <CODE>OBJECT</CODE> attribute. * If archivelist contains more than one file: * <UL> * <LI>Each file must be separated from the one that follows it by a comma (,). * <LI><VAR>archivelist</VAR> must be enclosed in double quote marks. * </UL> * All <CODE>.jar</CODE> files in <VAR>archivelist</VAR> must be stored in the directory specified by the code base URL. * </DD> * <DT><CODE>CODEBASE = </CODE><VAR>codebaseURL</VAR></DT> * <DD> * This optional attribute specifies the code base URL of the MBean to be obtained. It identifies the directory that contains * the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> attribute. Specify this attribute only if the <CODE>.jar</CODE> files are not in the same * directory as the m-let text file. If this attribute is not specified, the base URL of the m-let text file is used. * </DD> * <DT><CODE>NAME = </CODE><VAR>mbeanname</VAR></DT> * <DD> * This optional attribute specifies the object name to be assigned to the * MBean instance when the m-let service registers it. If * <VAR>mbeanname</VAR> starts with the colon character (:), the domain * part of the object name is the default domain of the MBean server, * as returned by {@link javax.management.MBeanServer#getDefaultDomain()}. * </DD> * <DT><CODE>VERSION = </CODE><VAR>version</VAR></DT> * <DD> * This optional attribute specifies the version number of the MBean and * associated <CODE>.jar</CODE> files to be obtained. This version number can * be used to specify that the <CODE>.jar</CODE> files are loaded from the * server to update those stored locally in the cache the next time the m-let * text file is loaded. <VAR>version</VAR> must be a series of non-negative * decimal integers each separated by a period from the one that precedes it. * </DD> * <DT><VAR>arglist</VAR></DT> * <DD> * This optional attribute specifies a list of one or more parameters for the * MBean to be instantiated. This list describes the parameters to be passed the MBean's constructor. * Use the following syntax to specify each item in * <VAR>arglist</VAR>:</DD> * <DL> * <P> * <DT><<CODE>ARG TYPE=</CODE><VAR>argumentType</VAR> <CODE>VALUE=</CODE><VAR>value</VAR>></DT> * <P> * <DD>where:</DD> * <UL> * <LI><VAR>argumentType</VAR> is the type of the argument that will be passed as parameter to the MBean's constructor.</UL> * </DL> * <P>The arguments' type in the argument list should be a Java primitive type or a Java basic type * (<CODE>java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Long, java.lang.Integer, java.lang.Float, java.lang.Double, java.lang.String</CODE>). * </DL> * * When an m-let text file is loaded, an * instance of each MBean specified in the file is created and registered. * <P> * The m-let service extends the <CODE>java.net.URLClassLoader</CODE> and can be used to load remote classes * and jar files in the VM of the agent. * <p><STRONG>Note - </STRONG> The <CODE>MLet</CODE> class loader uses the {@link javax.management.MBeanServerFactory#getClassLoaderRepository(javax.management.MBeanServer)} * to load classes that could not be found in the loaded jar files. * * @since 1.5 */public class MLet extends java.net.URLClassLoader implements MLetMBean, MBeanRegistration, Externalizable { private static final long serialVersionUID = 3636148327800330130L; /* * ------------------------------------------ * PRIVATE VARIABLES * ------------------------------------------ */ /** * The reference to the MBean server. * @serial */ private MBeanServer server = null; /** * The list of instances of the <CODE>MLetContent</CODE> * class found at the specified URL. * @serial */ private List<MLetContent> mletList = new ArrayList<MLetContent>(); /** * The directory used for storing libraries locally before they are loaded. */ private String libraryDirectory; /** * The object name of the MLet Service. * @serial */ private ObjectName mletObjectName = null; /** * The URLs of the MLet Service. * @serial */ private URL[] myUrls = null; /** * What ClassLoaderRepository, if any, to use if this MLet * doesn't find an asked-for class. */ private transient ClassLoaderRepository currentClr; /** * True if we should consult the {@link ClassLoaderRepository} * when we do not find a class ourselves. */ private transient boolean delegateToCLR; /** * objects maps from primitive classes to primitive object classes. */ private Map<String,Class<?>> primitiveClasses = new HashMap<String,Class<?>>(8) ; { primitiveClasses.put(Boolean.TYPE.toString(), Boolean.class); primitiveClasses.put(Character.TYPE.toString(), Character.class); primitiveClasses.put(Byte.TYPE.toString(), Byte.class); primitiveClasses.put(Short.TYPE.toString(), Short.class); primitiveClasses.put(Integer.TYPE.toString(), Integer.class); primitiveClasses.put(Long.TYPE.toString(), Long.class); primitiveClasses.put(Float.TYPE.toString(), Float.class); primitiveClasses.put(Double.TYPE.toString(), Double.class); } /* * ------------------------------------------ * CONSTRUCTORS * ------------------------------------------ */ /* * The constructor stuff would be considerably simplified if our * parent, URLClassLoader, specified that its one- and * two-argument constructors were equivalent to its * three-argument constructor with trailing null arguments. But * it doesn't, which prevents us from having all the constructors * but one call this(...args...). */ /** * Constructs a new MLet using the default delegation parent ClassLoader. */ public MLet() { this(new URL[0]); } /** * Constructs a new MLet for the specified URLs using the default * delegation parent ClassLoader. The URLs will be searched in * the order specified for classes and resources after first * searching in the parent class loader. * * @param urls The URLs from which to load classes and resources. * */ public MLet(URL[] urls) { this(urls, true); } /** * Constructs a new MLet for the given URLs. The URLs will be * searched in the order specified for classes and resources * after first searching in the specified parent class loader. * The parent argument will be used as the parent class loader * for delegation. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * */ public MLet(URL[] urls, ClassLoader parent) { this(urls, parent, true); } /** * Constructs a new MLet for the specified URLs, parent class * loader, and URLStreamHandlerFactory. The parent argument will * be used as the parent class loader for delegation. The factory * argument will be used as the stream handler factory to obtain * protocol handlers when creating new URLs. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param factory The URLStreamHandlerFactory to use when creating URLs. * */ public MLet(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { this(urls, parent, factory, true); } /** * Constructs a new MLet for the specified URLs using the default * delegation parent ClassLoader. The URLs will be searched in * the order specified for classes and resources after first * searching in the parent class loader. * * @param urls The URLs from which to load classes and resources. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, boolean delegateToCLR) { super(urls); init(delegateToCLR); } /** * Constructs a new MLet for the given URLs. The URLs will be * searched in the order specified for classes and resources * after first searching in the specified parent class loader. * The parent argument will be used as the parent class loader * for delegation. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, ClassLoader parent, boolean delegateToCLR) { super(urls, parent); init(delegateToCLR); } /** * Constructs a new MLet for the specified URLs, parent class * loader, and URLStreamHandlerFactory. The parent argument will * be used as the parent class loader for delegation. The factory * argument will be used as the stream handler factory to obtain * protocol handlers when creating new URLs. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param factory The URLStreamHandlerFactory to use when creating URLs. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory, boolean delegateToCLR) { super(urls, parent, factory); init(delegateToCLR); } private void init(boolean delegateToCLR) { this.delegateToCLR = delegateToCLR; try { libraryDirectory = System.getProperty(MLET_LIB_DIR); if (libraryDirectory == null) libraryDirectory = getTmpDir(); } catch (SecurityException e) { // OK : We don't do AccessController.doPrivileged, but we don't // stop the user from creating an MLet just because they // can't read the MLET_LIB_DIR or java.io.tmpdir properties // either. } } /* * ------------------------------------------ * PUBLIC METHODS * ------------------------------------------ */ /** * Appends the specified URL to the list of URLs to search for classes and * resources. */ public void addURL(URL url) { if (!Arrays.asList(getURLs()).contains(url)) super.addURL(url); } /** * Appends the specified URL to the list of URLs to search for classes and * resources. * @exception ServiceNotFoundException The specified URL is malformed. */ public void addURL(String url) throws ServiceNotFoundException { try { URL ur = new URL(url); if (!Arrays.asList(getURLs()).contains(ur)) super.addURL(ur); } catch (MalformedURLException e) { if (MLET_LOGGER.isLoggable(Level.FINEST)) { MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(), "addUrl", "Malformed URL: " + url, e); } throw new ServiceNotFoundException("The specified URL is malformed"); } } /** Returns the search path of URLs for loading classes and resources. * This includes the original list of URLs specified to the constructor, * along with any URLs subsequently appended by the addURL() method. */ public URL[] getURLs() { return super.getURLs(); } /** * Loads a text file containing MLET tags that define the MBeans to * be added to the MBean server. The location of the text file is specified by * a URL. The MBeans specified in the MLET file will be instantiated and * registered in the MBean server. * * @param url The URL of the text file to be loaded as URL object. * * @return A set containing one entry per MLET tag in the m-let text file loaded. * Each entry specifies either the ObjectInstance for the created MBean, or a throwable object * (that is, an error or an exception) if the MBean could not be created. * * @exception ServiceNotFoundException One of the following errors has occurred: The m-let text file does * not contain an MLET tag, the m-let text file is not found, a mandatory * attribute of the MLET tag is not specified, the value of url is * null. * @exception IllegalStateException MLet MBean is not registered with an MBeanServer. */ public Set<Object> getMBeansFromURL(URL url) throws ServiceNotFoundException { if (url == null) { throw new ServiceNotFoundException("The specified URL is null"); } return getMBeansFromURL(url.toString()); } /** * Loads a text file containing MLET tags that define the MBeans to * be added to the MBean server. The location of the text file is specified by * a URL. The MBeans specified in the MLET file will be instantiated and * registered in the MBean server. * * @param url The URL of the text file to be loaded as String object. * * @return A set containing one entry per MLET tag in the m-let * text file loaded. Each entry specifies either the * ObjectInstance for the created MBean, or a throwable object * (that is, an error or an exception) if the MBean could not be * created. * * @exception ServiceNotFoundException One of the following * errors has occurred: The m-let text file does not contain an * MLET tag, the m-let text file is not found, a mandatory * attribute of the MLET tag is not specified, the url is * malformed. * @exception IllegalStateException MLet MBean is not registered * with an MBeanServer. * */ public Set<Object> getMBeansFromURL(String url) throws ServiceNotFoundException { String mth = "getMBeansFromURL"; if (server == null) { throw new IllegalStateException("This MLet MBean is not " + "registered with an MBeanServer."); } // Parse arguments if (url == null) { MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, "URL is null"); throw new ServiceNotFoundException("The specified URL is null"); } else { url = url.replace(File.separatorChar,'/'); } if (MLET_LOGGER.isLoggable(Level.FINER)) { MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, "<URL = " + url + ">"); }Lines 1–500 of 1336. Load more
/* * Copyright (c) 1999, 2008, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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. */ package javax.management.loading; // Java import import com.sun.jmx.defaults.JmxProperties; import com.sun.jmx.defaults.ServiceName; import com.sun.jmx.remote.util.EnvHelp; import java.io.Externalizable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.net.URLStreamHandlerFactory; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.logging.Level; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanException; import javax.management.MBeanRegistration; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.NotCompliantMBeanException; import javax.management.ObjectInstance; import javax.management.ObjectName; import javax.management.ReflectionException; import static com.sun.jmx.defaults.JmxProperties.MLET_LIB_DIR; import static com.sun.jmx.defaults.JmxProperties.MLET_LOGGER; import com.sun.jmx.defaults.ServiceName; import javax.management.ServiceNotFoundException; /** * Allows you to instantiate and register one or several MBeans in the MBean server * coming from a remote URL. M-let is a shortcut for management applet. The m-let service does this * by loading an m-let text file, which specifies information on the MBeans to be obtained. * The information on each MBean is specified in a single instance of a tag, called the MLET tag. * The location of the m-let text file is specified by a URL. * <p> * The <CODE>MLET</CODE> tag has the following syntax: * <p> * <<CODE>MLET</CODE><BR> * <CODE>CODE = </CODE><VAR>class</VAR><CODE> | OBJECT = </CODE><VAR>serfile</VAR><BR> * <CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE><BR> * <CODE>[CODEBASE = </CODE><VAR>codebaseURL</VAR><CODE>]</CODE><BR> * <CODE>[NAME = </CODE><VAR>mbeanname</VAR><CODE>]</CODE><BR> * <CODE>[VERSION = </CODE><VAR>version</VAR><CODE>]</CODE><BR> * ><BR> * <CODE>[</CODE><VAR>arglist</VAR><CODE>]</CODE><BR> * <<CODE>/MLET</CODE>> * <p> * where: * <DL> * <DT><CODE>CODE = </CODE><VAR>class</VAR></DT> * <DD> * This attribute specifies the full Java class name, including package name, of the MBean to be obtained. * The compiled <CODE>.class</CODE> file of the MBean must be contained in one of the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> * attribute. Either <CODE>CODE</CODE> or <CODE>OBJECT</CODE> must be present. * </DD> * <DT><CODE>OBJECT = </CODE><VAR>serfile</VAR></DT> * <DD> * This attribute specifies the <CODE>.ser</CODE> file that contains a serialized representation of the MBean to be obtained. * This file must be contained in one of the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> attribute. If the <CODE>.jar</CODE> file contains a directory hierarchy, specify the path of the file within this hierarchy. Otherwise a match will not be found. Either <CODE>CODE</CODE> or <CODE>OBJECT</CODE> must be present. * </DD> * <DT><CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE></DT> * <DD> * This mandatory attribute specifies one or more <CODE>.jar</CODE> files * containing MBeans or other resources used by * the MBean to be obtained. One of the <CODE>.jar</CODE> files must contain the file specified by the <CODE>CODE</CODE> or <CODE>OBJECT</CODE> attribute. * If archivelist contains more than one file: * <UL> * <LI>Each file must be separated from the one that follows it by a comma (,). * <LI><VAR>archivelist</VAR> must be enclosed in double quote marks. * </UL> * All <CODE>.jar</CODE> files in <VAR>archivelist</VAR> must be stored in the directory specified by the code base URL. * </DD> * <DT><CODE>CODEBASE = </CODE><VAR>codebaseURL</VAR></DT> * <DD> * This optional attribute specifies the code base URL of the MBean to be obtained. It identifies the directory that contains * the <CODE>.jar</CODE> files specified by the <CODE>ARCHIVE</CODE> attribute. Specify this attribute only if the <CODE>.jar</CODE> files are not in the same * directory as the m-let text file. If this attribute is not specified, the base URL of the m-let text file is used. * </DD> * <DT><CODE>NAME = </CODE><VAR>mbeanname</VAR></DT> * <DD> * This optional attribute specifies the object name to be assigned to the * MBean instance when the m-let service registers it. If * <VAR>mbeanname</VAR> starts with the colon character (:), the domain * part of the object name is the default domain of the MBean server, * as returned by {@link javax.management.MBeanServer#getDefaultDomain()}. * </DD> * <DT><CODE>VERSION = </CODE><VAR>version</VAR></DT> * <DD> * This optional attribute specifies the version number of the MBean and * associated <CODE>.jar</CODE> files to be obtained. This version number can * be used to specify that the <CODE>.jar</CODE> files are loaded from the * server to update those stored locally in the cache the next time the m-let * text file is loaded. <VAR>version</VAR> must be a series of non-negative * decimal integers each separated by a period from the one that precedes it. * </DD> * <DT><VAR>arglist</VAR></DT> * <DD> * This optional attribute specifies a list of one or more parameters for the * MBean to be instantiated. This list describes the parameters to be passed the MBean's constructor. * Use the following syntax to specify each item in * <VAR>arglist</VAR>:</DD> * <DL> * <P> * <DT><<CODE>ARG TYPE=</CODE><VAR>argumentType</VAR> <CODE>VALUE=</CODE><VAR>value</VAR>></DT> * <P> * <DD>where:</DD> * <UL> * <LI><VAR>argumentType</VAR> is the type of the argument that will be passed as parameter to the MBean's constructor.</UL> * </DL> * <P>The arguments' type in the argument list should be a Java primitive type or a Java basic type * (<CODE>java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Long, java.lang.Integer, java.lang.Float, java.lang.Double, java.lang.String</CODE>). * </DL> * * When an m-let text file is loaded, an * instance of each MBean specified in the file is created and registered. * <P> * The m-let service extends the <CODE>java.net.URLClassLoader</CODE> and can be used to load remote classes * and jar files in the VM of the agent. * <p><STRONG>Note - </STRONG> The <CODE>MLet</CODE> class loader uses the {@link javax.management.MBeanServerFactory#getClassLoaderRepository(javax.management.MBeanServer)} * to load classes that could not be found in the loaded jar files. * * @since 1.5 */ public class MLet extends java.net.URLClassLoader implements MLetMBean, MBeanRegistration, Externalizable { private static final long serialVersionUID = 3636148327800330130L; /* * ------------------------------------------ * PRIVATE VARIABLES * ------------------------------------------ */ /** * The reference to the MBean server. * @serial */ private MBeanServer server = null; /** * The list of instances of the <CODE>MLetContent</CODE> * class found at the specified URL. * @serial */ private List<MLetContent> mletList = new ArrayList<MLetContent>(); /** * The directory used for storing libraries locally before they are loaded. */ private String libraryDirectory; /** * The object name of the MLet Service. * @serial */ private ObjectName mletObjectName = null; /** * The URLs of the MLet Service. * @serial */ private URL[] myUrls = null; /** * What ClassLoaderRepository, if any, to use if this MLet * doesn't find an asked-for class. */ private transient ClassLoaderRepository currentClr; /** * True if we should consult the {@link ClassLoaderRepository} * when we do not find a class ourselves. */ private transient boolean delegateToCLR; /** * objects maps from primitive classes to primitive object classes. */ private Map<String,Class<?>> primitiveClasses = new HashMap<String,Class<?>>(8) ; { primitiveClasses.put(Boolean.TYPE.toString(), Boolean.class); primitiveClasses.put(Character.TYPE.toString(), Character.class); primitiveClasses.put(Byte.TYPE.toString(), Byte.class); primitiveClasses.put(Short.TYPE.toString(), Short.class); primitiveClasses.put(Integer.TYPE.toString(), Integer.class); primitiveClasses.put(Long.TYPE.toString(), Long.class); primitiveClasses.put(Float.TYPE.toString(), Float.class); primitiveClasses.put(Double.TYPE.toString(), Double.class); } /* * ------------------------------------------ * CONSTRUCTORS * ------------------------------------------ */ /* * The constructor stuff would be considerably simplified if our * parent, URLClassLoader, specified that its one- and * two-argument constructors were equivalent to its * three-argument constructor with trailing null arguments. But * it doesn't, which prevents us from having all the constructors * but one call this(...args...). */ /** * Constructs a new MLet using the default delegation parent ClassLoader. */ public MLet() { this(new URL[0]); } /** * Constructs a new MLet for the specified URLs using the default * delegation parent ClassLoader. The URLs will be searched in * the order specified for classes and resources after first * searching in the parent class loader. * * @param urls The URLs from which to load classes and resources. * */ public MLet(URL[] urls) { this(urls, true); } /** * Constructs a new MLet for the given URLs. The URLs will be * searched in the order specified for classes and resources * after first searching in the specified parent class loader. * The parent argument will be used as the parent class loader * for delegation. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * */ public MLet(URL[] urls, ClassLoader parent) { this(urls, parent, true); } /** * Constructs a new MLet for the specified URLs, parent class * loader, and URLStreamHandlerFactory. The parent argument will * be used as the parent class loader for delegation. The factory * argument will be used as the stream handler factory to obtain * protocol handlers when creating new URLs. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param factory The URLStreamHandlerFactory to use when creating URLs. * */ public MLet(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { this(urls, parent, factory, true); } /** * Constructs a new MLet for the specified URLs using the default * delegation parent ClassLoader. The URLs will be searched in * the order specified for classes and resources after first * searching in the parent class loader. * * @param urls The URLs from which to load classes and resources. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, boolean delegateToCLR) { super(urls); init(delegateToCLR); } /** * Constructs a new MLet for the given URLs. The URLs will be * searched in the order specified for classes and resources * after first searching in the specified parent class loader. * The parent argument will be used as the parent class loader * for delegation. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, ClassLoader parent, boolean delegateToCLR) { super(urls, parent); init(delegateToCLR); } /** * Constructs a new MLet for the specified URLs, parent class * loader, and URLStreamHandlerFactory. The parent argument will * be used as the parent class loader for delegation. The factory * argument will be used as the stream handler factory to obtain * protocol handlers when creating new URLs. * * @param urls The URLs from which to load classes and resources. * @param parent The parent class loader for delegation. * @param factory The URLStreamHandlerFactory to use when creating URLs. * @param delegateToCLR True if, when a class is not found in * either the parent ClassLoader or the URLs, the MLet should delegate * to its containing MBeanServer's {@link ClassLoaderRepository}. * */ public MLet(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory, boolean delegateToCLR) { super(urls, parent, factory); init(delegateToCLR); } private void init(boolean delegateToCLR) { this.delegateToCLR = delegateToCLR; try { libraryDirectory = System.getProperty(MLET_LIB_DIR); if (libraryDirectory == null) libraryDirectory = getTmpDir(); } catch (SecurityException e) { // OK : We don't do AccessController.doPrivileged, but we don't // stop the user from creating an MLet just because they // can't read the MLET_LIB_DIR or java.io.tmpdir properties // either. } } /* * ------------------------------------------ * PUBLIC METHODS * ------------------------------------------ */ /** * Appends the specified URL to the list of URLs to search for classes and * resources. */ public void addURL(URL url) { if (!Arrays.asList(getURLs()).contains(url)) super.addURL(url); } /** * Appends the specified URL to the list of URLs to search for classes and * resources. * @exception ServiceNotFoundException The specified URL is malformed. */ public void addURL(String url) throws ServiceNotFoundException { try { URL ur = new URL(url); if (!Arrays.asList(getURLs()).contains(ur)) super.addURL(ur); } catch (MalformedURLException e) { if (MLET_LOGGER.isLoggable(Level.FINEST)) { MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(), "addUrl", "Malformed URL: " + url, e); } throw new ServiceNotFoundException("The specified URL is malformed"); } } /** Returns the search path of URLs for loading classes and resources. * This includes the original list of URLs specified to the constructor, * along with any URLs subsequently appended by the addURL() method. */ public URL[] getURLs() { return super.getURLs(); } /** * Loads a text file containing MLET tags that define the MBeans to * be added to the MBean server. The location of the text file is specified by * a URL. The MBeans specified in the MLET file will be instantiated and * registered in the MBean server. * * @param url The URL of the text file to be loaded as URL object. * * @return A set containing one entry per MLET tag in the m-let text file loaded. * Each entry specifies either the ObjectInstance for the created MBean, or a throwable object * (that is, an error or an exception) if the MBean could not be created. * * @exception ServiceNotFoundException One of the following errors has occurred: The m-let text file does * not contain an MLET tag, the m-let text file is not found, a mandatory * attribute of the MLET tag is not specified, the value of url is * null. * @exception IllegalStateException MLet MBean is not registered with an MBeanServer. */ public Set<Object> getMBeansFromURL(URL url) throws ServiceNotFoundException { if (url == null) { throw new ServiceNotFoundException("The specified URL is null"); } return getMBeansFromURL(url.toString()); } /** * Loads a text file containing MLET tags that define the MBeans to * be added to the MBean server. The location of the text file is specified by * a URL. The MBeans specified in the MLET file will be instantiated and * registered in the MBean server. * * @param url The URL of the text file to be loaded as String object. * * @return A set containing one entry per MLET tag in the m-let * text file loaded. Each entry specifies either the * ObjectInstance for the created MBean, or a throwable object * (that is, an error or an exception) if the MBean could not be * created. * * @exception ServiceNotFoundException One of the following * errors has occurred: The m-let text file does not contain an * MLET tag, the m-let text file is not found, a mandatory * attribute of the MLET tag is not specified, the url is * malformed. * @exception IllegalStateException MLet MBean is not registered * with an MBeanServer. * */ public Set<Object> getMBeansFromURL(String url) throws ServiceNotFoundException { String mth = "getMBeansFromURL"; if (server == null) { throw new IllegalStateException("This MLet MBean is not " + "registered with an MBeanServer."); } // Parse arguments if (url == null) { MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, "URL is null"); throw new ServiceNotFoundException("The specified URL is null"); } else { url = url.replace(File.separatorChar,'/'); } if (MLET_LOGGER.isLoggable(Level.FINER)) { MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, "<URL = " + url + ">"); }