/* * JBoss, the OpenSource J2EE webOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package javax.management.loading; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.ServiceNotFoundException; import java.net.URL; import java.net.URLStreamHandlerFactory; import java.net.URLClassLoader; import java.net.MalformedURLException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import java.util.StringTokenizer; import java.util.List; import java.text.ParseException; import org.jboss.logging.Logger; import org.jboss.mx.loading.MBeanFileParser; import org.jboss.mx.loading.MLetParser; import org.jboss.mx.loading.MBeanElement; import org.jboss.mx.loading.LoaderRepository; import org.jboss.mx.loading.UnifiedClassLoader; import org.jboss.mx.server.ServerConstants; import org.jboss.mx.util.MBeanInstaller; /** * URL classloader capable of parsing an MLet text file adhering to the file * format defined in the JMX specification (v1.0). * * @see javax.management.loading.MLetMBean * * @author Juha Lindfors. * @version $Revision: 1.10.4.4 $ * *

Revisions: * *

20020313 Juha Lindfors: *

* *

20020317 Juha Lindfors: *

* *

20020501 Fusayuki Minamoto: *

*/ public class MLet extends URLClassLoader implements MLetMBean, MBeanRegistration { // FIXME: (RI javadoc) Note - The MLet class loader uses the DefaultLoaderRepository // to load classes that could not be found in the loaded jar files. // // IOW we need to override findClass for this cl... // I think we can avoid the ugly dlr field hack from RI // Attributes ---------------------------------------------------- /** Reference to the MBean server this loader is registered to. */ private MBeanServer server = null; /** Object name of this loader. */ private ObjectName objectName = null; /** MBean installer based on MLet version. */ private MBeanInstaller installer = null; /** * A delegate classloader in the loader repository * used when we've been added to the unified loader repository */ private UnifiedClassLoader ucl = null; // Static -------------------------------------------------------- private static final Logger log = Logger.getLogger(MLet.class); /** * Is the classloader repository some form of JBoss unified loader repository */ private static final boolean isUnifiedRepository; // Determine whether we are doing Unified Repository Support static { if (System.getProperty(ServerConstants.LOADER_REPOSITORY_CLASS_PROPERTY).equals( ServerConstants.UNIFIED_LOADER_REPOSITORY_CLASS)) isUnifiedRepository = true; else isUnifiedRepository = false; } // Constructors -------------------------------------------------- public MLet() { super(new URL[0], Thread.currentThread().getContextClassLoader()); } public MLet(URL[] urls) { super(urls, Thread.currentThread().getContextClassLoader()); } public MLet(URL[] urls, ClassLoader parent) { super(urls, parent); } public MLet(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { super(urls, parent, factory); } // MBeanRegistration implementation ------------------------------ public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception { if (name == null) name = new ObjectName(":type=MLet"); this.objectName = name; this.server = server; this.installer = new MBeanInstaller(server, this, name); return name; } public void postRegister(Boolean registrationDone) { if (registrationDone.booleanValue() == false) tidyUp(); else { // FIXME: 3.2 does not follow the spec, the MLET is not added to the loader // repository by the registry, do it here. LoaderRepository ulr = LoaderRepository.getDefaultLoaderRepository(); if (isUnifiedRepository) { try { URL[] urls = super.getURLs(); if (urls.length != 0) { ucl = ulr.newClassLoader(urls[0], true); for (int i = 1; i < urls.length; ++i) ulr.addClassLoaderURL(ucl, urls[i]); } } catch (Exception e) { log.warn("Failed to create classloader for MLet", e); } } else ulr.addClassLoader(this); } } public void preDeregister() throws Exception { // FIXME: 3.2 does not follow the spec, the MLET is not removed from the loader // repository by the registry, do it here. LoaderRepository ulr = LoaderRepository.getDefaultLoaderRepository(); if (isUnifiedRepository) { ulr.removeClassLoader(ucl); ucl = null; } else { ulr.removeClassLoader(this); } } public void postDeregister() { tidyUp(); } // MLetMBean implementation -------------------------------------- public Set getMBeansFromURL(String url) throws ServiceNotFoundException { try { return getMBeansFromURL(new URL(url)); } catch (MalformedURLException e) { throw new ServiceNotFoundException("Malformed URL:" + url); } } public Set getMBeansFromURL(URL url) throws ServiceNotFoundException { if (server == null) throw new ServiceNotFoundException("Loader must be registered to the server before loading the MBeans."); HashSet mbeans = new HashSet(); MBeanElement element = null; try { MBeanFileParser parser = new MLetParser(); Set mlets = parser.parseMBeanFile(url); if (mlets.size() == 0) throw new ServiceNotFoundException("The specified URL '" + url + "' does not contain MLET tags."); Iterator it = mlets.iterator(); while (it.hasNext()) { element = (MBeanElement)it.next(); String codebase = element.getCodebase(); // if no codebase is specified then the url of the mlet text file is used if (codebase == null) codebase = url.toString().substring(0, url.toString().lastIndexOf('/')); String codebaseURL = null; List archives = element.getArchives(); for (int i = 0; i