You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2010/05/13 12:14:21 UTC

svn commit: r943862 - in /openejb/trunk/openejb3/container/openejb-core/src: main/java/org/apache/openejb/core/ main/java/org/apache/openejb/core/interceptor/ main/java/org/apache/openejb/core/managed/ main/java/org/apache/openejb/core/mdb/ main/java/o...

Author: dblevins
Date: Thu May 13 10:14:20 2010
New Revision: 943862

URL: http://svn.apache.org/viewvc?rev=943862&view=rev
Log:
OPENEJB-1275: JMX: EJB Method invocations
OPENEJB-1273: JMX: Stateless Pool Stats
Full wiring complete

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java   (with props)
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java   (with props)
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java   (with props)
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/monitoring/
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ManagedMBean.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MethodScratchPad.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ScratchPad.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/StatsInterceptor.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java Thu May 13 10:14:20 2010
@@ -48,10 +48,8 @@ import org.apache.openejb.OpenEJBExcepti
 import org.apache.openejb.SystemException;
 import org.apache.openejb.core.cmp.KeyGenerator;
 import org.apache.openejb.core.interceptor.InterceptorData;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.core.ivm.EjbHomeProxyHandler;
-import org.apache.openejb.core.ivm.EjbObjectProxyHandler;
-import org.apache.openejb.core.stateful.StatefulEjbObjectHandler;
-import org.apache.openejb.core.stateless.StatelessEjbObjectHandler;
 import org.apache.openejb.core.timer.EjbTimerService;
 import org.apache.openejb.core.timer.MethodSchedule;
 import org.apache.openejb.core.transaction.TransactionType;
@@ -59,12 +57,7 @@ import org.apache.openejb.core.transacti
 import org.apache.openejb.util.Index;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.proxy.InvocationHandler;
-import org.apache.openejb.util.proxy.LocalBeanProxyFactory;
 
-/**
- * @org.apache.xbean.XBean element="deployment"
- */
 public class CoreDeploymentInfo implements org.apache.openejb.DeploymentInfo {
 
     private boolean destroyed;
@@ -124,9 +117,12 @@ public class CoreDeploymentInfo implemen
     private final Map<Method, TransactionType> methodTransactionType = new HashMap<Method, TransactionType>();
     private TransactionPolicyFactory transactionPolicyFactory;
 
-    private final Map<Method, List<InterceptorData>> methodInterceptors = new HashMap<Method, List<InterceptorData>>();
     private final List<MethodSchedule> methodSchedules = new ArrayList<MethodSchedule>();
+    private final Map<Method, List<InterceptorData>> methodInterceptors = new HashMap<Method, List<InterceptorData>>();
     private final List<InterceptorData> callbackInterceptors = new ArrayList<InterceptorData>();
+    private final Set<InterceptorData> instanceScopedInterceptors = new HashSet<InterceptorData>();
+
+    private final List<InterceptorInstance> systemInterceptors = new ArrayList<InterceptorInstance>(); 
     private final Map<Method, Method> methodMap = new HashMap<Method, Method>();
     private final Map<String, String> securityRoleReferenceMap = new HashMap<String, String>();
     private String jarPath;
@@ -718,19 +714,6 @@ public class CoreDeploymentInfo implemen
         return retain != null && retain;
     }
 
-    public List<InterceptorData> getMethodInterceptors(Method method) {
-        List<InterceptorData> interceptors = methodInterceptors.get(method);
-        if (interceptors == null) {
-            interceptors = new ArrayList<InterceptorData>();
-        }
-        return interceptors;
-    }
-
-    public void setMethodInterceptors(Method method, List<InterceptorData> interceptors) {
-        methodInterceptors.put(method, interceptors);
-        this.interceptors.addAll(interceptors);
-    }
-
     public List<MethodSchedule> getMethodSchedules() {
         return methodSchedules;
     }
@@ -739,10 +722,29 @@ public class CoreDeploymentInfo implemen
         methodSchedules.addAll(schedules);
     }
 
-    private final Set<InterceptorData> interceptors = new HashSet<InterceptorData>();
+    /**
+     * When an instance of an EJB is instantiated, everything in this list
+     * is also instatiated and tied to the bean instance.  Per spec, interceptors
+     * are supposed to have the same lifecycle as the bean they wrap.
+     *
+     * OpenEJB has the concept of interceptors which do not share the same lifecycle
+     * as the bean instance -- they may be instantiated elsewhere and simply applied
+     * to the bean.  The impact is that these interceptors must be multithreaded.
+     * It also means we do not add these interceptors to this list and expose them
+     * via different means.
+     *
+     * @return standard interceptors sharing the bean lifecycle
+     */
+    public Set<InterceptorData> getInstanceScopedInterceptors() {
+        return instanceScopedInterceptors;
+    }
+
+    public void addSystemInterceptor(Object interceptor) {
+        systemInterceptors.add(new InterceptorInstance(interceptor));    
+    }
 
