User: starksm
Date: 01/04/13 12:06:59
Modified: src/main/org/jboss/configuration ConfigurationService.java
Log:
Change the ServiceControl to be a passive service with which services
requiring lifecycle events must register.
Change ConfigurationService to register all mbean found in the jboss.jcml
file with the ServiceControl service and make jboss-auto.jcml write only.
Revision Changes Path
1.21 +185 -36 jboss/src/main/org/jboss/configuration/ConfigurationService.java
Index: ConfigurationService.java
===================================================================
RCS file:
/cvsroot/jboss/jboss/src/main/org/jboss/configuration/ConfigurationService.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- ConfigurationService.java 2001/03/15 03:23:44 1.20
+++ ConfigurationService.java 2001/04/13 19:06:59 1.21
@@ -9,9 +9,12 @@
import java.io.*;
import java.beans.*;
+import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import java.net.URL;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
@@ -23,15 +26,22 @@
import org.jboss.logging.Log;
+import org.jboss.util.Service;
+import org.jboss.util.ServiceFactory;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.util.XmlHelper;
-/**
- * <description>
+/** The ConfigurationService MBean is loaded when JBoss starts up by the
+JMX MLet. The ConfigurationService in turn loads the jboss.jcml configuration
+when loadConfiguration() is invoked. This instantiates JBoss specific mbean
+services that wish to be controlled by the JBoss ServiceControl/Service
+lifecycle service.
*
- * @see <related>
+ * @see org.jboss.util.Service
+ * @see org.jboss.util.ServiceControl
* @author Rickard Öberg ([EMAIL PROTECTED])
- * @version $Revision: 1.20 $
+ * @author [EMAIL PROTECTED]
+ * @version $Revision: 1.21 $
*/
public class ConfigurationService
extends ServiceMBeanSupport
@@ -53,6 +63,7 @@
Log log = Log.createLog(getName());
MBeanServer server;
+ ObjectName serviceControl;
// Static --------------------------------------------------------
@@ -74,8 +85,13 @@
public void load(Document configuration)
throws Exception
{
+ // Get the ServiceControl MBean
+ serviceControl = new ObjectName(server.getDefaultDomain(), "service",
"ServiceControl");
+ if( server.isRegistered(serviceControl) == false )
+ throw new IllegalStateException("Failed to find ServiceControl mbean,
name="+serviceControl);
+
try
- {
+ {
// Set configuration to MBeans from XML
NodeList nl = configuration.getElementsByTagName("mbean");
for (int i = 0; i < nl.getLength(); i++)
@@ -137,6 +153,9 @@
}
}
+
+ // Register the mbean with the JBoss ServiceControl mbean
+ registerService(objectName, info, mbeanElement);
}
} catch (Throwable e)
{
@@ -240,10 +259,9 @@
public void loadConfiguration()
throws Exception
{
- // This is a 3-step process
+ // This is a 2-step process
// 1) Load user conf. and create MBeans from that
- // 2) Load auto-saved conf and apply to created MBeans
- // 3) Apply user conf to created MBeans, overwriting any auto-saved conf.
+ // 2) Apply user conf to created MBeans
// Load user config from XML, and create the MBeans
InputStream conf =
Thread.currentThread().getContextClassLoader().getResourceAsStream("jboss.jcml");
@@ -261,7 +279,6 @@
try
{
userConf = parser.parse(new InputSource(new StringReader(cfg)));
- //userConf = xdb.getDocument();
}
catch (SAXException se)
{
@@ -270,31 +287,6 @@
create(userConf);
- // Load auto-saved configuration from XML, and apply it
- conf =
Thread.currentThread().getContextClassLoader().getResourceAsStream("jboss-auto.jcml");
- if (conf != null) // The auto file is optional
- {
- arr = new byte[conf.available()];
- conf.read(arr);
- conf.close();
- cfg = new String(arr);
-
- // Parse XML
- Document autoConf;
-
- try
- {
- autoConf = parser.parse(new InputSource(new StringReader(cfg)));
- //autoConf = xdb.getDocument();
- }
- catch (SAXException se)
- {
- throw new IOException(se.getMessage());
- }
- create(autoConf);
- load(autoConf);
- }
-
// Apply user conf
conf =
Thread.currentThread().getContextClassLoader().getResourceAsStream("jboss.jcml");
arr = new byte[conf.available()];
@@ -337,7 +329,8 @@
try
{
// Create MBean
- ObjectInstance instance = server.createMBean(code,
objectName, new ObjectName(server.getDefaultDomain(), "service", "MLet"));
+ ObjectInstance instance = server.createMBean(code,
objectName,
+ new ObjectName(server.getDefaultDomain(), "service",
"MLet"));
info = server.getMBeanInfo(instance.getObjectName());
} catch (Throwable ex)
{
@@ -409,6 +402,162 @@
} catch(NoSuchMethodException e) {}
return false;
}
-}
+ /** Register the mbean given by objectName with the ServiceControl service.
+ */
+ void registerService(ObjectName objectName, MBeanInfo info, Element
mbeanElement)
+ throws ClassNotFoundException, InstantiationException,
IllegalAccessException
+ {
+ // Check for a serviceFactory attribute
+ String serviceFactory = mbeanElement.getAttribute("serviceFactory");
+ Service service = getServiceInstance(objectName, info, serviceFactory);
+ if( service != null )
+ {
+ Object[] args = {service};
+ String[] signature = {"org.jboss.util.Service"};
+ try
+ {
+ server.invoke(serviceControl, "register", args, signature);
+ }
+ catch(Exception e)
+ {
+ logException(e);
+ }
+ }
+ }
+
+ /** Get the Service interface through which the mbean given by objectName will
+ be managed.
+ */
+ Service getServiceInstance(ObjectName objectName, MBeanInfo info, String
serviceFactory)
+ throws ClassNotFoundException, InstantiationException,
IllegalAccessException
+ {
+ Service service = null;
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ if( serviceFactory != null && serviceFactory.length() > 0 )
+ {
+ Class clazz = loader.loadClass(serviceFactory);
+ ServiceFactory factory = (ServiceFactory) clazz.newInstance();
+ service = factory.createService(server, objectName);
+ }
+ else
+ {
+ MBeanOperationInfo[] opInfo = info.getOperations();
+ Class[] interfaces = { org.jboss.util.Service.class };
+ InvocationHandler handler = new ServiceProxy(objectName, opInfo);
+ service = (Service) Proxy.newProxyInstance(loader, interfaces, handler);
+ }
+ return service;
+ }
+ /** A mapping from the Service interface method names to the
+ corresponding index into the ServiceProxy.hasOp array.
+ */
+ static HashMap serviceOpMap = new HashMap();
+ static
+ {
+ serviceOpMap.put("init", new Integer(0));
+ serviceOpMap.put("start", new Integer(1));
+ serviceOpMap.put("destroy", new Integer(2));
+ serviceOpMap.put("stop", new Integer(3));
+ }
+ /** An implementation of InvocationHandler used to proxy of the Service
+ interface for mbeans. It determines which of the init/start/stop/destroy
+ methods of the Service interface an mbean implements by inspecting its
+ MBeanOperationInfo values. Each Service interface method that has a
+ matching operation is forwarded to the mbean by invoking the method
+ through the MBeanServer object.
+ */
+ class ServiceProxy implements InvocationHandler
+ {
+
+ private boolean[] hasOp = {false, false, false, false};
+ private ObjectName objectName;
+
+ /** Go through the opInfo array and for each operation that
+ matches on of the Service interface methods set the corresponding
+ hasOp array value to true.
+ */
+ ServiceProxy(ObjectName objectName, MBeanOperationInfo[] opInfo)
+ {
+ this.objectName = objectName;
+ for(int op = 0; op < opInfo.length; op ++)
+ {
+ MBeanOperationInfo info = opInfo[op];
+ String name = info.getName();
+ Integer opID = (Integer) serviceOpMap.get(name);
+ if( opID == null )
+ continue;
+
+ // Validate that is a no-arg void return type method
+ if( info.getReturnType().equals("void") == false )
+ continue;
+ if( info.getSignature().length != 0 )
+ continue;
+ hasOp[opID.intValue()] = true;
+ }
+ }
+
+ /** Map the method name to a Service interface method index and
+ if the corresponding hasOp array element is true, dispatch the
+ method to the mbean we are proxying.
+ @return null always.
+ */
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable
+ {
+ String name = method.getName();
+ Integer opID = (Integer) serviceOpMap.get(name);
+ if( opID != null && hasOp[opID.intValue()] == true )
+ {
+ try
+ {
+ String[] sig = {};
+ server.invoke(objectName, name, args, sig);
+ }
+ catch(JMRuntimeException e)
+ {
+ logException(e);
+ }
+ catch(JMException e)
+ {
+ logException(e);
+ }
+ }
+ return null;
+ }
+ }
+
+ /** Go through the myriad of nested JMX exception to pull out the
+ true exception if possible and log it.
+ */
+ void logException(Exception e)
+ {
+ if( e instanceof RuntimeErrorException )
+ {
+ Throwable t = ((RuntimeErrorException)e).getTargetError();
+ log.exception(t);
+ }
+ else if( e instanceof RuntimeMBeanException)
+ {
+ Throwable t = ((RuntimeMBeanException)e).getTargetException();
+ log.exception(t);
+ }
+ else if( e instanceof RuntimeOperationsException)
+ {
+ Throwable t = ((RuntimeOperationsException)e).getTargetException();
+ log.exception(t);
+ }
+ else if( e instanceof MBeanException)
+ {
+ Throwable t = ((MBeanException)e).getTargetException();
+ log.exception(t);
+ }
+ else if( e instanceof ReflectionException)
+ {
+ Throwable t = ((ReflectionException)e).getTargetException();
+ log.exception(t);
+ }
+ else
+ log.exception(e);
+ }
+}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development