0001: /**
0002: * The XMOJO Project 5
0003: * Copyright © 2003 XMOJO.org. All rights reserved.
0004:
0005: * NO WARRANTY
0006:
0007: * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
0008: * THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
0009: * OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
0010: * PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
0011: * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0012: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
0013: * TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
0014: * LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
0015: * REPAIR OR CORRECTION.
0016:
0017: * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
0018: * ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
0019: * THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
0020: * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
0021: * USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
0022: * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
0023: * PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
0024: * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
0025: * SUCH DAMAGES.
0026: **/package javax.management.loading;
0027:
0028: import java.io.File;
0029: import java.io.FileOutputStream;
0030: import java.io.InputStream;
0031: import java.io.InputStreamReader;
0032: import java.io.BufferedReader;
0033: import java.io.StringReader;
0034: import java.io.IOException;
0035: import java.io.StreamCorruptedException;
0036: import java.util.Hashtable;
0037: import java.util.Set;
0038: import java.util.Vector;
0039: import java.util.HashSet;
0040: import java.util.Arrays;
0041: import java.util.ArrayList;
0042: import java.util.StringTokenizer;
0043: import java.net.URL;
0044: import java.net.URLConnection;
0045: import java.net.URLClassLoader;
0046: import java.net.URLStreamHandlerFactory;
0047: import java.net.MalformedURLException;
0048: import java.text.ParseException;
0049:
0050: import javax.management.ObjectName;
0051: import javax.management.MBeanServer;
0052: import javax.management.MBeanRegistration;
0053: import javax.management.MBeanRegistrationException;
0054: import javax.management.MalformedObjectNameException;
0055: import javax.management.RuntimeOperationsException;
0056: import javax.management.NotCompliantMBeanException;
0057: import javax.management.InstanceAlreadyExistsException;
0058: import javax.management.ServiceNotFoundException;
0059:
0060: import com.adventnet.agent.logging.Log;
0061: import com.adventnet.agent.logging.LogFactory;
0062:
0063: /**
0064: * This MLet service allows to instantiate and register one or several MBeans
0065: * in the MBean server coming from a remote URL. M-let is a shortcut for
0066: * management applet. The m-let service does this by loading an m-let text file,
0067: * which specifies information on the MBeans to be obtained. The information
0068: * on each MBean is specified in a single instance of a tag, called the MLET tag.
0069: * The location of the m-let text file is specified by a URL.
0070: * <p>
0071: * The <CODE>MLET</CODE> tag has the following syntax:
0072: * <p>
0073: * <<CODE>MLET</CODE><BR>
0074: * <CODE>CODE = </CODE><VAR>class</VAR><CODE> | OBJECT = </CODE><VAR>serfile</VAR><BR>
0075: * <CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE><BR>
0076: * <CODE>[CODEBASE = </CODE><VAR>codebaseURL</VAR><CODE>]</CODE><BR>
0077: * <CODE>[NAME = </CODE><VAR>mbeanname</VAR><CODE>]</CODE><BR>
0078: * <CODE>[VERSION = </CODE><VAR>version</VAR><CODE>]</CODE><BR>
0079: * ><BR>
0080: * <CODE>[</CODE><VAR>arglist</VAR><CODE>]</CODE><BR>
0081: * <<CODE>/MLET</CODE>>
0082: * <p>
0083: * where:
0084: * <DL>
0085: * <DT><CODE>CODE = </CODE><VAR>class</VAR></DT>
0086: * <DD>
0087: * This attribute specifies the full Java class name, including package name,
0088: * of the MBean to be obtained. The compiled <CODE>.class</CODE> file of the
0089: * MBean must be contained in one of the <CODE>.jar</CODE> files specified by
0090: * the <CODE>ARCHIVE</CODE> attribute. Either <CODE>CODE</CODE> or
0091: * <CODE>OBJECT</CODE> must be present.
0092: * </DD>
0093: * <DT><CODE>OBJECT = </CODE><VAR>serfile</VAR></DT>
0094: * <DD>
0095: * This attribute specifies the <CODE>.ser</CODE> file that contains a
0096: * serialized representation of the MBean to be obtained. This file must be
0097: * contained in one of the <CODE>.jar</CODE> files specified by the
0098: * <CODE>ARCHIVE</CODE> attribute. If the <CODE>.jar</CODE> file contains a
0099: * directory hierarchy, specify the path of the file within this hierarchy.
0100: * Otherwise a match will not be found. Either <CODE>CODE</CODE> or
0101: * <CODE>OBJECT</CODE> must be present.
0102: * </DD>
0103: * <DT><CODE>ARCHIVE = "</CODE><VAR>archiveList</VAR><CODE>"</CODE></DT>
0104: * <DD>
0105: * This mandatory attribute specifies one or more <CODE>.jar</CODE> files
0106: * containing MBeans or other resources used by the MBean to be obtained.
0107: * One of the <CODE>.jar</CODE> files must contain the file specified by
0108: * the <CODE>CODE</CODE> or <CODE>OBJECT</CODE> attribute.
0109: * If archivelist contains more than one file:
0110: * <UL>
0111: * <LI>Each file must be separated from the one that follows it by a comma (,).
0112: * <LI><VAR>archivelist</VAR> must be enclosed in double quote marks.
0113: * </UL>
0114: * All <CODE>.jar</CODE> files in <VAR>archivelist</VAR> must be stored in
0115: * the directory specified by the code base URL.
0116: * </DD>
0117: * <DT><CODE>CODEBASE = </CODE><VAR>codebaseURL</VAR></DT>
0118: * <DD>
0119: * This optional attribute specifies the code base URL of the MBean to be
0120: * obtained. It identifies the directory that contains the <CODE>.jar</CODE>
0121: * files specified by the <CODE>ARCHIVE</CODE> attribute. Specify this
0122: * attribute only if the <CODE>.jar</CODE> files are not in the same
0123: * directory as the m-let text file. If this attribute is not specified,
0124: * the base URL of the m-let text file is used.
0125: * </DD>
0126: * <DT><CODE>NAME = </CODE><VAR>mbeanname</VAR></DT>
0127: * <DD>
0128: * This optional attribute specifies the object name to be assigned to the
0129: * MBean instance when the m-let service registers it. If <VAR>mbeanname</VAR>
0130: * starts with the colon character (:), the domain part of the object name is
0131: * the domain of the agent. The m-let service invokes the
0132: * <CODE>getDomain()</CODE> method of the Framework class to
0133: * obtain this information.
0134: * </DD>
0135: * <DT><CODE>VERSION = </CODE><VAR>version</VAR></DT>
0136: * <DD>
0137: * This optional attribute specifies the version number of the MBean and
0138: * associated <CODE>.jar</CODE> files to be obtained. This version number can
0139: * be used to specify that the <CODE>.jar</CODE> files are loaded from the
0140: * server to update those stored locally in the cache the next time the m-let
0141: * text file is loaded. <VAR>version</VAR> must be a series of non-negative
0142: * decimal integers each separated by a period from the one that precedes it.
0143: * </DD>
0144: * <DT><VAR>arglist</VAR></DT>
0145: * <DD>
0146: * This optional attribute specifies a list of one or more parameters for the
0147: * MBean to be instantiated. This list describes the parameters to be passed
0148: * the MBean's constructor. Use the following syntax to specify each item in
0149: * <VAR>arglist</VAR>:</DD>
0150: * <DL>
0151: * <P>
0152: * <DT><<CODE>ARG TYPE=</CODE><VAR>argumentType</VAR> <CODE>VALUE=</CODE><VAR>value</VAR>></DT>
0153: * <P>
0154: * <DD>where:</DD>
0155: * <UL>
0156: * <LI><VAR>argumentType</VAR> is the type of the argument that will be passed
0157: * as parameter to the MBean's constructor.</UL>
0158: * </DL>
0159: * <P>The arguments' type in the argument list should be a Java primitive type
0160: * or a Java basic type (<CODE>java.lang.Boolean, java.lang.Byte,
0161: * java.lang.Short, java.lang.Long, java.lang.Integer, java.lang.Float,
0162: * java.lang.Double, java.lang.String</CODE>).
0163: * </DL>
0164: *
0165: * When an m-let text file is loaded, an instance of each MBean specified
0166: * in the file is created and registered.
0167: * <P>
0168: * The m-let Service extends the <CODE>java.net.URLClassLoader</CODE> and can
0169: * be used to load remote classes and jar files in the VM of the agent.
0170: * <p><STRONG>Note - </STRONG> The <CODE>MLet</CODE> class loader uses the
0171: * {@link javax.management.loading.DefaultLoaderRepository DefaultLoaderRepository}
0172: * to load classes that could not be found in the loaded jar files.
0173: */
0174: public class MLet extends URLClassLoader implements MLetMBean,
0175: MBeanRegistration {
0176: /* Vector to store the list of MLets */
0177: protected Vector mletList = null;
0178:
0179: /* Variable to store the reference of the MBeanServer. */
0180: protected MBeanServer server = null;
0181:
0182: /* Variable to store the ObjectName of the MLet*/
0183: private ObjectName objectName = null;
0184:
0185: /* Parser variable used to parse the MLet text file. */
0186: private MLetParser parser = null;
0187:
0188: /* Variable to store the Library Directory used by the MLet */
0189: private String libDir = System.getProperty("user.dir");
0190:
0191: /*Variable to store the versions and the corresponding jarNames*/
0192: private Hashtable versionTable = null;
0193:
0194: /* Logger */
0195: private Log log;
0196:
0197: /* boolean to indicate whether to use default loader */
0198: boolean useDefaultLoader = false;
0199:
0200: /**
0201: * Constructs a new MLet using the default delegation parent ClassLoader.
0202: */
0203: public MLet() {
0204: this (new URL[0]);
0205: createLogger();
0206: }
0207:
0208: /**
0209: * Constructs a new MLet for the specified URLs using the default delegation
0210: * parent ClassLoader. The URLs will be searched in the order specified for
0211: * classes and resources after first searching in the parent class loader.
0212: *
0213: * @param urls the URLs from which to load classes and resources
0214: */
0215: public MLet(URL[] urls) {
0216: super (urls);
0217: versionTable = new Hashtable();
0218: createLogger();
0219: }
0220:
0221: /**
0222: * Constructs a new MLet for the given URLs. The URLs will be searched in
0223: * the order specified for classes and resources after first searching in
0224: * the specified parent class loader. URLStreamHandlerFactory. The parent
0225: * argument will be used as the parent class loader for delegation. The
0226: * factory argument will be used as the stream handler factory to obtain
0227: * protocol handlers when creating new URLs.
0228: *
0229: * @param urls the URLs from which to load classes and resources
0230: *
0231: * @param parent the parent class loader for delegation
0232: */
0233: public MLet(URL[] urls, ClassLoader parent) {
0234: super (urls, parent);
0235: versionTable = new Hashtable();
0236: createLogger();
0237: }
0238:
0239: /**
0240: * Constructs a new MLet for the specified URLs, parent class loader, and
0241: * URLStreamHandlerFactory. The parent argument will be used as the parent
0242: * class loader for delegation. The factory argument will be used as the
0243: * stream handler factory to obtain protocol handlers when creating new
0244: * URLs.
0245: *
0246: * @param urls - the URLs from which to load classes and resources
0247: *
0248: * @param parent - the parent class loader for delegation
0249: *
0250: * @param factory - the URLStreamHandlerFactory to use when creating URLs
0251: */
0252: public MLet(URL[] urls, ClassLoader parent,
0253: URLStreamHandlerFactory factory) {
0254: super (urls, parent, factory);
0255: versionTable = new Hashtable();
0256: createLogger();
0257: }
0258:
0259: /**
0260: * Appends the specified URL to the list of URLs to search for classes and
0261: * resources.
0262: *
0263: * @param url The url from which to load the MBeans in a string format.
0264: *
0265: * @exception javax.management.ServiceNotFoundException - The specified
0266: * URL is malformed.
0267: */
0268: public void addURL(String url) throws ServiceNotFoundException {
0269: try {
0270: URL Url = new URL(url);
0271:
0272: // if this URL object does not exists and then add it
0273: if (Arrays.asList(getURLs()).contains(url) == false)
0274: super .addURL(Url);
0275: } catch (MalformedURLException e) {
0276: log.warn("Check URL", e);
0277: throw new ServiceNotFoundException(e.getMessage());
0278: }
0279: }
0280:
0281: /**
0282: * Appends the specified URL to the list of URLs to search for classes and
0283: * resources.
0284: *
0285: * @param url The url from which to load the MBeans in a string format.
0286: *
0287: * @overrides addURL in class java.net.URLClassLoader
0288: */
0289: public void addURL(URL url) {
0290: // if this URL object does not exists and then add it
0291: if (Arrays.asList(getURLs()).contains(url) == false)
0292: super .addURL(url);
0293: }
0294:
0295: /**
0296: * Gets the current directory used by the library loader for storing
0297: * native libraries before they are loaded into memory.
0298: *
0299: * @return The current directory used by the library loader.
0300: */
0301: public String getLibraryDirectory() {
0302: return libDir;
0303: }
0304:
0305: /**
0306: * Sets the directory used by the library loader for storing
0307: * native libraries before they are loaded into memory.
0308: *
0309: * @param libDir The directory used by the library loader.
0310: */
0311: public void setLibraryDirectory(String libDir) {
0312: this .libDir = libDir;
0313: }
0314:
0315: /**
0316: * Loads a text file containing MLET tags that define the MBeans to be
0317: * added to the agent. The location of the text file is specified by a URL.
0318: * The MBeans specified in the MLET file will be instantiated and
0319: * registered by the MBeanServer.
0320: *
0321: * @param url - The URL of the text file to be loaded as String object.
0322: *
0323: * @return A set containing one entry per MLET tag in the m-let text file
0324: * loaded. Each entry specifies either the ObjectInstance for
0325: * the created MBean, or a throwable object (that is, an error
0326: * or an exception) if the MBean could not be created.
0327: *
0328: * @exception javax.management.ServiceNotFoundException - One of the
0329: * following errors has occurred:
0330: * The m-let text file does not contain an MLET tag,
0331: * the m-let text file is not found,
0332: * a mandatory attribute of the MLET tag is not specified,
0333: * the url is malformed.
0334: *
0335: * @see MLetMBean#getMBeansFromURL(String)
0336: */
0337: public Set getMBeansFromURL(String url)
0338: throws ServiceNotFoundException {
0339: try {
0340: return getMBeansFromURL(new URL(url));
0341: } catch (Exception e) {
0342: e.printStackTrace();
0343: log.error(url, e);
0344: throw new ServiceNotFoundException(e.getMessage());
0345: }
0346: }
0347:
0348: /**
0349: * Loads a text file containing MLET tags that define the MBeans to be
0350: * added to the agent. The location of the text file is specified by a URL.
0351: * The MBeans specified in the MLET file will be instantiated and
0352: * registered by the MBeanServer.
0353: *
0354: * @param url - The URL of the text file to be loaded as URL object.
0355: *
0356: * @return A set containing one entry per MLET tag in the m-let text file
0357: * loaded. Each entry specifies either the ObjectInstance for
0358: * the created MBean, or a throwable object (that is, an
0359: * error or an exception) if the MBean could not be created.
0360: *
0361: * @exception javax.management.ServiceNotFoundException - One of the
0362: * following errors has occurred:
0363: * The m-let text file does not contain an MLET tag,
0364: * the m-let text file is not found,
0365: * a mandatory attribute of the MLET tag is not specified,
0366: * the value of url is null.
0367: *
0368: * @see MLetMBean#getMBeansFromURL(URL)
0369: */
0370: public Set getMBeansFromURL(URL url)
0371: throws ServiceNotFoundException {
0372: boolean isVersioning = false;
0373:
0374: //This hashset will be used to return the set
0375: HashSet mset = new HashSet();
0376:
0377: String protocol = url.getProtocol();
0378: String host = url.getHost();
0379: int port = url.getPort();
0380:
0381: try {
0382: URLConnection con = url.openConnection();
0383: String fix = new String();
0384: String tfix = new String();
0385: InputStreamReader dis = new InputStreamReader(con
0386: .getInputStream());
0387: BufferedReader stream = new BufferedReader(dis);
0388: fix = stream.readLine();
0389:
0390: while (fix != null) {
0391: int strIndex = fix.indexOf("VERSION");
0392:
0393: if (strIndex != -1) {
0394: String temp = fix;
0395: StringTokenizer tokenizer = new StringTokenizer(
0396: temp, "=");
0397:
0398: String firstHalf = tokenizer.nextToken();
0399: String ver = tokenizer.nextToken();
0400: ver = ver.trim();
0401: ver = "\"" + ver + "\"";
0402: String secondHalf = ver;
0403:
0404: fix = firstHalf + " = " + secondHalf;
0405:
0406: }
0407:
0408: tfix = tfix + "\n" + fix;
0409: tfix = tfix.replace('_', '@');
0410:
0411: fix = stream.readLine();
0412: }
0413:
0414: StringReader r = new StringReader(tfix);
0415: parser = new MLetParser(r);
0416: } catch (ParseException pe) {
0417: log.error("Parse Error Exception ", pe);
0418: throw new ServiceNotFoundException(pe.getMessage());
0419: } catch (IOException ie) {
0420: throw new ServiceNotFoundException(ie.getMessage());
0421: } catch (Exception ex) {
0422: log.error("Exception", ex);
0423: throw new ServiceNotFoundException(ex.getMessage());
0424: }
0425:
0426: Vector vec = parser.getMLetVector();
0427:
0428: for (int i = 0; i < vec.size(); i++) {
0429: URL toAdd = null;
0430: SimpleMLet mlet = (SimpleMLet) vec.elementAt(i);
0431:
0432: // The following variables completely describe the MLet Tag.
0433:
0434: String codeBaseURL = mlet.getCodebase();
0435: String code = mlet.getCode();
0436: String serObject = mlet.getObject();
0437: Vector jarVector = mlet.getArchive();
0438: String name = mlet.getName();
0439:
0440: String version = mlet.getVersion();
0441: ArrayList argTypes = mlet.getArgTypes();
0442: ArrayList argValues = mlet.getArgValues();
0443: String className = null;
0444: if (code != null && code.endsWith("class"))
0445: className = code.substring(0, code.length() - 6);
0446:
0447: //Step 1:
0448: //Add all the URLs appended with the jarNames and store the
0449: //version details in the versionTable.
0450: for (int count = 0; count < jarVector.size(); count++) {
0451: String jarName = (String) jarVector.elementAt(count);
0452: String existingVersion = null;
0453: existingVersion = (String) (versionTable.get(jarName));
0454: if (existingVersion == null && version != null) {
0455: versionTable.put(jarName, version);
0456: } else {
0457: if (version != null) {
0458: if (!existingVersion.equals(version)) {
0459: isVersioning = true;
0460: //Version is changed. So need to reload the jar
0461: //files from the Server
0462: }
0463: }
0464: }
0465: //PERF --- < if the jar is already in the URL search path, dont add it all >
0466: try {
0467:
0468: if (codeBaseURL != null) {
0469: String testURL = getProperURLString(
0470: codeBaseURL, protocol, host, port,
0471: jarName);
0472: toAdd = new URL(testURL);
0473:
0474: } else
0475: toAdd = new URL(protocol, host, port, "/"
0476: + jarName);
0477: } catch (Exception e) {
0478: // e.printStackTrace();
0479: log.warn(e.getMessage()
0480: + " hence returning new HashSer");
0481: return new HashSet();
0482: }
0483: if (!isJarPresentInURLClasspath(toAdd)) {
0484: super .addURL(toAdd);
0485: }
0486: }
0487:
0488: //Step 2:
0489: //Check for the Mandatory fields
0490: if (code == null && serObject == null) {
0491: log.error("BOTH CODE and OBJECT cannnot be null");
0492: throw new ServiceNotFoundException(
0493: "Both CODE and OBJECT cannot be null");
0494: }
0495:
0496: if (code != null && serObject != null) {
0497: //Log Error...Both mandatory attributes cannot be present
0498: //for one MLet.
0499: log
0500: .error("Only one of the mandatory fields CODE/OBJECT must be present");
0501: mset
0502: .add(new Error(
0503: "Only one of the mandatory fields CODE/OBJECT must be specified"));
0504: return mset;
0505: }
0506:
0507: //This is the object that will be registered.
0508: Object toReg = null;
0509:
0510: //Step 3:
0511: //Load the class if it is a Serialized file.
0512: if (serObject != null) {
0513: try {
0514: toReg = loadMBeanFromSerializedObject(this ,
0515: serObject);
0516: } catch (Exception e) {
0517: mset.add(e);
0518: e.printStackTrace();
0519: log.warn("loadMBeanFromSerializedObject", e);
0520: //Log the Error Messages from the deSerialization.
0521: }
0522:
0523: try {
0524: if (name != null) {
0525: mset.add(server.registerMBean(toReg,
0526: new ObjectName(name)));
0527: } else {
0528: mset.add(server.registerMBean(toReg, null));
0529: }
0530: } catch (InstanceAlreadyExistsException ie) {
0531: log.warn("", ie);
0532: mset.add(ie);
0533: } catch (MBeanRegistrationException mre) {
0534: log.warn("", mre);
0535: mset.add(mre);
0536: } catch (NotCompliantMBeanException nmbe) {
0537: log.warn("", nmbe);
0538: mset.add(nmbe);
0539: } catch (RuntimeOperationsException roe) {
0540: log.warn("", roe);
0541: mset.add(roe);
0542: } catch (MalformedObjectNameException me) {
0543: log.warn("", me);
0544: mset.add(me);
0545: }
0546: } else {
0547: try {
0548: //This means you have to load the class from the jar files.
0549: Class clazz = null;
0550:
0551: if (isVersioning) {
0552: clazz = super .findLoadedClass(mlet.getCode());
0553: if (clazz == null) {
0554: clazz = findClass(mlet.getCode());
0555: }
0556:
0557: isVersioning = false;
0558: }
0559:
0560: //The above searches the entire URLS and loads the class.
0561:
0562: if (!(argTypes.size() == 0)) {
0563: Object[] types = argTypes.toArray();
0564: Object[] values = argValues.toArray();
0565:
0566: String[] typesArr = new String[types.length];
0567: for (int j = 0; j < types.length; j++) {
0568: typesArr[j] = (String) types[j];
0569: }
0570:
0571: if (name != null) {
0572: mset.add(server.createMBean(mlet.getCode(),
0573: new ObjectName(name), objectName,
0574: values, typesArr));
0575: } else {
0576: mset
0577: .add(server.createMBean(mlet
0578: .getCode(), null,
0579: objectName, values,
0580: typesArr));
0581: }
0582: } else {
0583: if (name != null) {
0584: mset.add(server.createMBean(mlet.getCode(),
0585: new ObjectName(name), objectName));
0586: } else {
0587: mset.add(server.createMBean(mlet.getCode(),
0588: null, objectName));
0589: }
0590: }
0591: } catch (ClassNotFoundException e) {
0592: throw new ServiceNotFoundException(e.getMessage());
0593: } catch (Exception e) {
0594: e.printStackTrace();
0595: throw new ServiceNotFoundException(e.getMessage());
0596: }
0597: }
0598: }
0599:
0600: return mset;
0601: }//End of getMBeanFromURL(URL url)
0602:
0603: /**
0604: * Returns the search path of URLs for loading classes and resources.
0605: * This includes the original list of URLs specified to the constructor,
0606: * along with any URLs subsequently appended by the addURL() method.
0607: *
0608: * @return This returns the search path of URLs for loading classes
0609: * and resources
0610: *
0611: * @overrides getURLs in class java.net.URLClassLoader
0612: *
0613: * @see MLetMBean#getURLs()
0614: */
0615: public URL[] getURLs() {
0616: return super .getURLs();
0617: }
0618:
0619: //MBeanRegistration implementation
0620:
0621: /**
0622: * This method allows the m-let to perform any operations it needs before
0623: * being registered in the MBeanServer. If the ObjectName is null,
0624: * the m-let provides a default name for its registration :service=MLet
0625: *
0626: * @param server - The MBeanServer in which the m-let will be registered.
0627: *
0628: * @param name - The object name of the m-let.
0629: *
0630: * @return The name of the m-let registered.
0631: *
0632: * @exception java.lang.Exception - This exception should be caught by the
0633: * MBeanServer and re-thrown as an MBeanRegistrationException.
0634: *
0635: * @see MBeanRegistration#preRegister(MBeanServer, ObjectName)
0636: */
0637: public ObjectName preRegister(MBeanServer server, ObjectName name)
0638: throws Exception {
0639: this .server = server;
0640:
0641: if (name == null) {
0642: objectName = new ObjectName(":type=MLet");
0643: return objectName;
0644: }
0645:
0646: objectName = name;
0647: return objectName;
0648: }
0649:
0650: /**
0651: * Allows the m-let to perform any operations needed after having been
0652: * registered in the MBeanServer or after the registration has failed.
0653: *
0654: * @param registrationDone - Indicates whether or not the m-let has been
0655: * successfully registered in the MBeanServer. The value
0656: * false means that either the registration phase has failed.
0657: *
0658: * @see MBeanRegistration#postRegister(Boolean)
0659: */
0660: public void postRegister(Boolean registrationDone) {
0661: }
0662:
0663: /**
0664: * Allows the m-let to perform any operations it needs before being
0665: * de-registered by the MBeanServer.
0666: *
0667: * @exception java.langException - This exception should be caught by the
0668: * MBeanServer and re-thrown as an MBeanRegistrationException.
0669: *
0670: * @see MBeanRegistration#preDeregister()
0671: */
0672: public void preDeregister() throws Exception {
0673: }
0674:
0675: /**
0676: * Allows the m-let to perform any operations needed after having been
0677: * de-registered in the MBeanServer.
0678: *
0679: * @see MBeanRegistration#postDeregister()
0680: */
0681: public void postDeregister() {
0682: }
0683:
0684: /**
0685: * This method reads the objects contents during Object Serialization.
0686: *
0687: * @param in The serialization input stream.
0688: *
0689: * @exception java.io.IOException Signals that an I/O exception of some
0690: * sort has occurred.
0691: *
0692: * @exception java.lang.ClassNotFoundException The class for an object
0693: * being restored cannot be found.
0694: */
0695: public void readExternal(java.io.ObjectInput in)
0696: throws java.io.IOException,
0697: java.lang.ClassNotFoundException {
0698: }
0699:
0700: /**
0701: * This method saves the objects contents during Object Serialization.
0702: * @param out The serialization output stream.
0703: *
0704: * @exception java.io.IOException Signals that an I/O exception of some
0705: * sort has occurred.
0706: */
0707: public void writeExternal(java.io.ObjectOutput out)
0708: throws java.io.IOException {
0709: }
0710:
0711: //-------------------------- Protected methods --------------------------//
0712:
0713: /**
0714: * This is the main method for class loaders that is being redefined.
0715: *
0716: * @param name The name of the class.
0717: *
0718: * @return The resulting Class object.
0719: *
0720: * @exception java.lang.ClassNotFoundException The specified class
0721: * could not be found.
0722: */
0723: protected synchronized java.lang.Class findClass(
0724: java.lang.String name)
0725: throws java.lang.ClassNotFoundException {
0726: Class clazz = null;
0727: try {
0728: clazz = super .findClass(name);
0729: } catch (ClassNotFoundException cnfe) {
0730: //log Warning
0731: log
0732: .warn("Class not available in the URLClassLoader path...Loading from the DefaultLoaderRepository");
0733: }
0734:
0735: if (clazz == null && !useDefaultLoader) {
0736: try {
0737: clazz = DefaultLoaderRepository.loadClass(name);
0738: } catch (ClassNotFoundException cnfe) {
0739: log.warn(name, cnfe);
0740: throw cnfe;
0741: }
0742: }
0743:
0744: if (clazz == null)
0745: throw new ClassNotFoundException(name);
0746:
0747: return clazz;
0748: }
0749:
0750: /**
0751: * Returns the absolute path name of a native library. The VM invokes
0752: * this method to locate the native libraries that belong to classes
0753: * loaded with this class loader. Libraries are searched in the JAR files
0754: * using first just the native library name and if not found the native
0755: * library name together with the architecture-specific path name
0756: * (OSName/OSArch/OSVersion/lib/nativelibname), i.e.
0757: * <p>the library stat on Solaris SPARC 5.7 will be searched in the JAR
0758: * file as:
0759: * <ol>
0760: * <li>libstat.so
0761: * <li>SunOS/sparc/5.7/lib/libstat.so
0762: * </ol>
0763: * the library stat on Windows NT 4.0 will be searched in the JAR file as:
0764: * <ol>
0765: * <li>stat.dll
0766: * <li>WindowsNT/x86/4.0/lib/stat.dll
0767: * </ol>
0768: * If this method returns null, i.e. the libraries were not found in any of
0769: * the JAR files loaded with this class loader, the VM searches the library
0770: * along the path specified as the java.library.path property.
0771: * @overrides findLibrary in class java.lang.ClassLoader
0772: * @param libname the library name.
0773: * @return The absolute path of the native library.
0774: */
0775: protected String findLibrary(String libname) {
0776: if (libname == null) {
0777: log.debug(" input is a null value..so returning null");
0778: return null;
0779: }
0780: libname = System.mapLibraryName(libname);
0781:
0782: InputStream is = null;
0783: File file = null;
0784: FileOutputStream os = null;
0785:
0786: try {
0787: libname = libname.replace(File.separatorChar, '/');
0788: is = getResourceAsStream(libname);
0789: if (is != null) {
0790: file = new File(libDir, libname);
0791:
0792: if (file.exists())
0793: file.delete();
0794:
0795: file.getParentFile().mkdirs();
0796: os = new FileOutputStream(file);
0797:
0798: int value = 0;
0799: while ((value = is.read()) != -1) {
0800: os.write(value);
0801: }
0802: is.close();
0803: os.close();
0804: }
0805:
0806: if (file != null && file.exists())
0807: return file.getAbsolutePath();
0808:
0809: } catch (Exception e) {
0810: log.error("", e);
0811: }
0812:
0813: String os_name = deleteSpace(System.getProperty("os.name")
0814: .trim());
0815: String os_version = deleteSpace(System
0816: .getProperty("os.version").trim());
0817: String os_arch = deleteSpace(System.getProperty("os.arch")
0818: .trim());
0819:
0820: String fs = File.separator;
0821: libname = os_name + fs + os_arch + fs + os_version + fs + "lib"
0822: + fs + libname;
0823:
0824: try {
0825: libname = libname.replace(File.separatorChar, '/');
0826: is = getResourceAsStream(libname);
0827: if (is != null) {
0828: file = new File(libDir, libname);
0829:
0830: if (file.exists())
0831: file.delete();
0832:
0833: file.getParentFile().mkdirs();
0834: os = new FileOutputStream(file);
0835: int value = 0;
0836: while ((value = is.read()) != -1) {
0837: os.write(value);
0838: }
0839: is.close();
0840: os.close();
0841: }
0842:
0843: if (file != null && file.exists())
0844: return file.getAbsolutePath();
0845:
0846: } catch (Exception e) {
0847: log.error("", e);
0848: }
0849: return null;
0850: }
0851:
0852: //--------------------------- Package methods ---------------------------//
0853:
0854: void setUseDefaultLoader(boolean flag) {
0855: useDefaultLoader = flag;
0856: }
0857:
0858: synchronized Class findClassInMLet(String name)
0859: throws ClassNotFoundException {
0860: Class clazz = super .findClass(name);
0861:
0862: if (clazz == null)
0863: throw new ClassNotFoundException(name);
0864:
0865: return clazz;
0866: }
0867:
0868: //--------------------------- Private methods ---------------------------//
0869:
0870: /**
0871: * This method loads the MBeans from the serialized file specified.
0872: * It uses the URLClassLoader's getResourceAsStream() to read the
0873: * specified serialized file and returns the Object.
0874: *
0875: * @param mlet - the MLet instance that defines this method.
0876: *
0877: * @param serObjectFileName - the serialized file name . It includes the
0878: * durectory structure if one is present.
0879: *
0880: * @return the MBean object.
0881: *
0882: * @exception IOException
0883: *
0884: * @exception StreamCorruptedException
0885: *
0886: * @exception Exception
0887: */
0888: private Object loadMBeanFromSerializedObject(MLet mlet,
0889: String serObjectFileName) throws IOException,
0890: StreamCorruptedException, Exception {
0891: Object toRet = null;
0892: InputStream inStr = getResourceAsStream(serObjectFileName);
0893:
0894: if (inStr == null) {
0895: log.error("Serialized file" + serObjectFileName
0896: + "not found");
0897: throw new Error("Serialized file " + serObjectFileName
0898: + " not found");
0899: } else {
0900: try {
0901: MLetObjectInputStream oStr = new MLetObjectInputStream(
0902: inStr, this );
0903: toRet = oStr.readObject();
0904: oStr.close();
0905: } catch (StreamCorruptedException sce) {
0906: log
0907: .error("Error while loading MBean from serialized object"
0908: + sce);
0909: throw sce;
0910: } catch (IOException ioe) {
0911: log
0912: .error("Error while loading MBean from serialized object"
0913: + ioe);
0914: throw ioe;
0915: } catch (Exception e) {
0916: log
0917: .error("Error while loading MBean from serialized object"
0918: + e);
0919: throw e;
0920: }
0921: }
0922: return toRet;
0923: }
0924:
0925: private String deleteSpace(String inStr) {
0926: char[] cha = inStr.toCharArray();
0927: int count = 0;
0928:
0929: for (int i = 0; i < cha.length; i++) {
0930: if (cha[i] != ' ')
0931: count++;
0932: }
0933:
0934: char[] new_cha = new char[count];
0935: count = 0;
0936:
0937: for (int i = 0; i < cha.length; i++) {
0938: if (cha[i] != ' ')
0939: new_cha[count++] = cha[i];
0940: }
0941:
0942: return new String(new_cha);
0943: }
0944:
0945: private Class getProperClass(String type) {
0946: if (type.endsWith("int[]"))
0947: return (new int[0]).getClass();
0948: else if (type.endsWith("long[]"))
0949: return (new long[0]).getClass();
0950: else if (type.endsWith("byte[]"))
0951: return (new byte[0]).getClass();
0952: else if (type.endsWith("float[]"))
0953: return (new float[0]).getClass();
0954: else if (type.endsWith("char[]"))
0955: return (new char[0]).getClass();
0956: else if (type.endsWith("short[]"))
0957: return (new short[0]).getClass();
0958: else if (type.endsWith("double[]"))
0959: return (new double[0]).getClass();
0960: else if (type.endsWith("boolean[]"))
0961: return (new boolean[0]).getClass();
0962: else if (type.endsWith("String[]"))
0963: return (new String[0]).getClass();
0964:
0965: if (type.endsWith("int"))
0966: return int.class;
0967: else if (type.endsWith("long"))
0968: return long.class;
0969: else if (type.endsWith("byte"))
0970: return byte.class;
0971: else if (type.endsWith("float"))
0972: return float.class;
0973: else if (type.endsWith("char"))
0974: return char.class;
0975: else if (type.endsWith("short"))
0976: return short.class;
0977: else if (type.endsWith("double"))
0978: return double.class;
0979: else if (type.endsWith("boolean"))
0980: return boolean.class;
0981:
0982: return null;
0983: }
0984:
0985: private boolean isJarPresentInURLClasspath(URL toAdd) {
0986: URL[] urls = super .getURLs();
0987:
0988: for (int i = 0; i < urls.length; i++) {
0989: if (urls[i].equals(toAdd)) {
0990: //the jar is already present in the searchpath.
0991: return true;
0992: }
0993: }
0994:
0995: return false;
0996: }
0997:
0998: private String getProperURLString(String codeBase, String protocol,
0999: String host, int port, String jarName)
1000: throws MalformedURLException {
1001: String toRet = null;
1002:
1003: if (codeBase.indexOf(":") == -1) {
1004: //This is an relative path
1005: if (codeBase.startsWith("/") && codeBase.endsWith("/")) {
1006: //Construct the URL
1007: toRet = protocol + "://" + host + ":" + port + codeBase
1008: + jarName;
1009: } else {
1010: toRet = protocol + "://" + host + ":" + port + "/"
1011: + codeBase + "/" + jarName;
1012: }
1013:
1014: return toRet;
1015: } else if (codeBase.indexOf(".jar") == -1) {
1016: toRet = codeBase + "/" + jarName;
1017: new URL(toRet);
1018: return toRet;
1019: } else {
1020: new URL(codeBase);
1021: return codeBase;
1022: }
1023: }
1024:
1025: private void createLogger() {
1026: try {
1027: log = LogFactory.getInstance("JMX");
1028: } catch (Exception e) {
1029: }
1030: }
1031: }//End of class MLet
|