Save This Page
Home » openjdk-7 » javax » management » loading » [javadoc | source]
    1   /*
    2    * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.management.loading;
   27   
   28   // Java import
   29   import com.sun.jmx.defaults.JmxProperties;
   30   
   31   import com.sun.jmx.defaults.ServiceName;
   32   
   33   import com.sun.jmx.remote.util.EnvHelp;
   34   
   35   import java.io.Externalizable;
   36   import java.io.File;
   37   import java.io.FileOutputStream;
   38   import java.io.IOException;
   39   import java.io.InputStream;
   40   import java.io.ObjectInput;
   41   import java.io.ObjectInputStream;
   42   import java.io.ObjectOutput;
   43   import java.lang.reflect.Constructor;
   44   import java.net.MalformedURLException;
   45   import java.net.URL;
   46   import java.net.URLStreamHandlerFactory;
   47   import java.security.AccessController;
   48   import java.security.PrivilegedAction;
   49   import java.util.ArrayList;
   50   import java.util.Arrays;
   51   import java.util.HashMap;
   52   import java.util.HashSet;
   53   import java.util.List;
   54   import java.util.logging.Level;
   55   import java.util.Map;
   56   import java.util.Set;
   57   import java.util.StringTokenizer;
   58   
   59   import javax.management.InstanceAlreadyExistsException;
   60   import javax.management.InstanceNotFoundException;
   61   import javax.management.MBeanException;
   62   import javax.management.MBeanRegistration;
   63   import javax.management.MBeanRegistrationException;
   64   import javax.management.MBeanServer;
   65   import javax.management.NotCompliantMBeanException;
   66   import javax.management.ObjectInstance;
   67   import javax.management.ObjectName;
   68   import javax.management.ReflectionException;
   69   
   70   import static com.sun.jmx.defaults.JmxProperties.MLET_LIB_DIR;
   71   import static com.sun.jmx.defaults.JmxProperties.MLET_LOGGER;
   72   import com.sun.jmx.defaults.ServiceName;
   73   import javax.management.ServiceNotFoundException;
   74   
   75   /**
   76    * Allows you to instantiate and register one or several MBeans in the MBean server
   77    * coming from a remote URL. M-let is a shortcut for management applet. The m-let service does this
   78    * by loading an m-let text file, which specifies information on the MBeans to be obtained.
   79    * The information on each MBean is specified in a single instance of a tag, called the MLET tag.
   80    * The location of the m-let text file is specified by a URL.
   81    * <p>
   82    * The <CODE>MLET</CODE> tag has the following syntax:
   83    * <p>
   84    * &lt;<CODE>MLET</CODE><BR>
   85    *      <CODE>CODE = </CODE><VAR>class</VAR><CODE> | OBJECT = </CODE><VAR>serfile</VAR><BR>
   86    *      <CODE>ARCHIVE = &quot;</CODE><VAR>archiveList</VAR><CODE>&quot;</CODE><BR>
   87    *      <CODE>[CODEBASE = </CODE><VAR>codebaseURL</VAR><CODE>]</CODE><BR>
   88    *      <CODE>[NAME = </CODE><VAR>mbeanname</VAR><CODE>]</CODE><BR>
   89    *      <CODE>[VERSION = </CODE><VAR>version</VAR><CODE>]</CODE><BR>
   90    * &gt;<BR>
   91    *      <CODE>[</CODE><VAR>arglist</VAR><CODE>]</CODE><BR>
   92    * &lt;<CODE>/MLET</CODE>&gt;
   93    * <p>
   94    * where:
   95    * <DL>
   96    * <DT><CODE>CODE = </CODE><VAR>class</VAR></DT>
   97    * <DD>
   98    * This attribute specifies the full Java class name, including package name, of the MBean to be obtained.
   99    * 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>
  100    * attribute. Either <CODE>CODE</CODE> or <CODE>OBJECT</CODE> must be present.
  101    * </DD>
  102    * <DT><CODE>OBJECT = </CODE><VAR>serfile</VAR></DT>
  103    * <DD>
  104    * This attribute specifies the <CODE>.ser</CODE> file that contains a serialized representation of the MBean to be obtained.
  105    * 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.
  106    * </DD>
  107    * <DT><CODE>ARCHIVE = &quot;</CODE><VAR>archiveList</VAR><CODE>&quot;</CODE></DT>
  108    * <DD>
  109    * This mandatory attribute specifies one or more <CODE>.jar</CODE> files
  110    * containing MBeans or other resources used by
  111    * 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.
  112    * If archivelist contains more than one file:
  113    * <UL>
  114    * <LI>Each file must be separated from the one that follows it by a comma (,).
  115    * <LI><VAR>archivelist</VAR> must be enclosed in double quote marks.
  116    * </UL>
  117    * All <CODE>.jar</CODE> files in <VAR>archivelist</VAR> must be stored in the directory specified by the code base URL.
  118    * </DD>
  119    * <DT><CODE>CODEBASE = </CODE><VAR>codebaseURL</VAR></DT>
  120    * <DD>
  121    * This optional attribute specifies the code base URL of the MBean to be obtained. It identifies the directory that contains
  122    * 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
  123    * directory as the m-let text file. If this attribute is not specified, the base URL of the m-let text file is used.
  124    * </DD>
  125    * <DT><CODE>NAME = </CODE><VAR>mbeanname</VAR></DT>
  126    * <DD>
  127    * This optional attribute specifies the object name to be assigned to the
  128    * MBean instance when the m-let service registers it. If
  129    * <VAR>mbeanname</VAR> starts with the colon character (:), the domain
  130    * part of the object name is the default domain of the MBean server,
  131    * as returned by {@link javax.management.MBeanServer#getDefaultDomain()}.
  132    * </DD>
  133    * <DT><CODE>VERSION = </CODE><VAR>version</VAR></DT>
  134    * <DD>
  135    * This optional attribute specifies the version number of the MBean and
  136    * associated <CODE>.jar</CODE> files to be obtained. This version number can
  137    * be used to specify that the <CODE>.jar</CODE> files are loaded from the
  138    * server to update those stored locally in the cache the next time the m-let
  139    * text file is loaded. <VAR>version</VAR> must be a series of non-negative
  140    * decimal integers each separated by a period from the one that precedes it.
  141    * </DD>
  142    * <DT><VAR>arglist</VAR></DT>
  143    * <DD>
  144    * This optional attribute specifies a list of one or more parameters for the
  145    * MBean to be instantiated. This list describes the parameters to be passed the MBean's constructor.
  146    * Use the following syntax to specify each item in
  147    * <VAR>arglist</VAR>:</DD>
  148    * <DL>
  149    * <P>
  150    * <DT>&lt;<CODE>ARG TYPE=</CODE><VAR>argumentType</VAR> <CODE>VALUE=</CODE><VAR>value</VAR>&gt;</DT>
  151    * <P>
  152    * <DD>where:</DD>
  153    * <UL>
  154    * <LI><VAR>argumentType</VAR> is the type of the argument that will be passed as parameter to the MBean's constructor.</UL>
  155    * </DL>
  156    * <P>The arguments' type in the argument list should be a Java primitive type or a Java basic type
  157    * (<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>).
  158    * </DL>
  159    *
  160    * When an m-let text file is loaded, an
  161    * instance of each MBean specified in the file is created and registered.
  162    * <P>
  163    * The m-let service extends the <CODE>java.net.URLClassLoader</CODE> and can be used to load remote classes
  164    * and jar files in the VM of the agent.
  165    * <p><STRONG>Note - </STRONG> The <CODE>MLet</CODE> class loader uses the {@link javax.management.MBeanServerFactory#getClassLoaderRepository(javax.management.MBeanServer)}
  166    * to load classes that could not be found in the loaded jar files.
  167    *
  168    * @since 1.5
  169    */
  170   public class MLet extends java.net.URLClassLoader
  171        implements MLetMBean, MBeanRegistration, Externalizable {
  172   
  173        private static final long serialVersionUID = 3636148327800330130L;
  174   
  175        /*
  176        * ------------------------------------------
  177        *   PRIVATE VARIABLES
  178        * ------------------------------------------
  179        */
  180   
  181        /**
  182         * The reference to the MBean server.
  183         * @serial
  184         */
  185        private MBeanServer server = null;
  186   
  187   
  188        /**
  189         * The list of instances of the <CODE>MLetContent</CODE>
  190         * class found at the specified URL.
  191         * @serial
  192         */
  193        private List<MLetContent> mletList = new ArrayList<MLetContent>();
  194   
  195   
  196        /**
  197         * The directory used for storing libraries locally before they are loaded.
  198         */
  199        private String libraryDirectory;
  200   
  201   
  202        /**
  203         * The object name of the MLet Service.
  204         * @serial
  205         */
  206        private ObjectName mletObjectName = null;
  207   
  208        /**
  209         * The URLs of the MLet Service.
  210         * @serial
  211         */
  212        private URL[] myUrls = null;
  213   
  214        /**
  215         * What ClassLoaderRepository, if any, to use if this MLet
  216         * doesn't find an asked-for class.
  217         */
  218        private transient ClassLoaderRepository currentClr;
  219   
  220        /**
  221         * True if we should consult the {@link ClassLoaderRepository}
  222         * when we do not find a class ourselves.
  223         */
  224        private transient boolean delegateToCLR;
  225   
  226        /**
  227         * objects maps from primitive classes to primitive object classes.
  228         */
  229        private Map<String,Class<?>> primitiveClasses =
  230            new HashMap<String,Class<?>>(8) ;
  231        {
  232            primitiveClasses.put(Boolean.TYPE.toString(), Boolean.class);
  233            primitiveClasses.put(Character.TYPE.toString(), Character.class);
  234            primitiveClasses.put(Byte.TYPE.toString(), Byte.class);
  235            primitiveClasses.put(Short.TYPE.toString(), Short.class);
  236            primitiveClasses.put(Integer.TYPE.toString(), Integer.class);
  237            primitiveClasses.put(Long.TYPE.toString(), Long.class);
  238            primitiveClasses.put(Float.TYPE.toString(), Float.class);
  239            primitiveClasses.put(Double.TYPE.toString(), Double.class);
  240   
  241        }
  242   
  243   
  244        /*
  245         * ------------------------------------------
  246         *  CONSTRUCTORS
  247         * ------------------------------------------
  248         */
  249   
  250        /*
  251         * The constructor stuff would be considerably simplified if our
  252         * parent, URLClassLoader, specified that its one- and
  253         * two-argument constructors were equivalent to its
  254         * three-argument constructor with trailing null arguments.  But
  255         * it doesn't, which prevents us from having all the constructors
  256         * but one call this(...args...).
  257         */
  258   
  259        /**
  260         * Constructs a new MLet using the default delegation parent ClassLoader.
  261         */
  262        public MLet() {
  263            this(new URL[0]);
  264        }
  265   
  266        /**
  267         * Constructs a new MLet for the specified URLs using the default
  268         * delegation parent ClassLoader.  The URLs will be searched in
  269         * the order specified for classes and resources after first
  270         * searching in the parent class loader.
  271         *
  272         * @param  urls  The URLs from which to load classes and resources.
  273         *
  274         */
  275        public MLet(URL[] urls) {
  276            this(urls, true);
  277        }
  278   
  279        /**
  280         * Constructs a new MLet for the given URLs. The URLs will be
  281         * searched in the order specified for classes and resources
  282         * after first searching in the specified parent class loader.
  283         * The parent argument will be used as the parent class loader
  284         * for delegation.
  285         *
  286         * @param  urls  The URLs from which to load classes and resources.
  287         * @param  parent The parent class loader for delegation.
  288         *
  289         */
  290        public MLet(URL[] urls, ClassLoader parent) {
  291            this(urls, parent, true);
  292        }
  293   
  294        /**
  295         * Constructs a new MLet for the specified URLs, parent class
  296         * loader, and URLStreamHandlerFactory. The parent argument will
  297         * be used as the parent class loader for delegation. The factory
  298         * argument will be used as the stream handler factory to obtain
  299         * protocol handlers when creating new URLs.
  300         *
  301         * @param  urls  The URLs from which to load classes and resources.
  302         * @param  parent The parent class loader for delegation.
  303         * @param  factory  The URLStreamHandlerFactory to use when creating URLs.
  304         *
  305         */
  306        public MLet(URL[] urls,
  307                    ClassLoader parent,
  308                    URLStreamHandlerFactory factory) {
  309            this(urls, parent, factory, true);
  310        }
  311   
  312        /**
  313         * Constructs a new MLet for the specified URLs using the default
  314         * delegation parent ClassLoader.  The URLs will be searched in
  315         * the order specified for classes and resources after first
  316         * searching in the parent class loader.
  317         *
  318         * @param  urls  The URLs from which to load classes and resources.
  319         * @param  delegateToCLR  True if, when a class is not found in
  320         * either the parent ClassLoader or the URLs, the MLet should delegate
  321         * to its containing MBeanServer's {@link ClassLoaderRepository}.
  322         *
  323         */
  324        public MLet(URL[] urls, boolean delegateToCLR) {
  325            super(urls);
  326            init(delegateToCLR);
  327        }
  328   
  329        /**
  330         * Constructs a new MLet for the given URLs. The URLs will be
  331         * searched in the order specified for classes and resources
  332         * after first searching in the specified parent class loader.
  333         * The parent argument will be used as the parent class loader
  334         * for delegation.
  335         *
  336         * @param  urls  The URLs from which to load classes and resources.
  337         * @param  parent The parent class loader for delegation.
  338         * @param  delegateToCLR  True if, when a class is not found in
  339         * either the parent ClassLoader or the URLs, the MLet should delegate
  340         * to its containing MBeanServer's {@link ClassLoaderRepository}.
  341         *
  342         */
  343        public MLet(URL[] urls, ClassLoader parent, boolean delegateToCLR) {
  344            super(urls, parent);
  345            init(delegateToCLR);
  346        }
  347   
  348        /**
  349         * Constructs a new MLet for the specified URLs, parent class
  350         * loader, and URLStreamHandlerFactory. The parent argument will
  351         * be used as the parent class loader for delegation. The factory
  352         * argument will be used as the stream handler factory to obtain
  353         * protocol handlers when creating new URLs.
  354         *
  355         * @param  urls  The URLs from which to load classes and resources.
  356         * @param  parent The parent class loader for delegation.
  357         * @param  factory  The URLStreamHandlerFactory to use when creating URLs.
  358         * @param  delegateToCLR  True if, when a class is not found in
  359         * either the parent ClassLoader or the URLs, the MLet should delegate
  360         * to its containing MBeanServer's {@link ClassLoaderRepository}.
  361         *
  362         */
  363        public MLet(URL[] urls,
  364                    ClassLoader parent,
  365                    URLStreamHandlerFactory factory,
  366                    boolean delegateToCLR) {
  367            super(urls, parent, factory);
  368            init(delegateToCLR);
  369        }
  370   
  371        private void init(boolean delegateToCLR) {
  372            this.delegateToCLR = delegateToCLR;
  373   
  374            try {
  375                libraryDirectory = System.getProperty(MLET_LIB_DIR);
  376                if (libraryDirectory == null)
  377                    libraryDirectory = getTmpDir();
  378            } catch (SecurityException e) {
  379                // OK : We don't do AccessController.doPrivileged, but we don't
  380                //      stop the user from creating an MLet just because they
  381                //      can't read the MLET_LIB_DIR or java.io.tmpdir properties
  382                //      either.
  383            }
  384        }
  385   
  386   
  387        /*
  388         * ------------------------------------------
  389         *  PUBLIC METHODS
  390         * ------------------------------------------
  391         */
  392   
  393   
  394        /**
  395         * Appends the specified URL to the list of URLs to search for classes and
  396         * resources.
  397         */
  398        public void addURL(URL url) {
  399            if (!Arrays.asList(getURLs()).contains(url))
  400                super.addURL(url);
  401        }
  402   
  403        /**
  404         * Appends the specified URL to the list of URLs to search for classes and
  405         * resources.
  406         * @exception ServiceNotFoundException The specified URL is malformed.
  407         */
  408        public void addURL(String url) throws ServiceNotFoundException {
  409            try {
  410                URL ur = new URL(url);
  411                if (!Arrays.asList(getURLs()).contains(ur))
  412                    super.addURL(ur);
  413            } catch (MalformedURLException e) {
  414                if (MLET_LOGGER.isLoggable(Level.FINEST)) {
  415                    MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  416                            "addUrl", "Malformed URL: " + url, e);
  417                }
  418                throw new
  419                    ServiceNotFoundException("The specified URL is malformed");
  420            }
  421        }
  422   
  423        /** Returns the search path of URLs for loading classes and resources.
  424         * This includes the original list of URLs specified to the constructor,
  425         * along with any URLs subsequently appended by the addURL() method.
  426         */
  427        public URL[] getURLs() {
  428            return super.getURLs();
  429        }
  430   
  431        /**
  432         * Loads a text file containing MLET tags that define the MBeans to
  433         * be added to the MBean server. The location of the text file is specified by
  434         * a URL. The MBeans specified in the MLET file will be instantiated and
  435         * registered in the MBean server.
  436         *
  437         * @param url The URL of the text file to be loaded as URL object.
  438         *
  439         * @return  A set containing one entry per MLET tag in the m-let text file loaded.
  440         * Each entry specifies either the ObjectInstance for the created MBean, or a throwable object
  441         * (that is, an error or an exception) if the MBean could not be created.
  442         *
  443         * @exception ServiceNotFoundException One of the following errors has occurred: The m-let text file does
  444         * not contain an MLET tag, the m-let text file is not found, a mandatory
  445         * attribute of the MLET tag is not specified, the value of url is
  446         * null.
  447         * @exception IllegalStateException MLet MBean is not registered with an MBeanServer.
  448         */
  449        public Set<Object> getMBeansFromURL(URL url)
  450                throws ServiceNotFoundException  {
  451            if (url == null) {
  452                throw new ServiceNotFoundException("The specified URL is null");
  453            }
  454            return getMBeansFromURL(url.toString());
  455        }
  456   
  457        /**
  458         * Loads a text file containing MLET tags that define the MBeans to
  459         * be added to the MBean server. The location of the text file is specified by
  460         * a URL. The MBeans specified in the MLET file will be instantiated and
  461         * registered in the MBean server.
  462         *
  463         * @param url The URL of the text file to be loaded as String object.
  464         *
  465         * @return A set containing one entry per MLET tag in the m-let
  466         * text file loaded.  Each entry specifies either the
  467         * ObjectInstance for the created MBean, or a throwable object
  468         * (that is, an error or an exception) if the MBean could not be
  469         * created.
  470         *
  471         * @exception ServiceNotFoundException One of the following
  472         * errors has occurred: The m-let text file does not contain an
  473         * MLET tag, the m-let text file is not found, a mandatory
  474         * attribute of the MLET tag is not specified, the url is
  475         * malformed.
  476         * @exception IllegalStateException MLet MBean is not registered
  477         * with an MBeanServer.
  478         *
  479         */
  480        public Set<Object> getMBeansFromURL(String url)
  481                throws ServiceNotFoundException  {
  482   
  483            String mth = "getMBeansFromURL";
  484   
  485            if (server == null) {
  486                throw new IllegalStateException("This MLet MBean is not " +
  487                                                "registered with an MBeanServer.");
  488            }
  489            // Parse arguments
  490            if (url == null) {
  491                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
  492                        mth, "URL is null");
  493                throw new ServiceNotFoundException("The specified URL is null");
  494            } else {
  495                url = url.replace(File.separatorChar,'/');
  496            }
  497            if (MLET_LOGGER.isLoggable(Level.FINER)) {
  498                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
  499                        mth, "<URL = " + url + ">");
  500            }
  501   
  502            // Parse URL
  503            try {
  504                MLetParser parser = new MLetParser();
  505                mletList = parser.parseURL(url);
  506            } catch (Exception e) {
  507                final String msg =
  508                    "Problems while parsing URL [" + url +
  509                    "], got exception [" + e.toString() + "]";
  510                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, msg);
  511                throw EnvHelp.initCause(new ServiceNotFoundException(msg), e);
  512            }
  513   
  514            // Check that the list of MLets is not empty
  515            if (mletList.size() == 0) {
  516                final String msg =
  517                    "File " + url + " not found or MLET tag not defined in file";
  518                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, msg);
  519                throw new ServiceNotFoundException(msg);
  520            }
  521   
  522            // Walk through the list of MLets
  523            Set<Object> mbeans = new HashSet<Object>();
  524            for (MLetContent elmt : mletList) {
  525                // Initialize local variables
  526                String code = elmt.getCode();
  527                if (code != null) {
  528                    if (code.endsWith(".class")) {
  529                        code = code.substring(0, code.length() - 6);
  530                    }
  531                }
  532                String name = elmt.getName();
  533                URL codebase = elmt.getCodeBase();
  534                String version = elmt.getVersion();
  535                String serName = elmt.getSerializedObject();
  536                String jarFiles = elmt.getJarFiles();
  537                URL documentBase = elmt.getDocumentBase();
  538   
  539                // Display debug information
  540                if (MLET_LOGGER.isLoggable(Level.FINER)) {
  541                    final StringBuilder strb = new StringBuilder()
  542                    .append("\n\tMLET TAG     = ").append(elmt.getAttributes())
  543                    .append("\n\tCODEBASE     = ").append(codebase)
  544                    .append("\n\tARCHIVE      = ").append(jarFiles)
  545                    .append("\n\tCODE         = ").append(code)
  546                    .append("\n\tOBJECT       = ").append(serName)
  547                    .append("\n\tNAME         = ").append(name)
  548                    .append("\n\tVERSION      = ").append(version)
  549                    .append("\n\tDOCUMENT URL = ").append(documentBase);
  550                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
  551                            mth, strb.toString());
  552                }
  553   
  554                // Load classes from JAR files
  555                StringTokenizer st = new StringTokenizer(jarFiles, ",", false);
  556                while (st.hasMoreTokens()) {
  557                    String tok = st.nextToken().trim();
  558                    if (MLET_LOGGER.isLoggable(Level.FINER)) {
  559                        MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  560                                "Load archive for codebase <" + codebase +
  561                                ">, file <" + tok + ">");
  562                    }
  563                    // Check which is the codebase to be used for loading the jar file.
  564                    // If we are using the base MLet implementation then it will be
  565                    // always the remote server but if the service has been extended in
  566                    // order to support caching and versioning then this method will
  567                    // return the appropriate one.
  568                    //
  569                    try {
  570                        codebase = check(version, codebase, tok, elmt);
  571                    } catch (Exception ex) {
  572                        MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  573                                mth, "Got unexpected exception", ex);
  574                        mbeans.add(ex);
  575                        continue;
  576                    }
  577   
  578                    // Appends the specified JAR file URL to the list of
  579                    // URLs to search for classes and resources.
  580                    try {
  581                        if (!Arrays.asList(getURLs())
  582                            .contains(new URL(codebase.toString() + tok))) {
  583                            addURL(codebase + tok);
  584                        }
  585                    } catch (MalformedURLException me) {
  586                        // OK : Ignore jar file if its name provokes the
  587                        // URL to be an invalid one.
  588                    }
  589   
  590                }
  591                // Instantiate the class specified in the
  592                // CODE or OBJECT section of the MLet tag
  593                //
  594                Object o;
  595                ObjectInstance objInst;
  596   
  597                if (code != null && serName != null) {
  598                    final String msg =
  599                        "CODE and OBJECT parameters cannot be specified at the " +
  600                        "same time in tag MLET";
  601                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, msg);
  602                    mbeans.add(new Error(msg));
  603                    continue;
  604                }
  605                if (code == null && serName == null) {
  606                    final String msg =
  607                        "Either CODE or OBJECT parameter must be specified in " +
  608                        "tag MLET";
  609                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth, msg);
  610                    mbeans.add(new Error(msg));
  611                    continue;
  612                }
  613                try {
  614                    if (code != null) {
  615   
  616                        List<String> signat = elmt.getParameterTypes();
  617                        List<String> stringPars = elmt.getParameterValues();
  618                        List<Object> objectPars = new ArrayList<Object>();
  619   
  620                        for (int i = 0; i < signat.size(); i++) {
  621                            objectPars.add(constructParameter(stringPars.get(i),
  622                                                              signat.get(i)));
  623                        }
  624                        if (signat.isEmpty()) {
  625                            if (name == null) {
  626                                objInst = server.createMBean(code, null,
  627                                                             mletObjectName);
  628                            } else {
  629                                objInst = server.createMBean(code,
  630                                                             new ObjectName(name),
  631                                                             mletObjectName);
  632                            }
  633                        } else {
  634                            Object[] parms = objectPars.toArray();
  635                            String[] signature = new String[signat.size()];
  636                            signat.toArray(signature);
  637                            if (MLET_LOGGER.isLoggable(Level.FINEST)) {
  638                                final StringBuilder strb = new StringBuilder();
  639                                for (int i = 0; i < signature.length; i++) {
  640                                    strb.append("\n\tSignature     = ")
  641                                    .append(signature[i])
  642                                    .append("\t\nParams        = ")
  643                                    .append(parms[i]);
  644                                }
  645                                MLET_LOGGER.logp(Level.FINEST,
  646                                        MLet.class.getName(),
  647                                        mth, strb.toString());
  648                            }
  649                            if (name == null) {
  650                                objInst =
  651                                    server.createMBean(code, null, mletObjectName,
  652                                                       parms, signature);
  653                            } else {
  654                                objInst =
  655                                    server.createMBean(code, new ObjectName(name),
  656                                                       mletObjectName, parms,
  657                                                       signature);
  658                            }
  659                        }
  660                    } else {
  661                        o = loadSerializedObject(codebase,serName);
  662                        if (name == null) {
  663                            server.registerMBean(o, null);
  664                        } else {
  665                            server.registerMBean(o,  new ObjectName(name));
  666                        }
  667                        objInst = new ObjectInstance(name, o.getClass().getName());
  668                    }
  669                } catch (ReflectionException  ex) {
  670                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  671                            "ReflectionException", ex);
  672                    mbeans.add(ex);
  673                    continue;
  674                } catch (InstanceAlreadyExistsException  ex) {
  675                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  676                            "InstanceAlreadyExistsException", ex);
  677                    mbeans.add(ex);
  678                    continue;
  679                } catch (MBeanRegistrationException ex) {
  680                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  681                            "MBeanRegistrationException", ex);
  682                    mbeans.add(ex);
  683                    continue;
  684                } catch (MBeanException  ex) {
  685                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  686                            "MBeanException", ex);
  687                    mbeans.add(ex);
  688                    continue;
  689                } catch (NotCompliantMBeanException  ex) {
  690                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  691                            "NotCompliantMBeanException", ex);
  692                    mbeans.add(ex);
  693                    continue;
  694                } catch (InstanceNotFoundException   ex) {
  695                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  696                            "InstanceNotFoundException", ex);
  697                    mbeans.add(ex);
  698                    continue;
  699                } catch (IOException ex) {
  700                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  701                            "IOException", ex);
  702                    mbeans.add(ex);
  703                    continue;
  704                } catch (SecurityException ex) {
  705                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  706                            "SecurityException", ex);
  707                    mbeans.add(ex);
  708                    continue;
  709                } catch (Exception ex) {
  710                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  711                            "Exception", ex);
  712                    mbeans.add(ex);
  713                    continue;
  714                } catch (Error ex) {
  715                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
  716                            "Error", ex);
  717                    mbeans.add(ex);
  718                    continue;
  719                }
  720                mbeans.add(objInst);
  721            }
  722            return mbeans;
  723        }
  724   
  725        /**
  726         * Gets the current directory used by the library loader for
  727         * storing native libraries before they are loaded into memory.
  728         *
  729         * @return The current directory used by the library loader.
  730         *
  731         * @see #setLibraryDirectory
  732         *
  733         * @throws UnsupportedOperationException if this implementation
  734         * does not support storing native libraries in this way.
  735         */
  736        public synchronized String getLibraryDirectory() {
  737            return libraryDirectory;
  738        }
  739   
  740        /**
  741         * Sets the directory used by the library loader for storing
  742         * native libraries before they are loaded into memory.
  743         *
  744         * @param libdir The directory used by the library loader.
  745         *
  746         * @see #getLibraryDirectory
  747         *
  748         * @throws UnsupportedOperationException if this implementation
  749         * does not support storing native libraries in this way.
  750         */
  751        public synchronized void setLibraryDirectory(String libdir) {
  752            libraryDirectory = libdir;
  753        }
  754   
  755        /**
  756         * Allows the m-let to perform any operations it needs before
  757         * being registered in the MBean server. If the ObjectName is
  758         * null, the m-let provides a default name for its registration
  759         * &lt;defaultDomain&gt;:type=MLet
  760         *
  761         * @param server The MBean server in which the m-let will be registered.
  762         * @param name The object name of the m-let.
  763         *
  764         * @return  The name of the m-let registered.
  765         *
  766         * @exception java.lang.Exception This exception should be caught by the MBean server and re-thrown
  767         *as an MBeanRegistrationException.
  768         */
  769        public ObjectName preRegister(MBeanServer server, ObjectName name)
  770                throws Exception {
  771   
  772            // Initialize local pointer to the MBean server
  773            setMBeanServer(server);
  774   
  775            // If no name is specified return a default name for the MLet
  776            if (name == null) {
  777                name = new ObjectName(server.getDefaultDomain() + ":" + ServiceName.MLET);
  778            }
  779   
  780           this.mletObjectName = name;
  781           return this.mletObjectName;
  782        }
  783   
  784        /**
  785         * Allows the m-let to perform any operations needed after having been
  786         * registered in the MBean server or after the registration has failed.
  787         *
  788         * @param registrationDone Indicates whether or not the m-let has
  789         * been successfully registered in the MBean server. The value
  790         * false means that either the registration phase has failed.
  791         *
  792         */
  793        public void postRegister (Boolean registrationDone) {
  794        }
  795   
  796        /**
  797         * Allows the m-let to perform any operations it needs before being unregistered
  798         * by the MBean server.
  799         *
  800         * @exception java.langException This exception should be caught
  801         * by the MBean server and re-thrown as an
  802         * MBeanRegistrationException.
  803         */
  804        public void preDeregister() throws java.lang.Exception {
  805        }
  806   
  807   
  808        /**
  809         * Allows the m-let to perform any operations needed after having been
  810         * unregistered in the MBean server.
  811         */
  812        public void postDeregister() {
  813        }
  814   
  815        /**
  816         * <p>Save this MLet's contents to the given {@link ObjectOutput}.
  817         * Not all implementations support this method.  Those that do not
  818         * throw {@link UnsupportedOperationException}.  A subclass may
  819         * override this method to support it or to change the format of
  820         * the written data.</p>
  821         *
  822         * <p>The format of the written data is not specified, but if
  823         * an implementation supports {@link #writeExternal} it must
  824         * also support {@link #readExternal} in such a way that what is
  825         * written by the former can be read by the latter.</p>
  826         *
  827         * @param out The object output stream to write to.
  828         *
  829         * @exception IOException If a problem occurred while writing.
  830         * @exception UnsupportedOperationException If this
  831         * implementation does not support this operation.
  832         */
  833        public void writeExternal(ObjectOutput out)
  834                throws IOException, UnsupportedOperationException {
  835            throw new UnsupportedOperationException("MLet.writeExternal");
  836        }
  837   
  838        /**
  839         * <p>Restore this MLet's contents from the given {@link ObjectInput}.
  840         * Not all implementations support this method.  Those that do not
  841         * throw {@link UnsupportedOperationException}.  A subclass may
  842         * override this method to support it or to change the format of
  843         * the read data.</p>
  844         *
  845         * <p>The format of the read data is not specified, but if an
  846         * implementation supports {@link #readExternal} it must also
  847         * support {@link #writeExternal} in such a way that what is
  848         * written by the latter can be read by the former.</p>
  849         *
  850         * @param in The object input stream to read from.
  851         *
  852         * @exception IOException if a problem occurred while reading.
  853         * @exception ClassNotFoundException if the class for the object
  854         * being restored cannot be found.
  855         * @exception UnsupportedOperationException if this
  856         * implementation does not support this operation.
  857         */
  858        public void readExternal(ObjectInput in)
  859                throws IOException, ClassNotFoundException,
  860                       UnsupportedOperationException {
  861            throw new UnsupportedOperationException("MLet.readExternal");
  862        }
  863   
  864        /*
  865         * ------------------------------------------
  866         *  PACKAGE METHODS
  867         * ------------------------------------------
  868         */
  869   
  870        /**
  871         * <p>Load a class, using the given {@link ClassLoaderRepository} if
  872         * the class is not found in this MLet's URLs.  The given
  873         * ClassLoaderRepository can be null, in which case a {@link
  874         * ClassNotFoundException} occurs immediately if the class is not
  875         * found in this MLet's URLs.</p>
  876         *
  877         * @param name The name of the class we want to load.
  878         * @param clr  The ClassLoaderRepository that will be used to search
  879         *             for the given class, if it is not found in this
  880         *             ClassLoader.  May be null.
  881         * @return The resulting Class object.
  882         * @exception ClassNotFoundException The specified class could not be
  883         *            found in this ClassLoader nor in the given
  884         *            ClassLoaderRepository.
  885         *
  886         */
  887        public synchronized Class<?> loadClass(String name,
  888                                               ClassLoaderRepository clr)
  889                 throws ClassNotFoundException {
  890            final ClassLoaderRepository before=currentClr;
  891            try {
  892                currentClr = clr;
  893                return loadClass(name);
  894            } finally {
  895                currentClr = before;
  896            }
  897        }
  898   
  899        /*
  900         * ------------------------------------------
  901         *  PROTECTED METHODS
  902         * ------------------------------------------
  903         */
  904   
  905        /**
  906         * This is the main method for class loaders that is being redefined.
  907         *
  908         * @param name The name of the class.
  909         *
  910         * @return The resulting Class object.
  911         *
  912         * @exception ClassNotFoundException The specified class could not be
  913         *            found.
  914         */
  915        protected Class<?> findClass(String name) throws ClassNotFoundException {
  916            /* currentClr is context sensitive - used to avoid recursion
  917               in the class loader repository.  (This is no longer
  918               necessary with the new CLR semantics but is kept for
  919               compatibility with code that might have called the
  920               two-parameter loadClass explicitly.)  */
  921            return findClass(name, currentClr);
  922        }
  923   
  924        /**
  925         * Called by {@link MLet#findClass(java.lang.String)}.
  926         *
  927         * @param name The name of the class that we want to load/find.
  928         * @param clr The ClassLoaderRepository that can be used to search
  929         *            for the given class. This parameter is
  930         *            <code>null</code> when called from within the
  931         *            {@link javax.management.MBeanServerFactory#getClassLoaderRepository(javax.management.MBeanServer) Class Loader Repository}.
  932         * @exception ClassNotFoundException The specified class could not be
  933         *            found.
  934         *
  935         **/
  936        Class<?> findClass(String name, ClassLoaderRepository clr)
  937            throws ClassNotFoundException {
  938            Class<?> c = null;
  939            MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), "findClass", name);
  940            // Try looking in the JAR:
  941            try {
  942                c = super.findClass(name);
  943                if (MLET_LOGGER.isLoggable(Level.FINER)) {
  944                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
  945                            "findClass",
  946                            "Class " + name + " loaded through MLet classloader");
  947                }
  948            } catch (ClassNotFoundException e) {
  949                // Drop through
  950                if (MLET_LOGGER.isLoggable(Level.FINEST)) {
  951                    MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  952                            "findClass",
  953                            "Class " + name + " not found locally");
  954                }
  955            }
  956            // if we are not called from the ClassLoaderRepository
  957            if (c == null && delegateToCLR && clr != null) {
  958                // Try the classloader repository:
  959                //
  960                try {
  961                    if (MLET_LOGGER.isLoggable(Level.FINEST)) {
  962                        MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  963                                "findClass",
  964                                "Class " + name + " : looking in CLR");
  965                    }
  966                    c = clr.loadClassBefore(this, name);
  967                    // The loadClassBefore method never returns null.
  968                    // If the class is not found we get an exception.
  969                    if (MLET_LOGGER.isLoggable(Level.FINER)) {
  970                        MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
  971                                "findClass",
  972                                "Class " + name + " loaded through " +
  973                                "the default classloader repository");
  974                    }
  975                } catch (ClassNotFoundException e) {
  976                    // Drop through
  977                    if (MLET_LOGGER.isLoggable(Level.FINEST)) {
  978                        MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  979                                "findClass",
  980                                "Class " + name + " not found in CLR");
  981                    }
  982                }
  983            }
  984            if (c == null) {
  985                MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
  986                        "findClass", "Failed to load class " + name);
  987                throw new ClassNotFoundException(name);
  988            }
  989            return c;
  990        }
  991   
  992        /**
  993         * Returns the absolute path name of a native library. The VM
  994         * invokes this method to locate the native libraries that belong
  995         * to classes loaded with this class loader. Libraries are
  996         * searched in the JAR files using first just the native library
  997         * name and if not found the native library name together with
  998         * the architecture-specific path name
  999         * (<code>OSName/OSArch/OSVersion/lib/nativelibname</code>), i.e.
 1000         * <p>
 1001         * the library stat on Solaris SPARC 5.7 will be searched in the JAR file as:
 1002         * <OL>
 1003         * <LI>libstat.so
 1004         * <LI>SunOS/sparc/5.7/lib/libstat.so
 1005         * </OL>
 1006         * the library stat on Windows NT 4.0 will be searched in the JAR file as:
 1007         * <OL>
 1008         * <LI>stat.dll
 1009         * <LI>WindowsNT/x86/4.0/lib/stat.dll
 1010         * </OL>
 1011         *
 1012         * <p>More specifically, let <em>{@code nativelibname}</em> be the result of
 1013         * {@link System#mapLibraryName(java.lang.String)
 1014         * System.mapLibraryName}{@code (libname)}.  Then the following names are
 1015         * searched in the JAR files, in order:<br>
 1016         * <em>{@code nativelibname}</em><br>
 1017         * {@code <os.name>/<os.arch>/<os.version>/lib/}<em>{@code nativelibname}</em><br>
 1018         * where {@code <X>} means {@code System.getProperty(X)} with any
 1019         * spaces in the result removed, and {@code /} stands for the
 1020         * file separator character ({@link File#separator}).
 1021         * <p>
 1022         * If this method returns <code>null</code>, i.e. the libraries
 1023         * were not found in any of the JAR files loaded with this class
 1024         * loader, the VM searches the library along the path specified
 1025         * as the <code>java.library.path</code> property.
 1026         *
 1027         * @param libname The library name.
 1028         *
 1029         * @return The absolute path of the native library.
 1030         */
 1031        protected String findLibrary(String libname) {
 1032   
 1033            String abs_path;
 1034            String mth = "findLibrary";
 1035   
 1036            // Get the platform-specific string representing a native library.
 1037            //
 1038            String nativelibname = System.mapLibraryName(libname);
 1039   
 1040            //
 1041            // See if the native library is accessible as a resource through the JAR file.
 1042            //
 1043            if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1044                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1045                        "Search " + libname + " in all JAR files");
 1046            }
 1047   
 1048            // First try to locate the library in the JAR file using only
 1049            // the native library name.  e.g. if user requested a load
 1050            // for "foo" on Solaris SPARC 5.7 we try to load "libfoo.so"
 1051            // from the JAR file.
 1052            //
 1053            if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1054                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1055                        "loadLibraryAsResource(" + nativelibname + ")");
 1056            }
 1057            abs_path = loadLibraryAsResource(nativelibname);
 1058            if (abs_path != null) {
 1059                if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1060                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1061                            nativelibname + " loaded, absolute path = " + abs_path);
 1062                }
 1063                return abs_path;
 1064            }
 1065   
 1066            // Next try to locate it using the native library name and
 1067            // the architecture-specific path name.  e.g. if user
 1068            // requested a load for "foo" on Solaris SPARC 5.7 we try to
 1069            // load "SunOS/sparc/5.7/lib/libfoo.so" from the JAR file.
 1070            //
 1071            nativelibname = removeSpace(System.getProperty("os.name")) + File.separator +
 1072                removeSpace(System.getProperty("os.arch")) + File.separator +
 1073                removeSpace(System.getProperty("os.version")) + File.separator +
 1074                "lib" + File.separator + nativelibname;
 1075            if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1076                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1077                        "loadLibraryAsResource(" + nativelibname + ")");
 1078            }
 1079   
 1080            abs_path = loadLibraryAsResource(nativelibname);
 1081            if (abs_path != null) {
 1082                if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1083                    MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1084                            nativelibname + " loaded, absolute path = " + abs_path);
 1085                }
 1086                return abs_path;
 1087            }
 1088   
 1089            //
 1090            // All paths exhausted, library not found in JAR file.
 1091            //
 1092   
 1093            if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1094                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1095                        libname + " not found in any JAR file");
 1096                MLET_LOGGER.logp(Level.FINER, MLet.class.getName(), mth,
 1097                        "Search " + libname + " along the path " +
 1098                        "specified as the java.library.path property");
 1099            }
 1100   
 1101            // Let the VM search the library along the path
 1102            // specified as the java.library.path property.
 1103            //
 1104            return null;
 1105        }
 1106   
 1107   
 1108        /*
 1109         * ------------------------------------------
 1110         *  PRIVATE METHODS
 1111         * ------------------------------------------
 1112         */
 1113   
 1114        private String getTmpDir() {
 1115            // JDK 1.4
 1116            String tmpDir = System.getProperty("java.io.tmpdir");
 1117            if (tmpDir != null) return tmpDir;
 1118   
 1119            // JDK < 1.4
 1120            File tmpFile = null;
 1121            try {
 1122                // Try to guess the system temporary dir...
 1123                tmpFile = File.createTempFile("tmp","jmx");
 1124                if (tmpFile == null) return null;
 1125                final File tmpDirFile = tmpFile.getParentFile();
 1126                if (tmpDirFile == null) return null;
 1127                return tmpDirFile.getAbsolutePath();
 1128            } catch (Exception x) {
 1129                MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1130                        "getTmpDir", "Failed to determine system temporary dir");
 1131                return null;
 1132            } finally {
 1133                // Cleanup ...
 1134                if (tmpFile!=null) {
 1135                    try {
 1136                        boolean deleted = tmpFile.delete();
 1137                        if (!deleted) {
 1138                            MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1139                                    "getTmpDir", "Failed to delete temp file");
 1140                        }
 1141                    } catch (Exception x) {
 1142                        MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1143                                "getTmpDir", "Failed to delete temporary file", x);
 1144                    }
 1145                }
 1146           }
 1147        }
 1148   
 1149        /**
 1150         * Search the specified native library in any of the JAR files
 1151         * loaded by this classloader.  If the library is found copy it
 1152         * into the library directory and return the absolute path.  If
 1153         * the library is not found then return null.
 1154         */
 1155        private synchronized String loadLibraryAsResource(String libname) {
 1156            try {
 1157                InputStream is = getResourceAsStream(libname.replace(File.separatorChar,'/'));
 1158                if (is != null) {
 1159                    File directory = new File(libraryDirectory);
 1160                    directory.mkdirs();
 1161                    File file = File.createTempFile(libname + ".", null, directory);
 1162                    file.deleteOnExit();
 1163                    FileOutputStream fileOutput = new FileOutputStream(file);
 1164                    int c;
 1165                    while ((c = is.read()) != -1) {
 1166                        fileOutput.write(c);
 1167                    }
 1168                    is.close();
 1169                    fileOutput.close();
 1170                    if (file.exists()) {
 1171                        return file.getAbsolutePath();
 1172                    }
 1173                }
 1174            } catch (Exception e) {
 1175                MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1176                        "loadLibraryAsResource",
 1177                        "Failed to load library : " + libname, e);
 1178                return null;
 1179            }
 1180            return null;
 1181        }
 1182   
 1183      /**
 1184       * Removes any white space from a string. This is used to
 1185       * convert strings such as "Windows NT" to "WindowsNT".
 1186       */
 1187        private static String removeSpace(String s) {
 1188            return s.trim().replace(" ", "");
 1189        }
 1190   
 1191        /**
 1192         * <p>This method is to be overridden when extending this service to
 1193         * support caching and versioning.  It is called from {@link
 1194         * #getMBeansFromURL getMBeansFromURL} when the version,
 1195         * codebase, and jarfile have been extracted from the MLet file,
 1196         * and can be used to verify that it is all right to load the
 1197         * given MBean, or to replace the given URL with a different one.</p>
 1198         *
 1199         * <p>The default implementation of this method returns
 1200         * <code>codebase</code> unchanged.</p>
 1201         *
 1202         * @param version The version number of the <CODE>.jar</CODE>
 1203         * file stored locally.
 1204         * @param codebase The base URL of the remote <CODE>.jar</CODE> file.
 1205         * @param jarfile The name of the <CODE>.jar</CODE> file to be loaded.
 1206         * @param mlet The <CODE>MLetContent</CODE> instance that
 1207         * represents the <CODE>MLET</CODE> tag.
 1208         *
 1209         * @return the codebase to use for the loaded MBean.  The returned
 1210         * value should not be null.
 1211         *
 1212         * @exception Exception if the MBean is not to be loaded for some
 1213         * reason.  The exception will be added to the set returned by
 1214         * {@link #getMBeansFromURL getMBeansFromURL}.
 1215         *
 1216         */
 1217        protected URL check(String version, URL codebase, String jarfile,
 1218                            MLetContent mlet)
 1219                throws Exception {
 1220            return codebase;
 1221        }
 1222   
 1223       /**
 1224        * Loads the serialized object specified by the <CODE>OBJECT</CODE>
 1225        * attribute of the <CODE>MLET</CODE> tag.
 1226        *
 1227        * @param codebase The <CODE>codebase</CODE>.
 1228        * @param filename The name of the file containing the serialized object.
 1229        * @return The serialized object.
 1230        * @exception ClassNotFoundException The specified serialized
 1231        * object could not be found.
 1232        * @exception IOException An I/O error occurred while loading
 1233        * serialized object.
 1234        */
 1235        private Object loadSerializedObject(URL codebase, String filename)
 1236                throws IOException, ClassNotFoundException {
 1237           if (filename != null) {
 1238               filename = filename.replace(File.separatorChar,'/');
 1239           }
 1240           if (MLET_LOGGER.isLoggable(Level.FINER)) {
 1241               MLET_LOGGER.logp(Level.FINER, MLet.class.getName(),
 1242                       "loadSerializedObject", codebase.toString() + filename);
 1243           }
 1244           InputStream is = getResourceAsStream(filename);
 1245           if (is != null) {
 1246               try {
 1247                   ObjectInputStream ois = new MLetObjectInputStream(is, this);
 1248                   Object serObject = ois.readObject();
 1249                   ois.close();
 1250                   return serObject;
 1251               } catch (IOException e) {
 1252                   if (MLET_LOGGER.isLoggable(Level.FINEST)) {
 1253                       MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1254                               "loadSerializedObject",
 1255                               "Exception while deserializing " + filename, e);
 1256                   }
 1257                   throw e;
 1258               } catch (ClassNotFoundException e) {
 1259                   if (MLET_LOGGER.isLoggable(Level.FINEST)) {
 1260                       MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1261                               "loadSerializedObject",
 1262                               "Exception while deserializing " + filename, e);
 1263                   }
 1264                   throw e;
 1265               }
 1266           } else {
 1267               if (MLET_LOGGER.isLoggable(Level.FINEST)) {
 1268                   MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1269                           "loadSerializedObject", "Error: File " + filename +
 1270                           " containing serialized object not found");
 1271               }
 1272               throw new Error("File " + filename + " containing serialized object not found");
 1273           }
 1274        }
 1275   
 1276        /**
 1277         * Converts the String value of the constructor's parameter to
 1278         * a basic Java object with the type of the parameter.
 1279         */
 1280        private  Object constructParameter(String param, String type) {
 1281            // check if it is a primitive type
 1282            Class<?> c = primitiveClasses.get(type);
 1283            if (c != null) {
 1284               try {
 1285                   Constructor<?> cons =
 1286                       c.getConstructor(new Class[] {String.class});
 1287                   Object[] oo = new Object[1];
 1288                   oo[0]=param;
 1289                   return(cons.newInstance(oo));
 1290   
 1291               } catch (Exception  e) {
 1292                   MLET_LOGGER.logp(Level.FINEST, MLet.class.getName(),
 1293                           "constructParameter", "Got unexpected exception", e);
 1294               }
 1295           }
 1296           if (type.compareTo("java.lang.Boolean") == 0)
 1297                return Boolean.valueOf(param);
 1298           if (type.compareTo("java.lang.Byte") == 0)
 1299                return new Byte(param);
 1300           if (type.compareTo("java.lang.Short") == 0)
 1301                return new Short(param);
 1302           if (type.compareTo("java.lang.Long") == 0)
 1303                return new Long(param);
 1304           if (type.compareTo("java.lang.Integer") == 0)
 1305                return new Integer(param);
 1306           if (type.compareTo("java.lang.Float") == 0)
 1307                return new Float(param);
 1308           if (type.compareTo("java.lang.Double") == 0)
 1309                return new Double(param);
 1310           if (type.compareTo("java.lang.String") == 0)
 1311                return param;
 1312   
 1313           return param;
 1314        }
 1315   
 1316       private synchronized void setMBeanServer(final MBeanServer server) {
 1317           this.server = server;
 1318           PrivilegedAction<ClassLoaderRepository> act =
 1319               new PrivilegedAction<ClassLoaderRepository>() {
 1320                   public ClassLoaderRepository run() {
 1321                       return server.getClassLoaderRepository();
 1322                   }
 1323               };
 1324           currentClr = AccessController.doPrivileged(act);
 1325       }
 1326   
 1327   }

Save This Page
Home » openjdk-7 » javax » management » loading » [javadoc | source]