org.jboss.system.ServiceCreator Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.system;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.management.MBeanServer;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.StandardMBean;
import org.jboss.logging.Logger;
import org.jboss.mx.server.ServerConstants;
import org.jboss.mx.service.ServiceConstants;
import org.jboss.mx.util.JMXExceptionDecoder;
import org.jboss.mx.util.ObjectNameFactory;
import org.jboss.system.metadata.ServiceConstructorMetaData;
import org.jboss.system.metadata.ServiceMetaData;
import org.jboss.system.metadata.ServiceMetaDataParser;
import org.w3c.dom.Element;
/**
* A helper class for the controller.
*
* @see Service
*
* @author Marc Fleury
* @author David Jencks
* @author Adrian Brock
* @version $Revision: 86477 $
*/
public class ServiceCreator
{
/** Instance logger. */
private static final Logger log = Logger.getLogger(ServiceCreator.class);
/** The MBean Registry Object Name */
private static ObjectName MBEAN_REGISTRY = ObjectNameFactory.create(ServerConstants.MBEAN_REGISTRY);
/** The server */
private MBeanServer server;
/**
* Rethrow an error as an exception
*
* @param context the context
* @param t the original throwable
* @return never
* @throws Exception always
*/
public static Exception rethrow(String context, Throwable t) throws Exception
{
if (t instanceof Error)
throw (Error) t;
else if (t instanceof Exception)
throw (Exception) t;
throw new RuntimeException(context, t);
}
/**
* Install an MBean
*
* @todo expand the meta data to include a pre-instantiated object
* @param server the mbean server
* @param objectName the object name
* @param metaData the service metadata
* @param mbean any mbean instance
* @return the installed instance
* @throws Exception for any error
*/
public static ServiceInstance install(MBeanServer server, ObjectName objectName, ServiceMetaData metaData, Object mbean) throws Exception
{
if (server == null)
throw new IllegalArgumentException("Null MBeanServer");
if (objectName == null)
throw new IllegalArgumentException("Null ObjectName");
if (metaData == null && mbean == null)
throw new IllegalArgumentException("Either metadata or an mbean object must be supplied");
// Check for duplicate
if (server.isRegistered(objectName))
throw new RuntimeException("Trying to install an already registered mbean: " + objectName);
try
{
ServiceInstance result = null;
// No meta data just register directly
if (metaData == null)
{
ObjectInstance instance = server.registerMBean(mbean, objectName);
result = new ServiceInstance(instance, mbean);
}
else
{
String code = metaData.getCode();
if (code == null || code.trim().length() == 0)
throw new ConfigurationException("Missing or empty code for mbean " + objectName);
String xmbeanDD = metaData.getXMBeanDD();
// Not an XMBean
if (xmbeanDD == null)
{
String interfaceName = metaData.getInterfaceName();
if (interfaceName != null)
result = installStandardMBean(server, objectName, metaData);
else
result = installPlainMBean(server, objectName, metaData);
}
// Embedded XMBean Descriptor
else if (xmbeanDD.length() == 0)
result = installEmbeddedXMBean(server, objectName, metaData);
// Reference to external XMBean descriptor
else
result = installExternalXMBean(server, objectName, metaData);
}
log.debug("Created mbean: " + objectName);
return result;
}
catch (Throwable e)
{
Throwable newE = JMXExceptionDecoder.decode(e);
// didn't work, unregister in case the jmx agent is screwed.
try
{
server.unregisterMBean(objectName);
}
catch (Throwable ignore)
{
}
throw rethrow("Unable to createMBean for " + objectName, newE);
}
}
/**
* Install a StandardMBean
*
* @param server the mbean server
* @param objectName the object name
* @param metadata the service metadata
* @return the installed instance
* @throws Exception for any error
*/
private static ServiceInstance installStandardMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
{
ObjectName loaderName = metaData.getClassLoaderName();
ClassLoader loader = server.getClassLoader(loaderName);
String code = metaData.getCode();
ServiceConstructorMetaData constructor = metaData.getConstructor();
String interfaceName = metaData.getInterfaceName();
Class> intf = loader.loadClass(interfaceName);
log.debug("About to create bean resource: " + objectName + " with code: " + code + " and interface " + interfaceName);
Object resource = server.instantiate(code,
loaderName,
constructor.getParameters(loader),
constructor.getSignature());
log.debug("About to register StandardMBean : " + objectName);
ObjectInstance instance = server.createMBean(StandardMBean.class.getName(),
objectName,
loaderName,
new Object[] { resource, intf },
new String[] { Object.class.getName() , Class.class.getName() });
return new ServiceInstance(instance, resource);
}
/**
* Install a plain MBean
*
* @param server the mbean server
* @param objectName the object name
* @param metadata the service metadata
* @return the installed instance
* @throws Exception for any error
*/
private static ServiceInstance installPlainMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
{
ObjectName loaderName = metaData.getClassLoaderName();
ClassLoader loader = server.getClassLoader(loaderName);
String code = metaData.getCode();
ServiceConstructorMetaData constructor = metaData.getConstructor();
// This is a standard or dynamic mbean
log.debug("About to create bean: " + objectName + " with code: " + code);
Object resource = null;
try
{
resource = server.instantiate(code,
loaderName,
constructor.getParameters(loader),
constructor.getSignature());
}
catch (ReflectionException e)
{
// This hack is for backwards compatibility on the error messages
Throwable t = e.getCause();
if (t instanceof ClassNotFoundException)
throw e;
throw new NotCompliantMBeanException("Error in constructor for " + code + " " + e.toString());
}
Map values = new HashMap();
values.put(ServerConstants.CLASSLOADER, loader);
ObjectInstance instance = (ObjectInstance) server.invoke(MBEAN_REGISTRY, "registerMBean", new Object[] { resource, objectName, values }, new String[] { Object.class.getName(), ObjectName.class.getName(), Map.class.getName() });
return new ServiceInstance(instance, resource);
}
/**
* Install an embedded XMBean
*
* @param server the mbean server
* @param objectName the object name
* @param metadata the service metadata
* @return the installed instance
* @throws Exception for any error
*/
private static ServiceInstance installEmbeddedXMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
{
ObjectName loaderName = metaData.getClassLoaderName();
ClassLoader loader = server.getClassLoader(loaderName);
String code = metaData.getCode();
ServiceConstructorMetaData constructor = metaData.getConstructor();
// This is an xmbean with an embedded mbean descriptor
log.debug("About to create xmbean object: " + objectName + " with code: " + code + " with embedded descriptor");
//xmbean: construct object first.
Object resource = server.instantiate(code,
loaderName,
constructor.getParameters(loader),
constructor.getSignature());
String xmbeanCode = metaData.getXMBeanCode();
Element mbeanDescriptor = metaData.getXMBeanDescriptor();
Object[] args = { resource, mbeanDescriptor, ServiceConstants.PUBLIC_JBOSSMX_XMBEAN_DTD_1_0 };
String[] sig = { Object.class.getName(), Element.class.getName(), String.class.getName() };
ObjectInstance instance = server.createMBean(xmbeanCode,
objectName,
loaderName,
args,
sig);
return new ServiceInstance(instance, resource);
}
/**
* Install an external XMBean
*
* @param server the mbean server
* @param objectName the object name
* @param metadata the service metadata
* @return the installed instance
* @throws Exception for any error
*/
private static ServiceInstance installExternalXMBean(MBeanServer server, ObjectName objectName, ServiceMetaData metaData) throws Exception
{
ObjectName loaderName = metaData.getClassLoaderName();
ClassLoader loader = server.getClassLoader(loaderName);
String code = metaData.getCode();
ServiceConstructorMetaData constructor = metaData.getConstructor();
String xmbeanDD = metaData.getXMBeanDD();
// This is an xmbean with an external descriptor
log.debug("About to create xmbean object: " + objectName + " with code: " + code + " with descriptor: " + xmbeanDD);
//xmbean: construct object first.
Object resource = server.instantiate(code,
loaderName,
constructor.getParameters(loader),
constructor.getSignature());
// Try to find the dd first as a resource then as a URL
URL xmbeanddUrl = null;
try
{
xmbeanddUrl = resource.getClass().getClassLoader().getResource(xmbeanDD);
}
catch (Exception e)
{
}
if (xmbeanddUrl == null)
xmbeanddUrl = new URL(xmbeanDD);
String xmbeanCode = metaData.getXMBeanCode();
//now create the mbean
Object[] args = { resource, xmbeanddUrl };
String[] sig = { Object.class.getName(), URL.class.getName() };
ObjectInstance instance = server.createMBean(xmbeanCode,
objectName,
loaderName,
args,
sig);
return new ServiceInstance(instance, resource);
}
/**
* Uninstall an MBean
*
* @param server the mbean server
* @param objectName the object name
*/
public static void uninstall(MBeanServer server, ObjectName objectName)
{
if (server == null)
throw new IllegalArgumentException("Null MBeanServer");
if (objectName == null)
throw new IllegalArgumentException("Null ObjectName");
try
{
log.debug("Removing mbean from server: " + objectName);
server.unregisterMBean(objectName);
}
catch (Throwable t)
{
log.debug("Error unregistering mbean " + objectName, t);
}
}
/**
* Create a new ServiceCreator
*
* @deprecated This is no longer used and will be going away
* @param server the mbean server
*/
public ServiceCreator(final MBeanServer server)
{
if (server == null)
throw new IllegalArgumentException("Null MBeanServer");
this.server = server;
}
/**
* Clean shutdown
*/
public void shutdown()
{
this.server = null;
}
/**
* Parses the given configuration document and creates MBean
* instances in the current MBean server.
*
* @deprecated This is no longer used and will be going away
* @param mbeanName the object name
* @param loaderName the classloader
* @param mbeanElement the config
* @return the created object instance
* @throws Exception for any error
*/
public ObjectInstance install(ObjectName mbeanName, ObjectName loaderName, Element mbeanElement) throws Exception
{
if (mbeanName == null)
throw new IllegalArgumentException("Null mbeanName");
if (mbeanElement == null)
throw new IllegalArgumentException("Null mbean element");
ServiceMetaDataParser parser = new ServiceMetaDataParser(mbeanElement);
List metaDatas = parser.parse();
if (metaDatas.isEmpty())
throw new RuntimeException("No mbeans found in passed configuration for " + mbeanName);
ServiceMetaData metaData = metaDatas.get(0);
metaData.setClassLoaderName(loaderName);
ServiceInstance instance = install(server, mbeanName, metaData, null);
return instance.getObjectInstance();
}
/**
* Remove the installed object
*
* @param name the object name
* @throws Exception for any error
*/
public void remove(ObjectName name) throws Exception
{
if (name == null)
throw new IllegalArgumentException("Null name");
uninstall(server, name);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy