User: starksm Date: 01/08/13 20:31:34 Modified: src/main/org/jboss/ejb ContainerFactory.java Container.java Added: src/main/org/jboss/ejb ContainerRelection.java ContainerRelectionMBean.java Log: Add a prototype DynamicMBean interface implementation to Container to expose the EJB interface classes and invocation entry points. Revision Changes Path 1.90 +16 -9 jboss/src/main/org/jboss/ejb/ContainerFactory.java Index: ContainerFactory.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/ContainerFactory.java,v retrieving revision 1.89 retrieving revision 1.90 diff -u -r1.89 -r1.90 --- ContainerFactory.java 2001/08/10 16:51:19 1.89 +++ ContainerFactory.java 2001/08/14 03:31:34 1.90 @@ -68,7 +68,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Peter Antman</a>. * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a> * @author <a href="mailto:[EMAIL PROTECTED]">Sacha Labourey</a> -* @version $Revision: 1.89 $ +* @version $Revision: 1.90 $ */ public class ContainerFactory extends ServiceMBeanSupport @@ -579,26 +579,29 @@ ClassLoader localCl ) throws Exception { + Container container = null; // Added message driven deployment if( bean.isMessageDriven() ) { - return createMessageDrivenContainer( bean, cl, localCl ); + container = createMessageDrivenContainer( bean, cl, localCl ); } else if( bean.isSession() ) // Is session? { if( ( (SessionMetaData) bean ).isStateless() ) // Is stateless? { - return createStatelessSessionContainer( bean, cl, localCl ); + container = createStatelessSessionContainer( bean, cl, localCl ); } else // Stateful { - return createStatefulSessionContainer( bean, cl, localCl ); + container = createStatefulSessionContainer( bean, cl, localCl ); } } else // Entity { - return createEntityContainer( bean, cl, localCl ); + container = createEntityContainer( bean, cl, localCl ); } + container.setMBeanServer(this.getServer()); + return container; } private MessageDrivenContainer createMessageDrivenContainer( BeanMetaData bean, @@ -713,11 +716,14 @@ * Either creates the Management MBean wrapper for a container and start * it or it destroy it. **/ - private void handleContainerManagement( Container container, boolean doStart ) { - try { + private void handleContainerManagement( Container container, boolean doStart ) + { + try + { // Create and register the ContainerMBean ObjectName name = new ObjectName( "Management", "jndiName", container.getBeanMetaData().getJndiName() ); - if( doStart ) { + if( doStart ) + { getServer().createMBean( "org.jboss.management.ContainerManagement", name, @@ -727,7 +733,8 @@ getServer().invoke( name, "init", new Object[] {}, new String[] {} ); getServer().invoke( name, "start", new Object[] {}, new String[] {} ); } - else { + else + { // If not startup then assume that the MBean is there getServer().invoke( name, "stop", new Object[] {}, new String[] {} ); getServer().invoke( name, "destroy", new Object[] {}, new String[] {} ); 1.54 +182 -9 jboss/src/main/org/jboss/ejb/Container.java Index: Container.java =================================================================== RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/Container.java,v retrieving revision 1.53 retrieving revision 1.54 diff -u -r1.53 -r1.54 --- Container.java 2001/08/03 17:15:43 1.53 +++ Container.java 2001/08/14 03:31:34 1.54 @@ -14,6 +14,20 @@ import java.util.HashMap; import java.util.Set; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.DynamicMBean; +import javax.management.InvalidAttributeValueException; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.MBeanServer; +import javax.management.ObjectName; +import javax.management.ReflectionException; import javax.naming.Context; import javax.naming.Name; import javax.naming.InitialContext; @@ -39,10 +53,6 @@ import org.jboss.metadata.ResourceEnvRefMetaData; import org.jboss.metadata.ApplicationMetaData; -import org.jnp.interfaces.Naming; -import org.jnp.interfaces.java.javaURLContextFactory; -import org.jnp.server.NamingServer; - import org.jboss.ejb.plugins.local.BaseLocalContainerInvoker; /** @@ -59,11 +69,11 @@ * * @see ContainerFactory * - * @author <a href="mailto:[EMAIL PROTECTED]">Rickard Öberg</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a> - * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a>. + * @author <a href="mailto:[EMAIL PROTECTED]">Rickard Öberg</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Scott Stark</a>. * @author <a href="[EMAIL PROTECTED]">Bill Burke</a> - * @version $Revision: 1.53 $ + * @version $Revision: 1.54 $ * * <p><b>Revisions:</b> * @@ -71,8 +81,12 @@ * <ul> * <li> Added BeanLockManager. * </ul> + * <p><b>2001/08/13 scott.stark:</b> + * <ul> + * <li> Added DynamicMBean support for method invocations and access to EJB interfaces. + * </ul> */ -public abstract class Container +public abstract class Container implements DynamicMBean { // Constants ----------------------------------------------------- @@ -136,6 +150,8 @@ /** ??? */ protected Class localInterface; + protected MBeanServer mbeanServer; + // Public -------------------------------------------------------- public Class getLocalClass() @@ -209,6 +225,10 @@ { return securityProxy; } + void setMBeanServer(MBeanServer mbeanServer) + { + this.mbeanServer = mbeanServer; + } /** * Sets the application deployment unit for this container. All the bean @@ -383,6 +403,9 @@ throws Exception { localContainerInvoker.start(); + + ObjectName jmxName = new ObjectName(":service=Container,jndiName="+this.getBeanMetaData().getJndiName()); + mbeanServer.registerMBean(this, jmxName); } /** @@ -393,6 +416,14 @@ public void stop() { localContainerInvoker.stop(); + try + { + ObjectName jmxName = new ObjectName(":service=Container,jndiName="+this.getBeanMetaData().getJndiName()); + mbeanServer.unregisterMBean(jmxName); + } + catch(Exception e) + { + } } /** @@ -434,6 +465,148 @@ */ public abstract Object invoke(MethodInvocation mi) throws Exception; + + // Begin DynamicMBean interface implementation + public Object getAttribute(String attribute) + throws AttributeNotFoundException, + MBeanException, + ReflectionException + { + return null; + } + + public void setAttribute(Attribute attribute) + throws AttributeNotFoundException, + InvalidAttributeValueException, + MBeanException, + ReflectionException + { + } + + public AttributeList getAttributes(String[] attributes) + { + return null; + } + + public AttributeList setAttributes(AttributeList attributes) + { + return null; + } + + /** Handle a operation invocation. + */ + public Object invoke(String actionName, Object[] params, String[] signature) + throws MBeanException, ReflectionException + { + if( params != null && params.length == 1 && (params[0] instanceof MethodInvocation) == false ) + throw new MBeanException(new IllegalArgumentException("Expected zero or single MethodInvocation argument")); + + Object value = null; + MethodInvocation mi = null; + if( params != null && params.length == 1 ) + mi = (MethodInvocation) params[0]; + + ClassLoader callerClassLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(this.classLoader); + // Check against home, remote, localHome, local, getHome, getRemote, getLocalHome, getLocal + if( actionName.equals("remote") ) + { + value = invoke(mi); + } + else if( actionName.equals("local") ) + { + throw new MBeanException(new UnsupportedOperationException("local is not supported yet")); + } + else if( actionName.equals("home") ) + { + value = invokeHome(mi); + } + else if( actionName.equals("localHome") ) + { + throw new MBeanException(new UnsupportedOperationException("localHome is not supported yet")); + } + else if( actionName.equals("getHome") ) + { + String className = this.getBeanMetaData().getHome(); + if( clasName != null ) + { + Class clazz = this.classLoader.loadClass(className); + value = clazz; + } + } + else if( actionName.equals("getRemote") ) + { + String className = this.getBeanMetaData().getRemote(); + if( className != null ) + { + Class clazz = this.classLoader.loadClass(className); + value = clazz; + } + } + else if( actionName.equals("getLocalHome") ) + { + value = this.localHomeInterface; + } + else if( actionName.equals("getLocal") ) + { + value = this.localInterface; + } + else + { + throw new MBeanException(new IllegalArgumentException("Unknown action: "+actionName)); + } + } + catch(Exception e) + { + log.error("invoke returned an exception", e); + throw new MBeanException(e, "invoke returned an exception"); + } + finally + { + Thread.currentThread().setContextClassLoader(callerClassLoader); + } + + return value; + } + + /** Build the container MBean information on attributes, contstructors, operations, + and notifications. Currently there are no attributes, no constructors, no + notifications, and the following ops: + <ul> + <li>'home' -> invokeHome(MethodInvocation);</li> + <li>'remote' -> invoke(MethodInvocation);</li> + <li>'localHome' -> not implemented;</li> + <li>'local' -> not implemented;</li> + <li>'getHome' -> return EBJHome interface;</li> + <li>'getRemote' -> return EJBObject interface</li> + </ul> + */ + public MBeanInfo getMBeanInfo() + { + MBeanParameterInfo miInfo = new MBeanParameterInfo("method", MethodInvocation.class.getName(), "MethodInvocation data"); + MBeanConstructorInfo[] ctorInfo = null; + MBeanOperationInfo[] opInfo = { + new MBeanOperationInfo("home", "Invoke an EJBHome interface method", + new MBeanParameterInfo[] {miInfo}, + "java.lang.Object", MBeanOperationInfo.ACTION_INFO), + new MBeanOperationInfo("remote", "Invoke an EJBObject interface method", + new MBeanParameterInfo[] {miInfo}, + "java.lang.Object", MBeanOperationInfo.ACTION_INFO), + new MBeanOperationInfo("getHome", "Get the EJBHome interface class", + null, + "java.lang.Class", MBeanOperationInfo.INFO), + new MBeanOperationInfo("getRemote", "Get the EJBObject interface class", + null, + "java.lang.Class", MBeanOperationInfo.INFO) + }; + MBeanNotificationInfo[] notifyInfo = null; + return new MBeanInfo(getClass().getName(), "EJB Container MBean", + null, ctorInfo, opInfo, notifyInfo); + } + + // End DynamicMBean interface // Protected ----------------------------------------------------- 1.1 jboss/src/main/org/jboss/ejb/ContainerRelection.java Index: ContainerRelection.java =================================================================== package org.jboss.ejb; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.RuntimeOperationsException; import org.jboss.util.ServiceMBeanSupport; /** The ContainerRelectionMBean implementation. * @author [EMAIL PROTECTED] * @version $Revision: 1.1 $ */ public class ContainerRelection extends ServiceMBeanSupport implements ContainerRelectionMBean { /** Lookup the mbean located under the object name ":service=Container,jndiName=<jndiName>" and invoke the getHome and getRemote interfaces and dump the methods for each in an html pre block. */ public String inspectEJB(String jndiName) { MBeanServer server = getServer(); StringBuffer buffer = new StringBuffer(); try { buffer.append("<pre>"); ObjectName containerName = new ObjectName(":service=Container,jndiName="+jndiName); Class homeClass = (Class) server.invoke(containerName, "getHome", null, null); buffer.append("\nHome class = "+homeClass); buffer.append("\nClassLoader: "+homeClass.getClassLoader()); buffer.append("\nCodeSource: "+homeClass.getProtectionDomain().getCodeSource()); buffer.append("\n- Methods:"); Method[] homeMethods = homeClass.getMethods(); for(int m = 0; m < homeMethods.length; m ++) buffer.append("\n--- "+homeMethods[m]); Class remoteClass = (Class) server.invoke(containerName, "getRemote", null, null); buffer.append("\nRemote class = "+remoteClass); buffer.append("\n- Methods:"); Method[] remoteMethods = remoteClass.getMethods(); for(int m = 0; m < remoteMethods.length; m ++) buffer.append("\n--- "+remoteMethods[m]); buffer.append("\n</pre>\n"); } catch(Throwable e) { if( e instanceof RuntimeOperationsException ) { RuntimeOperationsException roe = (RuntimeOperationsException) e; e = roe.getTargetException(); } StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); buffer.append(sw.toString()); buffer.append("\n</pre>\n"); } return buffer.toString(); } public String getName() { return "ContainerRelection"; } } 1.1 jboss/src/main/org/jboss/ejb/ContainerRelectionMBean.java Index: ContainerRelectionMBean.java =================================================================== package org.jboss.ejb; /** A sample mbean that looks up the Container MBean for the jndiName passed to the inspectEJB method and retrieves its Home and Remote interfaces and lists all of their methods. * @author [EMAIL PROTECTED] * @version $Revision: 1.1 $ */ public interface ContainerRelectionMBean { /** Lookup the mbean located under the object name ":service=Container,jndiName=<jndiName>" and invoke the getHome and getRemote interfaces and dump the methods for each in an html pre block. */ public String inspectEJB(String jndiName); } _______________________________________________ Jboss-development mailing list [EMAIL PROTECTED] http://lists.sourceforge.net/lists/listinfo/jboss-development