-    public Set<InterceptorData> getAllInterceptors() {
-        return interceptors;
+    public List<InterceptorInstance> getSystemInterceptors() {
+        return systemInterceptors;
     }
 
     public List<InterceptorData> getCallbackInterceptors() {
@@ -752,7 +754,33 @@ public class CoreDeploymentInfo implemen
     public void setCallbackInterceptors(List<InterceptorData> callbackInterceptors) {
         this.callbackInterceptors.clear();
         this.callbackInterceptors.addAll(callbackInterceptors);
-        this.interceptors.addAll(callbackInterceptors);
+        this.instanceScopedInterceptors.addAll(callbackInterceptors);
+    }
+
+    public List<InterceptorData> getMethodInterceptors(Method method) {
+
+        List<InterceptorData> interceptors = methodInterceptors.get(method);
+
+        if (interceptors == null) interceptors = Collections.EMPTY_LIST;
+
+        if (systemInterceptors.size() <= 0) return interceptors;
+
+        // we have system interceptors to add to the beginning of the stack
+        
+        List<InterceptorData> datas = new ArrayList<InterceptorData>(systemInterceptors.size() + interceptors.size());
+
+        for (InterceptorInstance instance : systemInterceptors) {
+            datas.add(instance.getData());
+        }
+
+        datas.addAll(interceptors);
+        
+        return datas;
+    }
+
+    public void setMethodInterceptors(Method method, List<InterceptorData> interceptors) {
+        methodInterceptors.put(method, interceptors);
+        this.instanceScopedInterceptors.addAll(interceptors);
     }
 
     public void createMethodMap() throws org.apache.openejb.SystemException {

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java Thu May 13 10:14:20 2010
@@ -18,7 +18,13 @@
 package org.apache.openejb.core.interceptor;
 
 import org.apache.openejb.core.Operation;
+import org.apache.xbean.finder.ClassFinder;
 
+import javax.interceptor.AroundInvoke;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
@@ -97,4 +103,18 @@ public class InterceptorData {
     public int hashCode() {
         return (clazz != null ? clazz.hashCode() : 0);
     }
+
+    public static InterceptorData scan(Class<?> clazz) {
+        ClassFinder finder = new ClassFinder(clazz);
+
+        InterceptorData data = new InterceptorData(clazz);
+
+        data.aroundInvoke.addAll(finder.findAnnotatedMethods(AroundInvoke.class));
+        data.postConstruct.addAll(finder.findAnnotatedMethods(PostConstruct.class));
+        data.preDestroy.addAll(finder.findAnnotatedMethods(PreDestroy.class));
+        data.postActivate.addAll(finder.findAnnotatedMethods(PostActivate.class));
+        data.prePassivate.addAll(finder.findAnnotatedMethods(PrePassivate.class));
+
+        return data;
+    }
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java?rev=943862&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java Thu May 13 10:14:20 2010
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.core.interceptor;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InterceptorInstance {
+    private final Object interceptor;
+    private final InterceptorData data;
+
+    public InterceptorInstance(Object interceptor, InterceptorData data) {
+        this.interceptor = interceptor;
+        this.data = data;
+    }
+
+    public InterceptorInstance(Object interceptor) {
+        this(interceptor, InterceptorData.scan(interceptor.getClass()));
+    }
+
+    public Object getInterceptor() {
+        return interceptor;
+    }
+
+    public InterceptorData getData() {
+        return data;
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java Thu May 13 10:14:20 2010
@@ -17,6 +17,7 @@
 package org.apache.openejb.core.managed;
 
 import java.lang.reflect.Method;
+import java.lang.management.ManagementFactory;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
 import java.rmi.dgc.VMID;
@@ -38,6 +39,8 @@ import javax.naming.NamingException;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.transaction.Transaction;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 
 import org.apache.openejb.ApplicationException;
 import org.apache.openejb.ContainerType;
@@ -49,6 +52,9 @@ import org.apache.openejb.OpenEJBExcepti
 import org.apache.openejb.ProxyInfo;
 import org.apache.openejb.RpcContainer;
 import org.apache.openejb.SystemException;
+import org.apache.openejb.monitoring.StatsInterceptor;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.ManagedMBean;
 import static org.apache.openejb.InjectionProcessor.unwrap;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ExceptionType;
@@ -58,6 +64,7 @@ import org.apache.openejb.core.Operation
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.core.managed.Cache.CacheFilter;
 import org.apache.openejb.core.managed.Cache.CacheListener;
 import org.apache.openejb.core.transaction.BeanTransactionPolicy;
@@ -221,6 +228,17 @@ public class ManagedContainer implements
     }
 
     private synchronized void undeploy(final CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        Data data = (Data) deploymentInfo.getContainerData();
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        for (ObjectName objectName : data.jmxNames) {
+            try {
+                server.unregisterMBean(objectName);
+            } catch (Exception e) {
+                logger.error("Unable to unregister MBean "+objectName);
+            }
+        }
+
         deploymentsById.remove(deploymentInfo.getDeploymentID());
         deploymentInfo.setContainer(null);
         deploymentInfo.setContainerData(null);
@@ -230,11 +248,6 @@ public class ManagedContainer implements
                 return deploymentInfo == instance.deploymentInfo;
             }
         });
-
-        StatefulContainerData data = (StatefulContainerData) deploymentInfo.getContainerData();
-        if (data != null) {
-            deploymentInfo.setContainerData(null);
-        }
     }
 
     private synchronized void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
@@ -242,7 +255,32 @@ public class ManagedContainer implements
 
         deploymentsById.put(deploymentInfo.getDeploymentID(), deploymentInfo);
         deploymentInfo.setContainer(this);
-        deploymentInfo.setContainerData(new StatefulContainerData(new Index<Method, MethodType>(methods)));
+        Data data = new Data(new Index<Method, MethodType>(methods));
+        deploymentInfo.setContainerData(data);
+
+        // Create stats interceptor
+        StatsInterceptor stats = new StatsInterceptor(deploymentInfo.getBeanClass());
+        deploymentInfo.addSystemInterceptor(stats);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+        jmxName.set("J2EEServer", "openejb");
+        jmxName.set("J2EEApplication", null);
+        jmxName.set("EJBModule", deploymentInfo.getModuleID());
+        jmxName.set("StatelessSessionBean", deploymentInfo.getEjbName());
+        jmxName.set("j2eeType", "");
+        jmxName.set("name", deploymentInfo.getEjbName());
+
+        // register the invocation stats interceptor
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Invocations").build();
+            server.registerMBean(new ManagedMBean(stats), objectName);
+            data.jmxNames.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
     }
 
     /**
@@ -264,7 +302,7 @@ public class ManagedContainer implements
         // Use the backup way to determine call type if null was supplied.
         if (type == null) type = deployInfo.getInterfaceType(callInterface);
 
-        StatefulContainerData data = (StatefulContainerData) deployInfo.getContainerData();
+        Data data = (Data) deployInfo.getContainerData();
         MethodType methodType = data.getMethodIndex().get(callMethod);
         methodType = (methodType != null) ? methodType : MethodType.BUSINESS;
 
@@ -563,7 +601,14 @@ public class ManagedContainer implements
 
             // Create interceptors
             HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
-            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+
+            // Add the stats interceptor instance and other already created interceptor instances
+            for (InterceptorInstance interceptorInstance : deploymentInfo.getSystemInterceptors()) {
+                Class clazz = interceptorInstance.getData().getInterceptorClass();
+                interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
+            }
+
+            for (InterceptorData interceptorData : deploymentInfo.getInstanceScopedInterceptors()) {
                 if (interceptorData.getInterceptorClass().equals(beanClass)) {
                     continue;
                 }
@@ -1055,10 +1100,11 @@ public class ManagedContainer implements
         }
     }    
 
-    private static class StatefulContainerData {
+    private static class Data {
         private final Index<Method, MethodType> methodIndex;
-
-        private StatefulContainerData(Index<Method, MethodType> methodIndex) {
+        private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
+        
+        private Data(Index<Method, MethodType> methodIndex) {
             this.methodIndex = methodIndex;
         }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/EndpointFactory.java Thu May 13 10:14:20 2010
@@ -26,8 +26,11 @@ import javax.resource.spi.ActivationSpec
 import javax.resource.spi.endpoint.MessageEndpoint;
 import javax.resource.spi.endpoint.MessageEndpointFactory;
 import javax.transaction.xa.XAResource;
+import javax.management.ObjectName;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
 
 public class EndpointFactory implements MessageEndpointFactory {
     private final ActivationSpec activationSpec;
@@ -37,7 +40,8 @@ public class EndpointFactory implements 
     private final ClassLoader classLoader;
     private final Class[] interfaces;
     private final XAResourceWrapper xaResourceWrapper;
-
+    protected final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
+    
     public EndpointFactory(ActivationSpec activationSpec, MdbContainer container, CoreDeploymentInfo deploymentInfo, MdbInstanceFactory instanceFactory, XAResourceWrapper xaResourceWrapper) {
         this.activationSpec = activationSpec;
         this.container = container;

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbContainer.java Thu May 13 10:14:20 2010
@@ -24,6 +24,9 @@ import org.apache.openejb.ApplicationExc
 import org.apache.openejb.ContainerType;
 import org.apache.openejb.RpcContainer;
 import org.apache.openejb.InterfaceType;
+import org.apache.openejb.monitoring.StatsInterceptor;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.ManagedMBean;
 import org.apache.openejb.resource.XAResourceWrapper;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.core.BaseContext;
@@ -51,8 +54,11 @@ import javax.resource.spi.ResourceAdapte
 import javax.resource.spi.ActivationSpec;
 import javax.resource.spi.UnavailableException;
 import javax.resource.ResourceException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.management.ManagementFactory;
 import java.util.List;
 import java.util.Map;
 import java.util.Arrays;
@@ -135,6 +141,29 @@ public class MdbContainer implements Rpc
         deploymentInfo.setContainerData(endpointFactory);
         deployments.put(deploymentId, deploymentInfo);
 
+        // Create stats interceptor
+        StatsInterceptor stats = new StatsInterceptor(deploymentInfo.getBeanClass());
+        deploymentInfo.addSystemInterceptor(stats);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+        jmxName.set("J2EEServer", "openejb");
+        jmxName.set("J2EEApplication", null);
+        jmxName.set("EJBModule", deploymentInfo.getModuleID());
+        jmxName.set("StatelessSessionBean", deploymentInfo.getEjbName());
+        jmxName.set("j2eeType", "");
+        jmxName.set("name", deploymentInfo.getEjbName());
+
+        // register the invocation stats interceptor
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Invocations").build();
+            server.registerMBean(new ManagedMBean(stats), objectName);
+            endpointFactory.jmxNames.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
         // activate the endpoint
         try {
             resourceAdapter.endpointActivation(endpointFactory, activationSpec);
@@ -205,6 +234,15 @@ public class MdbContainer implements Rpc
             EndpointFactory endpointFactory = (EndpointFactory) deploymentInfo.getContainerData();
             if (endpointFactory != null) {
                 resourceAdapter.endpointDeactivation(endpointFactory, endpointFactory.getActivationSpec());
+
+                MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+                for (ObjectName objectName : endpointFactory.jmxNames) {
+                    try {
+                        server.unregisterMBean(objectName);
+                    } catch (Exception e) {
+                        logger.error("Unable to unregister MBean "+objectName);
+                    }
+                }
             }
         } finally {
             deploymentInfo.setContainer(null);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java Thu May 13 10:14:20 2010
@@ -35,12 +35,12 @@ import org.apache.openejb.core.Operation
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 import org.apache.xbean.recipe.ConstructionException;
 import org.apache.xbean.recipe.ObjectRecipe;
-import org.apache.xbean.recipe.Option;
 
 /**
  * A MdbInstanceFactory creates instances of message driven beans for a single instance. This class differs from other
@@ -200,7 +200,14 @@ public class MdbInstanceFactory {
             Object bean = injectionProcessor.createInstance();
 
             HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
-            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+
+            // Add the stats interceptor instance and other already created interceptor instances
+            for (InterceptorInstance interceptorInstance : deploymentInfo.getSystemInterceptors()) {
+                Class clazz = interceptorInstance.getData().getInterceptorClass();
+                interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
+            }
+
+            for (InterceptorData interceptorData : deploymentInfo.getInstanceScopedInterceptors()) {
                 if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
 
                 Class clazz = interceptorData.getInterceptorClass();

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java Thu May 13 10:14:20 2010
@@ -17,7 +17,7 @@
 package org.apache.openejb.core.singleton;
 
 import java.lang.reflect.Method;
-import java.rmi.RemoteException;
+import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -39,16 +39,22 @@ import javax.ejb.NoSuchEJBException;
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.xml.ws.WebServiceContext;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 
 import org.apache.openejb.Injection;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.ApplicationException;
+import org.apache.openejb.monitoring.StatsInterceptor;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.ManagedMBean;
 import org.apache.openejb.core.BaseContext;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.Operation;
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
@@ -173,7 +179,14 @@ public class SingletonInstanceManager {
             }
 
             HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
-            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+
+            // Add the stats interceptor instance and other already created interceptor instances
+            for (InterceptorInstance interceptorInstance : deploymentInfo.getSystemInterceptors()) {
+                Class clazz = interceptorInstance.getData().getInterceptorClass();
+                interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
+            }
+
+            for (InterceptorData interceptorData : deploymentInfo.getInstanceScopedInterceptors()) {
                 if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
 
                 Class clazz = interceptorData.getInterceptorClass();
@@ -334,17 +347,57 @@ public class SingletonInstanceManager {
 
     public void deploy(CoreDeploymentInfo deploymentInfo) {
         Data data = new Data();
-        deploymentInfo.setContainerData(data);      
+        deploymentInfo.setContainerData(data);
+
+        // Create stats interceptor
+        StatsInterceptor stats = new StatsInterceptor(deploymentInfo.getBeanClass());
+        deploymentInfo.addSystemInterceptor(stats);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+        jmxName.set("J2EEServer", "openejb");
+        jmxName.set("J2EEApplication", null);
+        jmxName.set("EJBModule", deploymentInfo.getModuleID());
+        jmxName.set("SingletonSessionBean", deploymentInfo.getEjbName());
+        jmxName.set("j2eeType", "");
+        jmxName.set("name", deploymentInfo.getEjbName());
+
+        // register the invocation stats interceptor
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Invocations").build();
+            server.registerMBean(new ManagedMBean(stats), objectName);
+            data.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
     }
 
     public void undeploy(CoreDeploymentInfo deploymentInfo) {
         Data data = (Data) deploymentInfo.getContainerData();
         if (data == null) return;
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        for (ObjectName objectName : data.jmxNames) {
+            try {
+                server.unregisterMBean(objectName);
+            } catch (Exception e) {
+                logger.error("Unable to unregister MBean "+objectName);
+            }
+        }
+
         deploymentInfo.setContainerData(null);
     }
 
     private static final class Data {
         private final AtomicReference<Future<Instance>> singleton = new AtomicReference<Future<Instance>>();
+        private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
+
+        public ObjectName add(ObjectName name) {
+            jmxNames.add(name);
+            return name;
+        }
     }
 
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Thu May 13 10:14:20 2010
@@ -17,6 +17,7 @@
 package org.apache.openejb.core.stateful;
 
 import java.lang.reflect.Method;
+import java.lang.management.ManagementFactory;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
 import java.rmi.dgc.VMID;
@@ -33,12 +34,13 @@ import javax.ejb.RemoveException;
 import javax.ejb.SessionBean;
 import javax.ejb.SessionContext;
 import javax.ejb.SessionSynchronization;
-import javax.ejb.NoSuchEJBException;
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
 import javax.transaction.Transaction;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
 
 import org.apache.openejb.ApplicationException;
 import org.apache.openejb.ContainerType;
@@ -50,6 +52,9 @@ import org.apache.openejb.OpenEJBExcepti
 import org.apache.openejb.ProxyInfo;
 import org.apache.openejb.RpcContainer;
 import org.apache.openejb.SystemException;
+import org.apache.openejb.monitoring.StatsInterceptor;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.ManagedMBean;
 import static org.apache.openejb.InjectionProcessor.unwrap;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.ExceptionType;
@@ -59,6 +64,7 @@ import org.apache.openejb.core.Operation
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.core.stateful.Cache.CacheFilter;
 import org.apache.openejb.core.stateful.Cache.CacheListener;
 import org.apache.openejb.core.transaction.BeanTransactionPolicy;
@@ -232,6 +238,17 @@ public class StatefulContainer implement
     }
 
     private synchronized void undeploy(final CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
+        Data data = (Data) deploymentInfo.getContainerData();
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        for (ObjectName objectName : data.jmxNames) {
+            try {
+                server.unregisterMBean(objectName);
+            } catch (Exception e) {
+                logger.error("Unable to unregister MBean "+objectName);
+            }
+        }
+
         deploymentsById.remove(deploymentInfo.getDeploymentID());
         deploymentInfo.setContainer(null);
         deploymentInfo.setContainerData(null);
@@ -241,11 +258,6 @@ public class StatefulContainer implement
                 return deploymentInfo == instance.deploymentInfo;
             }
         });
-
-        StatefulContainerData data = (StatefulContainerData) deploymentInfo.getContainerData();
-        if (data != null) {
-            deploymentInfo.setContainerData(null);
-        }
     }
 
     private synchronized void deploy(CoreDeploymentInfo deploymentInfo) throws OpenEJBException {
@@ -253,7 +265,32 @@ public class StatefulContainer implement
 
         deploymentsById.put(deploymentInfo.getDeploymentID(), deploymentInfo);
         deploymentInfo.setContainer(this);
-        deploymentInfo.setContainerData(new StatefulContainerData(new Index<Method, MethodType>(methods)));
+        Data data = new Data(new Index<Method, MethodType>(methods));
+        deploymentInfo.setContainerData(data);
+
+        // Create stats interceptor
+        StatsInterceptor stats = new StatsInterceptor(deploymentInfo.getBeanClass());
+        deploymentInfo.addSystemInterceptor(stats);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+        jmxName.set("J2EEServer", "openejb");
+        jmxName.set("J2EEApplication", null);
+        jmxName.set("EJBModule", deploymentInfo.getModuleID());
+        jmxName.set("StatefulSessionBean", deploymentInfo.getEjbName());
+        jmxName.set("j2eeType", "");
+        jmxName.set("name", deploymentInfo.getEjbName());
+
+        // register the invocation stats interceptor
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Invocations").build();
+            server.registerMBean(new ManagedMBean(stats), objectName);
+            data.jmxNames.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
     }
 
     /**
@@ -275,7 +312,7 @@ public class StatefulContainer implement
         // Use the backup way to determine call type if null was supplied.
         if (type == null) type = deployInfo.getInterfaceType(callInterface);
 
-        StatefulContainerData data = (StatefulContainerData) deployInfo.getContainerData();
+        Data data = (Data) deployInfo.getContainerData();
         MethodType methodType = data.getMethodIndex().get(callMethod);
         methodType = (methodType != null) ? methodType : MethodType.BUSINESS;
 
@@ -575,7 +612,14 @@ public class StatefulContainer implement
 
             // Create interceptors
             HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
-            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+
+            // Add the stats interceptor instance and other already created interceptor instances
+            for (InterceptorInstance interceptorInstance : deploymentInfo.getSystemInterceptors()) {
+                Class clazz = interceptorInstance.getData().getInterceptorClass();
+                interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
+            }
+
+            for (InterceptorData interceptorData : deploymentInfo.getInstanceScopedInterceptors()) {
                 if (interceptorData.getInterceptorClass().equals(beanClass)) {
                     continue;
                 }
@@ -1067,10 +1111,11 @@ public class StatefulContainer implement
         }
     }    
 
-    private static class StatefulContainerData {
+    private static class Data {
         private final Index<Method, MethodType> methodIndex;
-
-        private StatefulContainerData(Index<Method, MethodType> methodIndex) {
+        private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
+        
+        private Data(Index<Method, MethodType> methodIndex) {
             this.methodIndex = methodIndex;
         }
 

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Thu May 13 10:14:20 2010
@@ -18,6 +18,7 @@ package org.apache.openejb.core.stateles
 
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.management.ManagementFactory;
 import java.rmi.RemoteException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -36,10 +37,19 @@ import javax.ejb.SessionContext;
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.xml.ws.WebServiceContext;
+import javax.management.ObjectName;
+import javax.management.MBeanServer;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.InstanceNotFoundException;
 
 import org.apache.openejb.Injection;
 import org.apache.openejb.OpenEJBException;
 import org.apache.openejb.SystemException;
+import org.apache.openejb.monitoring.StatsInterceptor;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.ManagedMBean;
 import org.apache.openejb.loader.Options;
 import org.apache.openejb.core.BaseContext;
 import org.apache.openejb.core.CoreDeploymentInfo;
@@ -47,6 +57,7 @@ import org.apache.openejb.core.Operation
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.core.interceptor.InterceptorStack;
+import org.apache.openejb.core.interceptor.InterceptorInstance;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Duration;
 import org.apache.openejb.util.LogCategory;
@@ -198,7 +209,14 @@ public class StatelessInstanceManager {
             }
 
             HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
-            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+
+            // Add the stats interceptor instance and other already created interceptor instances
+            for (InterceptorInstance interceptorInstance : deploymentInfo.getSystemInterceptors()) {
+                Class clazz = interceptorInstance.getData().getInterceptorClass();
+                interceptorInstances.put(clazz.getName(), interceptorInstance.getInterceptor());
+            }
+
+            for (InterceptorData interceptorData : deploymentInfo.getInstanceScopedInterceptors()) {
                 if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
 
                 Class clazz = interceptorData.getInterceptorClass();
@@ -393,6 +411,39 @@ public class StatelessInstanceManager {
         long maxAge = builder.getMaxAge().getTime(TimeUnit.MILLISECONDS);
         double maxAgeOffset = builder.getMaxAgeOffset();
 
+        // Create stats interceptor
+        StatsInterceptor stats = new StatsInterceptor(deploymentInfo.getBeanClass());
+        deploymentInfo.addSystemInterceptor(stats);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+        ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+        jmxName.set("J2EEServer", "openejb");
+        jmxName.set("J2EEApplication", null);
+        jmxName.set("EJBModule", deploymentInfo.getModuleID());
+        jmxName.set("StatelessSessionBean", deploymentInfo.getEjbName());
+        jmxName.set("j2eeType", "");
+        jmxName.set("name", deploymentInfo.getEjbName());
+
+        // register the invocation stats interceptor
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Invocations").build();
+            server.registerMBean(new ManagedMBean(stats), objectName);
+            data.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
+        // register the pool
+        try {
+            ObjectName objectName = jmxName.set("j2eeType", "Pool").build();
+            server.registerMBean(new ManagedMBean(data.pool), objectName);
+            data.add(objectName);
+        } catch (Exception e) {
+            logger.error("Unable to register MBean ", e);
+        }
+
+        // Finally, fill the pool and start it
         for (int i = 0; i < min; i++) {
             Instance obj = createInstance(deploymentInfo);
 
@@ -424,13 +475,25 @@ public class StatelessInstanceManager {
         Data data = (Data) deploymentInfo.getContainerData();
         if (data == null) return;
         data.getPool().stop();
+
         //TODO *maybe* call ejbRemove on each bean in pool.
+
         deploymentInfo.setContainerData(null);
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        for (ObjectName objectName : data.jmxNames) {
+            try {
+                server.unregisterMBean(objectName);
+            } catch (Exception e) {
+                logger.error("Unable to unregister MBean "+objectName);
+            }
+        }
     }
 
     private static final class Data {
         private final Pool<Instance> pool;
         private Duration accessTimeout;
+        private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
 
         public Data(Pool<Instance> pool, Duration accessTimeout) {
             this.accessTimeout = accessTimeout;
@@ -448,6 +511,11 @@ public class StatelessInstanceManager {
         public Pool<Instance> getPool() {
             return pool;
         }
+
+        public ObjectName add(ObjectName name) {
+            jmxNames.add(name);
+            return name;
+        }
     }
 
 }

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ManagedMBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ManagedMBean.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ManagedMBean.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ManagedMBean.java Thu May 13 10:14:20 2010
@@ -50,7 +50,7 @@ import java.util.regex.Pattern;
 /**
  * @version $Rev$ $Date$
  */
-class ManagedMBean implements DynamicMBean {
+public class ManagedMBean implements DynamicMBean {
 
     private final List<MBeanAttributeInfo> attributes = new ArrayList<MBeanAttributeInfo>();
     private final List<MBeanOperationInfo> operations = new ArrayList<MBeanOperationInfo>();
@@ -64,7 +64,7 @@ class ManagedMBean implements DynamicMBe
     private MBeanParameterInfo excludeInfo;
     private MBeanParameterInfo includeInfo;
 
-    ManagedMBean(Object managed) {
+    public ManagedMBean(Object managed) {
         this(managed, "");
 
         try {

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MethodScratchPad.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MethodScratchPad.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MethodScratchPad.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/MethodScratchPad.java Thu May 13 10:14:20 2010
@@ -17,16 +17,32 @@
 package org.apache.openejb.monitoring;
 
 import org.apache.openejb.api.Monitor;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
 
 import javax.interceptor.InvocationContext;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
+import javax.management.MalformedObjectNameException;
+import javax.ejb.Stateless;
+import javax.naming.Context;
+import javax.naming.InitialContext;
 import java.lang.reflect.Method;
 import java.lang.management.ManagementFactory;
 import java.util.Map;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Random;
+import java.util.Properties;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.TreeMap;
+import java.util.LinkedHashMap;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -34,51 +50,96 @@ import java.util.concurrent.CountDownLat
  */
 public class MethodScratchPad {
     public static void main(String[] args) throws Exception {
-        new MethodScratchPad().main();
+        Runnable methods  = new Runnable() {
+            public void run() {
+                try {
+                    new MethodScratchPad().main();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+
+        Runnable pool = new Runnable() {
+            public void run() {
+                try {
+                    new ScratchPad().main();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+
+        new Thread(methods).start();
+//        new Thread(pool).start();
     }
 
     public void main() throws Exception {
 
-        List<Context> contexts = new ArrayList<Context>();
-        Class<MyBean> clazz = MyBean.class;
-        contexts.add(new Context(clazz.getMethod("red")));
-        contexts.add(new Context(clazz.getMethod("red")));
-        contexts.add(new Context(clazz.getMethod("red")));
-        contexts.add(new Context(clazz.getMethod("red")));
-        contexts.add(new Context(clazz.getMethod("red")));
-        contexts.add(new Context(clazz.getMethod("blue")));
-        contexts.add(new Context(clazz.getMethod("blue")));
-        contexts.add(new Context(clazz.getMethod("blue")));
-        contexts.add(new Context(clazz.getMethod("green")));
-        contexts.add(new Context(clazz.getMethod("green")));
-        contexts.add(new Context(clazz.getMethod("orange")));
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, InitContextFactory.class.getName());
 
-        Random random = new Random();
-        StatsInterceptor interceptor = new StatsInterceptor(clazz);
+        Assembler assembler = new Assembler();
+        ConfigurationFactory config = new ConfigurationFactory();
+
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
 
-        interceptor.invoke(contexts.get(random(random, 0, contexts.size())));
-        interceptor.invoke(contexts.get(random(random, 0, contexts.size())));
-        
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-        server.registerMBean(new ManagedMBean(interceptor), new ObjectName("something:name=Invocations"));
+        EjbJar ejbJar = new EjbJar();
+        ejbJar.addEnterpriseBean(new StatelessBean(MyBean.class));
+        assembler.createApplication(config.configureApplication(ejbJar));
+
+        javax.naming.Context context = new InitialContext();
+        Object bean = context.lookup("MyBeanLocal");
+
+        List<Method> methods = new ArrayList<Method>();
+        Class<?> clazz = MyBeanLocal.class;
+        methods.add(clazz.getMethod("red"));
+        methods.add(clazz.getMethod("red"));
+        methods.add(clazz.getMethod("red"));
+        methods.add(clazz.getMethod("red"));
+        methods.add(clazz.getMethod("red"));
+        methods.add(clazz.getMethod("blue"));
+        methods.add(clazz.getMethod("blue"));
+        methods.add(clazz.getMethod("blue"));
+        methods.add(clazz.getMethod("green"));
+        methods.add(clazz.getMethod("green"));
+        methods.add(clazz.getMethod("orange"));
+
+        Random random = new Random();
 
-        snooze(5000);
         while (true) {
-            interceptor.invoke(contexts.get(random(random, 0, contexts.size())));
+            methods.get(random(random, 0, methods.size())).invoke(bean);
         }
-//        new CountDownLatch(1).await();
-
     }
 
     @Monitor
-    public static class MyBean {
-        public void red(){}
-        public void green(){}
-        public void blue(){}
-        public void orange(){}
+    @Stateless
+    public static class MyBean implements MyBeanLocal {
+        public void red() {
+            snooze((int) (System.nanoTime() / 1000 % 287));
+        }
+
+        public void green() {
+            snooze((int) (System.nanoTime() / 1000 % 375));
+        }
+
+        public void blue() {
+            snooze((int) (System.nanoTime() / 1000 % 867));
+        }
+
+        public void orange() {
+            snooze((int) (System.nanoTime() / 1000 % 639));
+        }
     }
 
-    private void snooze(int millis) {
+    public static interface MyBeanLocal {
+        public void red();
+        public void green();
+        public void blue();
+        public void orange();
+    }
+
+    private static void snooze(int millis) {
         try {
             Thread.sleep(millis);
         } catch (InterruptedException e) {
@@ -92,40 +153,4 @@ public class MethodScratchPad {
         return (i % (max - min)) + min;
     }
 
-    private class Context implements InvocationContext {
-
-        private final Random random = new Random();
-
-        private final Method method;
-
-        private Context(Method method) {
-            this.method = method;
-        }
-
-        public Object getTarget() {
-            return null;
-        }
-
-        public Method getMethod() {
-            return method;
-        }
-
-        public Object[] getParameters() {
-            return new Object[0];
-        }
-
-        public void setParameters(Object[] objects) {
-        }
-
-        public Map<String, Object> getContextData() {
-            return null;
-        }
-
-        public Object proceed() throws Exception {
-            snooze((int) (System.nanoTime() / 1000 % 1000));
-
-            return null;
-        }
-    }
-
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java?rev=943862&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java Thu May 13 10:14:20 2010
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.monitoring;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ObjectNameBuilder {
+
+    private Map<String, String> map;
+    private String domain;
+
+    public ObjectNameBuilder() {
+        this("default");
+    }
+
+    public ObjectNameBuilder(String domain) {
+        map = new LinkedHashMap<String, String>();
+        this.domain = domain;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public ObjectName build() {
+        try {
+            StringBuilder sb = new StringBuilder(domain + ":");
+            for (Map.Entry<String, String> entry : map.entrySet()) {
+                sb.append(entry.getKey()).append("=").append(entry.getValue()).append(",");
+            }
+            sb.deleteCharAt(sb.lastIndexOf(","));
+
+            return new ObjectName(sb.toString());
+        } catch (MalformedObjectNameException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public ObjectNameBuilder set(String key, String value) {
+        map.put(key, value);
+        return this;
+    }
+
+    public ObjectNameBuilder copy() {
+        ObjectNameBuilder builder = new ObjectNameBuilder();
+        builder.domain = this.domain;
+        builder.map.putAll(this.map);
+        return builder;
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ObjectNameBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ScratchPad.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ScratchPad.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ScratchPad.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/ScratchPad.java Thu May 13 10:14:20 2010
@@ -21,6 +21,8 @@ import java.lang.reflect.Method;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
@@ -66,7 +68,15 @@ public class ScratchPad {
         pool.add("");
         pool.add("");
 
-        server.registerMBean(new ManagedMBean(pool), new ObjectName("something:name=Pool"));
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("EJBModule", "FooModule");
+        map.put("J2EEApplication", "FooApp");
+        map.put("J2EEServer", "FooServer");
+        map.put("j2eeType", "StatelessSessionBean");
+        map.put("name", "Pool");
+
+        ObjectName objectName = new ObjectName("something", new Hashtable(map));
+        server.registerMBean(new ManagedMBean(pool), objectName);
 
 //        while ("".equals("")) {
 //            object.tick(System.currentTimeMillis() % 1000);

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/StatsInterceptor.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/StatsInterceptor.java?rev=943862&r1=943861&r2=943862&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/StatsInterceptor.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/monitoring/StatsInterceptor.java Thu May 13 10:14:20 2010
@@ -19,6 +19,7 @@ package org.apache.openejb.monitoring;
 import org.apache.commons.math.stat.descriptive.SynchronizedDescriptiveStatistics;
 import org.apache.xbean.finder.ClassFinder;
 import org.apache.openejb.api.Monitor;
+import org.apache.openejb.core.interceptor.InterceptorData;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
@@ -38,10 +39,14 @@ import java.util.concurrent.atomic.Atomi
  */
 public class StatsInterceptor {
 
+    public static final InterceptorData metadata = InterceptorData.scan(StatsInterceptor.class);
+
     private final Map<Method, Stats> map = new ConcurrentHashMap<Method, Stats>();
     private final AtomicLong invocations = new AtomicLong();
+    private final AtomicLong invocationTime = new AtomicLong();
 
     private Monitor monitor;
+    private final boolean enabled;
 
     public StatsInterceptor(Class<?> componentClass) {
 
@@ -50,18 +55,24 @@ public class StatsInterceptor {
         for (Method method : finder.findAnnotatedMethods(Monitor.class)) {
             map.put(method, new Stats(method, monitor));
         }
+        enabled = monitor != null || map.size() > 0;
     }
 
     public boolean isMonitoringEnabled() {
-        return monitor != null || map.size() > 0;
+        return enabled;
     }
 
     @Managed
-    public long getInvocations() {
+    public long getInvocationCount() {
         return invocations.get();
     }
 
     @Managed
+    public long getInvocationTime() {
+        return invocationTime.get();
+    }
+
+    @Managed
     public long getMonitoredMethods() {
         return map.size();
     }
@@ -99,19 +110,25 @@ public class StatsInterceptor {
     private Object record(InvocationContext invocationContext) throws Exception {
         invocations.incrementAndGet();
 
-        Stats stats = stats(invocationContext);
+        Stats stats = enabled ? stats(invocationContext): null;
         long start = System.nanoTime();
-        try {
+        try{
             return invocationContext.proceed();
         } finally {
-            stats.record(start);
+            long time = millis(System.nanoTime() - start);
+            if (stats != null) stats.record(time);
+            invocationTime.addAndGet(time);
         }
     }
 
+    private long millis(long nanos) {
+        return TimeUnit.MILLISECONDS.convert(nanos, TimeUnit.NANOSECONDS);
+    }
+
     private Stats stats(InvocationContext invocationContext) {
         Method method = invocationContext.getMethod();
         Stats stats = map.get(method);
-        if (stats == null && monitor != null) {
+        if (stats == null) {
             stats = new Stats(method, monitor);
             map.put(method, stats);
         }
@@ -256,14 +273,10 @@ public class StatsInterceptor {
             return samples.getValues();
         }
 
-        public void record(long start) {
+        public void record(long time) {
             count.incrementAndGet();
-            long time = System.nanoTime() - start;
-            samples.addValue(millis(time));
+            samples.addValue(time);
         }
 
-        private long millis(long nanos) {
-            return TimeUnit.MILLISECONDS.convert(nanos, TimeUnit.NANOSECONDS);
-        }
     }
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java?rev=943862&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java Thu May 13 10:14:20 2010
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public final class Pipe implements Runnable {
+
+    private final InputStream in;
+    private final OutputStream out;
+
+    public Pipe(InputStream in, OutputStream out) {
+        this.in = in;
+        this.out = out;
+    }
+
+    public static void pipe(Process process) {
+        pipe(process.getInputStream(), System.out);
+        pipe(process.getErrorStream(), System.err);
+        pipe(System.in, process.getOutputStream());
+    }
+
+    public static void pipe(InputStream in, OutputStream out) {
+        final Thread thread = new Thread(new Pipe(in, out));
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+    public void run() {
+        try {
+            int i = -1;
+
+            byte[] buf = new byte[1024];
+
+            while ((i = in.read(buf)) != -1) {
+                out.write(buf, 0, i);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

Propchange: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Pipe.java
------------------------------------------------------------------------------
    svn:eol-style = native