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 2007/03/13 13:07:22 UTC

svn commit: r517657 [1/2] - in /incubator/openejb/trunk/openejb3: container/openejb-core/src/main/java/org/apache/openejb/ container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ container/openejb-core/src/main/java/org/apache/openej...

Author: dblevins
Date: Tue Mar 13 05:07:19 2007
New Revision: 517657

URL: http://svn.apache.org/viewvc?view=rev&rev=517657
Log:
Clean up of interceptor and lifecycle code.  
Implemented:
 OPENEJB-234: javax.ejb.Init
 OPENEJB-242: javax.ejb.Remove
 OPENEJB-522: EJB 3 Stateful beans with init-method/@Init

Added:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InitMethodInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/RemoveMethodInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/SetAccessible.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/DebuggableVmHackery.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/Compat3to2Test.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulSessionBeanTest.java
Modified:
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InterceptorBindingBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/StatefulBeanInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/Operation.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorStack.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
    incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/EjbJar.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/InitMethod.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Interceptor.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/NamedMethod.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/RemoveMethod.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/Session.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java
    incubator/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/oejb3/OpenejbJar.java
    incubator/openejb/trunk/openejb3/examples/helloworld-stateful-pojo/src/main/java/org/acme/FriendlyPersonImpl.java
    incubator/openejb/trunk/openejb3/examples/helloworld-stateful-pojo/src/main/resources/META-INF/ejb-jar.xml
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/stateful/AnnotatedFieldInjectionStatefulBean.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/stateful/BasicStatefulPojoBean.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/java/org/apache/openejb/test/stateful/ContextLookupStatefulPojoBean.java
    incubator/openejb/trunk/openejb3/itests/openejb-itests-beans/src/main/resources/META-INF/ejb-jar.xml
    incubator/openejb/trunk/openejb3/itests/openejb-itests-client/src/main/java/org/apache/openejb/test/stateful/StatefulLocalTestSuite.java

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java Tue Mar 13 05:07:19 2007
@@ -88,13 +88,15 @@
 
     ClassLoader getClassLoader();
 
-    Method getPostActivate();
+    public List<Method> getAroundInvoke();
 
-    Method getPostConstruct();
+    public List<Method> getPostConstruct();
 
-    Method getPreDestroy();
+    public List<Method> getPreDestroy();
 
-    Method getPrePassivate();
+    public List<Method> getPostActivate();
+
+    public List<Method> getPrePassivate();
 
     List<Injection> getInjections();
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AssemblerTool.java Tue Mar 13 05:07:19 2007
@@ -104,7 +104,7 @@
     public void applySecurityRoleReference(CoreDeploymentInfo deployment, EnterpriseBeanInfo beanInfo, AssemblerTool.RoleMapping roleMapping) {
         for (SecurityRoleReferenceInfo roleRef : beanInfo.securityRoleReferences) {
             List<String> physicalRoles = roleMapping.getPhysicalRoles(roleRef.roleLink);
-//HACK            deployment.addSecurityRoleReference(roleRef.roleName, physicalRoles);
+            deployment.addSecurityRoleReference(roleRef.roleName, physicalRoles);
         }
     }
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java Tue Mar 13 05:07:19 2007
@@ -23,7 +23,6 @@
 import org.apache.openejb.core.DeploymentContext;
 import org.apache.openejb.core.timer.EjbTimerServiceImpl;
 import org.apache.openejb.core.cmp.CmpUtil;
-import org.apache.openejb.core.interceptor.InterceptorData;
 import org.apache.openejb.util.Index;
 import org.apache.openejb.util.Messages;
 import org.apache.openejb.util.SafeToolkit;
@@ -37,6 +36,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Collections;
+import java.util.Arrays;
 
 class EnterpriseBeanBuilder {
     protected static final Messages messages = new Messages("org.apache.openejb.util.resources");
@@ -164,7 +165,7 @@
                 deployment.getInjections().add(injection);
             }
         }
-        
+
         for (ResourceEnvReferenceInfo info : bean.jndiEnc.resourceEnvRefs) {
             for (InjectionInfo target : info.targets) {
                 Class targetClass = loadClass(target.className, "classNotFound.injectionTarget");
@@ -172,9 +173,10 @@
                 deployment.getInjections().add(injection);
             }
         }
-        
-        deployment.setPostConstruct(getCallback(ejbClass, bean.postConstruct));
-        deployment.setPreDestroy(getCallback(ejbClass, bean.preDestroy));
+
+        // TODO
+//        deployment.setPostConstruct(getCallback(ejbClass, bean.postConstruct));
+//        deployment.setPreDestroy(getCallback(ejbClass, bean.preDestroy));
 
         // Timer
         deployment.setEjbTimeout(getTimeout(ejbClass, bean.timeoutMethod));
@@ -192,8 +194,29 @@
 
         if (bean instanceof StatefulBeanInfo) {
             StatefulBeanInfo statefulBeanInfo = (StatefulBeanInfo) bean;
-            deployment.setPrePassivate(getCallback(ejbClass, statefulBeanInfo.prePassivate));
-            deployment.setPostActivate(getCallback(ejbClass, statefulBeanInfo.postActivate));
+
+            for (InitMethodInfo init : statefulBeanInfo.initMethods) {
+                Method beanMethod = toMethod(ejbClass, init.beanMethod);
+                List<Method> methods = new ArrayList<Method>();
+
+                if (home != null) methods.addAll(Arrays.asList(home.getMethods()));
+                if (localhome != null) methods.addAll(Arrays.asList(localhome.getMethods()));
+
+                for (Method homeMethod : methods) {
+                    if (init.createMethod != null && !init.createMethod.methodName.equals(homeMethod.getName())) continue;
+
+                    if (!homeMethod.getName().startsWith("create")) continue;
+
+                    if (paramsMatch(beanMethod, homeMethod)){
+                        deployment.mapMethods(homeMethod, beanMethod);
+                    }
+                }
+            }
+
+            for (RemoveMethodInfo removeMethod : statefulBeanInfo.removeMethods) {
+                // TODO: Process retainIfException
+                deployment.getRemoveMethods().add(toMethod(ejbClass, removeMethod.beanMethod));
+            }
 
             Map<EntityManagerFactory, Map> extendedEntityManagerFactories = new HashMap<EntityManagerFactory, Map>();
             for (PersistenceContextReferenceInfo info : statefulBeanInfo.jndiEnc.persistenceContextRefs) {
@@ -246,6 +269,19 @@
         return deployment;
     }
 
+    public static boolean paramsMatch(Method methodA, Method methodB) {
+        if (methodA.getParameterTypes().length != methodB.getParameterTypes().length){
+            return false;
+        }
+
+        for (int i = 0; i < methodA.getParameterTypes().length; i++) {
+            Class<?> a = methodA.getParameterTypes()[i];
+            Class<?> b = methodB.getParameterTypes()[i];
+            if (!a.equals(b)) return false;
+        }
+        return true;
+    }
+
     public List<Exception> getWarnings() {
         return warnings;
     }
@@ -280,27 +316,33 @@
             if (TimedObject.class.isAssignableFrom(ejbClass)) {
                 timeout = TimedObject.class.getMethod("ejbTimeout", Timer.class);
             } else if (info.methodParams != null) {
-                List<Class> parameterTypes = new ArrayList<Class>();
-
-                for (String paramType : info.methodParams) {
-                    try {
-                        parameterTypes.add(Class.forName(paramType));
-                    } catch (ClassNotFoundException cnfe) {
-                        throw (IllegalStateException) new IllegalStateException("Parameter class could not be loaded for type " + paramType).initCause(cnfe);
-                    }
-                }
-
-                try {
-                    timeout = ejbClass.getMethod(info.methodName, parameterTypes.toArray(new Class[parameterTypes.size()]));
-                } catch (NoSuchMethodException e) {
-                    throw (IllegalStateException) new IllegalStateException("Timeout Callback method does not exist: " + ejbClass.getName() + "." + info.methodName).initCause(e);
-                }
+                timeout = toMethod(ejbClass, info);
             }
         } catch (Exception e) {
             warnings.add(e);
         }
 
         return timeout;
+    }
+
+    private Method toMethod(Class clazz, NamedMethodInfo info) {
+        Method method = null;
+        List<Class> parameterTypes = new ArrayList<Class>();
+
+        for (String paramType : info.methodParams) {
+            try {
+                parameterTypes.add(Class.forName(paramType));
+            } catch (ClassNotFoundException cnfe) {
+                throw new IllegalStateException("Parameter class could not be loaded for type " + paramType, cnfe);
+            }
+        }
+
+        try {
+            method = clazz.getMethod(info.methodName, parameterTypes.toArray(new Class[parameterTypes.size()]));
+        } catch (NoSuchMethodException e) {
+            throw new IllegalStateException("Callback method does not exist: " + clazz.getName() + "." + info.methodName, e);
+        }
+        return method;
     }
 
 

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InitMethodInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InitMethodInfo.java?view=auto&rev=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InitMethodInfo.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InitMethodInfo.java Tue Mar 13 05:07:19 2007
@@ -0,0 +1,25 @@
+/**
+ * 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.assembler.classic;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class InitMethodInfo extends InfoObject {
+    public NamedMethodInfo beanMethod;
+    public NamedMethodInfo createMethod;
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InterceptorBindingBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InterceptorBindingBuilder.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InterceptorBindingBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/InterceptorBindingBuilder.java Tue Mar 13 05:07:19 2007
@@ -38,6 +38,7 @@
 public class InterceptorBindingBuilder {
 
     public static final Logger logger = Logger.getInstance("OpenEJB.startup", InterceptorBindingBuilder.class.getPackage().getName());
+    private final List<InterceptorBindingInfo> packageAndClassBindings;
 
     public static enum Level {
         PACKAGE, CLASS, OVERLOADED_METHOD, EXACT_METHOD;
@@ -57,6 +58,14 @@
         Collections.sort(bindings, new IntercpetorBindingComparator());
         Collections.reverse(bindings);
 
+        packageAndClassBindings = new ArrayList<InterceptorBindingInfo>();
+        for (InterceptorBindingInfo binding : bindings) {
+            Level level = level(binding);
+            if (level == Level.PACKAGE || level == Level.CLASS){
+                packageAndClassBindings.add(binding);
+            }
+        }
+
         for (InterceptorInfo info : ejbJarInfo.interceptors) {
             Class clazz = null;
             try {
@@ -78,14 +87,28 @@
     private void toMethods(Class clazz, List<CallbackInfo> callbackInfos, List<Method> methods) {
         for (CallbackInfo callbackInfo : callbackInfos) {
             try {
-                Method method = clazz.getMethod(callbackInfo.method, InvocationContext.class);
+                Method method = getMethod(clazz, callbackInfo.method, InvocationContext.class);
                 methods.add(method);
             } catch (NoSuchMethodException e) {
-                logger.warning("Interceptor method not found (skipping): public void " + callbackInfo.method + "(InvocationContext); in class " + clazz.getName());
+                logger.warning("Interceptor method not found (skipping): public Object " + callbackInfo.method + "(InvocationContext); in class " + clazz.getName());
             }
         }
     }
 
+    private Method getMethod(Class clazz, String methodName, Class... parameterTypes) throws NoSuchMethodException {
+        NoSuchMethodException original = null;
+        while (clazz != null){
+            try {
+                Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
+                return SetAccessible.on(method);
+            } catch (NoSuchMethodException e) {
+                if (original == null) original = e;
+            }
+            clazz = clazz.getSuperclass();
+        }
+        throw original;
+    }
+
     private void toCallback(Class clazz, List<CallbackInfo> callbackInfos, List<Method> methods) {
         for (CallbackInfo callbackInfo : callbackInfos) {
             try {
@@ -97,6 +120,7 @@
         }
     }
 
+
     public void build(CoreDeploymentInfo deploymentInfo, EnterpriseBeanInfo beanInfo) {
         Class clazz = deploymentInfo.getBeanClass();
 
@@ -113,30 +137,43 @@
         }
 
         for (Method method : deploymentInfo.getBeanClass().getMethods()) {
-            List<InterceptorBindingInfo> methodBindings = processBindings(method, beanInfo.ejbName);
-            Collections.reverse(methodBindings);
-            List<InterceptorData> methodInterceptors = new ArrayList<InterceptorData>();
-
-            for (InterceptorBindingInfo info : methodBindings) {
-                List<String> classes = (info.interceptorOrder.size() > 0) ? info.interceptorOrder : info.interceptors;
-                for (String interceptorClassName : classes) {
-                    InterceptorData interceptorData = interceptors.get(interceptorClassName);
-                    if (interceptorData == null){
-                        logger.warning("InterceptorBinding references non-existent (undeclared) interceptor: " + interceptorClassName);
-                        continue;
-                    }
-                    methodInterceptors.add(interceptorData);
-                }
-            }
+            List<InterceptorData> methodInterceptors = createInterceptorDatas(method, beanInfo.ejbName, this.bindings);
 
             // The bean itself gets to intercept too and is always last.
             methodInterceptors.add(beanAsInterceptor);
 
             deploymentInfo.setMethodInterceptors(method, methodInterceptors);
         }
+
+        List<InterceptorData> callbackInterceptorDatas = createInterceptorDatas(null, beanInfo.ejbName, this.packageAndClassBindings);
+
+        // The bean itself gets to intercept too and is always last.
+        callbackInterceptorDatas.add(beanAsInterceptor);
+
+        deploymentInfo.setCallbackInterceptors(callbackInterceptorDatas);
+    }
+
+    private List<InterceptorData> createInterceptorDatas(Method method, String ejbName, List<InterceptorBindingInfo> bindings) {
+        List<InterceptorBindingInfo> methodBindings = processBindings(method, ejbName, bindings);
+        Collections.reverse(methodBindings);
+        List<InterceptorData> methodInterceptors = new ArrayList<InterceptorData>();
+
+        for (InterceptorBindingInfo info : methodBindings) {
+            List<String> classes = (info.interceptorOrder.size() > 0) ? info.interceptorOrder : info.interceptors;
+            for (String interceptorClassName : classes) {
+                InterceptorData interceptorData = interceptors.get(interceptorClassName);
+                if (interceptorData == null){
+                    logger.warning("InterceptorBinding references non-existent (undeclared) interceptor: " + interceptorClassName);
+                    continue;
+                }
+                methodInterceptors.add(interceptorData);
+            }
+        }
+        return methodInterceptors;
     }
 
-    private List<InterceptorBindingInfo> processBindings(Method method, String ejbName){
+
+    private List<InterceptorBindingInfo> processBindings(Method method, String ejbName, List<InterceptorBindingInfo> bindings){
         List<InterceptorBindingInfo> methodBindings = new ArrayList<InterceptorBindingInfo>();
 
         // The only critical thing to understand in this loop as that

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/RemoveMethodInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/RemoveMethodInfo.java?view=auto&rev=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/RemoveMethodInfo.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/RemoveMethodInfo.java Tue Mar 13 05:07:19 2007
@@ -0,0 +1,25 @@
+/**
+ * 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.assembler.classic;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class RemoveMethodInfo extends InfoObject {
+    public NamedMethodInfo beanMethod;
+    public boolean retainIfException;
+}

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/SetAccessible.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/SetAccessible.java?view=auto&rev=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/SetAccessible.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/SetAccessible.java Tue Mar 13 05:07:19 2007
@@ -0,0 +1,41 @@
+/**
+ * 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.assembler.classic;
+
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.lang.reflect.AccessibleObject;
+
+/**
+ * @version $Rev$ $Date$
+ */
+class SetAccessible implements PrivilegedAction {
+    private final java.lang.reflect.AccessibleObject object;
+
+    public SetAccessible(AccessibleObject object) {
+        this.object = object;
+    }
+
+    public Object run() {
+        object.setAccessible(true);
+        return object;
+    }
+
+    public static <T extends AccessibleObject> T on(T object){
+        return (T) AccessController.doPrivileged(new SetAccessible(object));
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/StatefulBeanInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/StatefulBeanInfo.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/StatefulBeanInfo.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/StatefulBeanInfo.java Tue Mar 13 05:07:19 2007
@@ -28,4 +28,7 @@
     public final List<CallbackInfo> postActivate = new ArrayList<CallbackInfo>();
     public final List<CallbackInfo> prePassivate = new ArrayList<CallbackInfo>();
 
+    public final List<InitMethodInfo> initMethods = new ArrayList<InitMethodInfo>();
+    public final List<RemoveMethodInfo> removeMethods = new ArrayList<RemoveMethodInfo>();
+
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java Tue Mar 13 05:07:19 2007
@@ -43,6 +43,8 @@
 import javax.ejb.TransactionAttributeType;
 import javax.ejb.TransactionManagement;
 import javax.ejb.TransactionManagementType;
+import javax.ejb.Init;
+import javax.ejb.Remove;
 import javax.persistence.PersistenceContext;
 import javax.persistence.PersistenceContexts;
 import javax.persistence.PersistenceProperty;
@@ -323,7 +325,15 @@
                         if (remoteHome != null) {
                             Class<?> homeClass = remoteHome.value();
                             try {
-                                Method create = homeClass.getMethod("create");
+                                Method create = null;
+                                for (Method method : homeClass.getMethods()) {
+                                    if (method.getName().startsWith("create")){
+                                        create = method;
+                                        break;
+                                    }
+                                }
+                                if (create == null) throw new NoSuchMethodException("create");
+
                                 Class<?> remoteClass = create.getReturnType();
                                 remoteBean.setHome(homeClass.getName());
                                 remoteBean.setRemote(remoteClass.getName());
@@ -338,10 +348,18 @@
                         if (localHome != null) {
                             Class<?> homeClass = localHome.value();
                             try {
-                                Method create = homeClass.getMethod("create");
+                                Method create = null;
+                                for (Method method : homeClass.getMethods()) {
+                                    if (method.getName().startsWith("create")){
+                                        create = method;
+                                        break;
+                                    }
+                                }
+                                if (create == null) throw new NoSuchMethodException("create");
+
                                 Class<?> remoteClass = create.getReturnType();
-                                remoteBean.setHome(homeClass.getName());
-                                remoteBean.setRemote(remoteClass.getName());
+                                remoteBean.setLocalHome(homeClass.getName());
+                                remoteBean.setLocal(remoteClass.getName());
                             } catch (NoSuchMethodException e) {
                                 logger.error("Class annotated as a LocalHome has no 'create()' method.  Unable to determine remote interface type.  Bean class: " + clazz.getName() + ",  Home class: " + homeClass.getName());
                             }
@@ -537,6 +555,23 @@
                 if (prePassivate == null) {
                     Method method = getFirst(classFinder.findAnnotatedMethods(PrePassivate.class));
                     if (method != null) session.addPrePassivate(method.getName());
+                }
+
+                List<Method> initMethods = classFinder.findAnnotatedMethods(Init.class);
+                for (Method method : initMethods) {
+                    InitMethod initMethod = new InitMethod(method);
+
+                    Init init = method.getAnnotation(Init.class);
+                    if (init.value() != null && !init.value().equals("")){
+                        initMethod.setCreateMethod(init.value());
+                    }
+
+                    session.getInitMethod().add(initMethod);
+                }
+
+                List<Method> removeMethods = classFinder.findAnnotatedMethods(Remove.class);
+                for (Method method : removeMethods) {
+                    session.getRemoveMethod().add(new RemoveMethod(method));
                 }
             }
         }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java Tue Mar 13 05:07:19 2007
@@ -65,7 +65,7 @@
 import org.apache.openejb.config.sys.ServiceProvider;
 import org.apache.openejb.config.sys.TransactionManager;
 import org.apache.openejb.config.sys.Resource;
-import org.apache.openejb.jee.ApplicationClient;
+import org.apache.openejb.jee.*;
 import org.apache.openejb.jee.jpa.EntityMappings;
 import org.apache.openejb.jee.jpa.JpaJaxbUtil;
 import org.apache.openejb.jee.jpa.unit.Persistence;
@@ -119,10 +119,13 @@
         Chain chain = new Chain();
 
         chain.add(new ReadDescriptors());
-        
+
         chain.add(new AnnotationDeployer());
 
         chain.add(new InitEjbDeployments());
+
+//        chain.add(new DebuggableVmHackery());
+
         chain.add(new CmpJpaConversion());
         chain.add(new OpenEjb2CmpConversion());
         chain.add(new SunConversion());

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/DebuggableVmHackery.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/DebuggableVmHackery.java?view=auto&rev=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/DebuggableVmHackery.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/DebuggableVmHackery.java Tue Mar 13 05:07:19 2007
@@ -0,0 +1,129 @@
+/**
+ * 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.config;
+
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.jee.oejb3.OpenejbJar;
+import org.apache.openejb.jee.oejb3.EjbDeployment;
+import org.apache.openejb.jee.oejb3.ResourceLink;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.MessageDrivenBean;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.EntityBean;
+import org.apache.openejb.jee.AssemblyDescriptor;
+import org.apache.openejb.jee.MethodPermission;
+import org.apache.openejb.jee.Method;
+import org.apache.openejb.jee.ContainerTransaction;
+import org.apache.openejb.jee.InterceptorBinding;
+import org.apache.openejb.jee.ResourceEnvRef;
+import org.apache.openejb.jee.MessageDestinationRef;
+import org.apache.openejb.jee.ResourceRef;
+import org.apache.openejb.jee.PersistenceContextRef;
+
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+class DebuggableVmHackery implements DynamicDeployer {
+
+    public AppModule deploy(AppModule appModule) throws OpenEJBException {
+        for (EjbModule ejbModule : appModule.getEjbModules()) {
+            EjbJar ejbJar = ejbModule.getEjbJar();
+            OpenejbJar openejbJar = ejbModule.getOpenejbJar();
+            Map<String, EjbDeployment> deployments = openejbJar.getDeploymentsByEjbName();
+
+            ejbJar.setRelationships(null);
+
+            for (EnterpriseBean bean : ejbJar.getEnterpriseBeans()) {
+
+                String ejbName = bean.getEjbName();
+                EjbDeployment ejbDeployment = deployments.get(ejbName);
+
+
+                for (ResourceRef ref : copy(bean.getResourceRef())) {
+                    if (ref.getResType().startsWith("javax.jms.")){
+                        ResourceLink resourceLink = ejbDeployment.getResourceLink(ref.getName());
+                        ejbDeployment.getResourceLink().remove(resourceLink);
+                        bean.getResourceRef().remove(ref);
+                    }
+                }
+
+                for (ResourceEnvRef ref : bean.getResourceEnvRef()) {
+                    ResourceLink resourceLink = ejbDeployment.getResourceLink(ref.getName());
+                    ejbDeployment.getResourceLink().remove(resourceLink);
+                }
+                bean.getResourceEnvRef().clear();
+
+                for (MessageDestinationRef ref : bean.getMessageDestinationRef()) {
+                    ResourceLink resourceLink = ejbDeployment.getResourceLink(ref.getName());
+                    ejbDeployment.getResourceLink().remove(resourceLink);
+                }
+                bean.getMessageDestinationRef().clear();
+
+                bean.getPersistenceContextRef().clear();
+                bean.getPersistenceUnitRef().clear();
+
+
+                if (!(bean instanceof MessageDrivenBean) && !(bean instanceof EntityBean)) {
+                    continue;
+                }
+
+                ejbJar.removeEnterpriseBean(ejbName);
+                openejbJar.removeEjbDeployment(ejbDeployment);
+
+                AssemblyDescriptor assemblyDescriptor = ejbJar.getAssemblyDescriptor();
+                if (assemblyDescriptor != null){
+                    for (MethodPermission permission : copy(assemblyDescriptor.getMethodPermission())) {
+                        for (Method method : copy(permission.getMethod())) {
+                            if (method.getEjbName().equals(ejbName)) {
+                                permission.getMethod().remove(method);
+                            }
+                        }
+                        if (permission.getMethod().size() == 0) {
+                            assemblyDescriptor.getMethodPermission().remove(permission);
+                        }
+                    }
+
+                    for (ContainerTransaction transaction : copy(assemblyDescriptor.getContainerTransaction())) {
+                        for (Method method : copy(transaction.getMethod())) {
+                            if (method.getEjbName().equals(ejbName)) {
+                                transaction.getMethod().remove(method);
+                            }
+                        }
+                        if (transaction.getMethod().size() == 0) {
+                            assemblyDescriptor.getContainerTransaction().remove(transaction);
+                        }
+                    }
+
+                    for (InterceptorBinding binding : copy(assemblyDescriptor.getInterceptorBinding())) {
+                        if (binding.getEjbName().equals(ejbName)) {
+                            assemblyDescriptor.getInterceptorBinding().remove(binding);
+                        }
+                    }
+                }
+            }
+        }
+        return appModule;
+    }
+
+    public <T> List<T> copy(List<T> list) {
+        return new ArrayList(list);
+    }
+}

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java Tue Mar 13 05:07:19 2007
@@ -346,8 +346,25 @@
 
         if (s.getSessionType() == SessionType.STATEFUL) {
             bean = new StatefulBeanInfo();
-            copyCallbacks(s.getPostActivate(), ((StatefulBeanInfo) bean).postActivate);
-            copyCallbacks(s.getPrePassivate(), ((StatefulBeanInfo) bean).prePassivate);
+            StatefulBeanInfo stateful = ((StatefulBeanInfo) bean);
+
+            copyCallbacks(s.getPostActivate(), stateful.postActivate);
+            copyCallbacks(s.getPrePassivate(), stateful.prePassivate);
+
+            for (InitMethod initMethod : s.getInitMethod()) {
+                InitMethodInfo init = new InitMethodInfo();
+                init.beanMethod = toInfo(initMethod.getBeanMethod());
+                init.createMethod = toInfo(initMethod.getCreateMethod());
+                stateful.initMethods.add(init);
+            }
+
+            for (RemoveMethod removeMethod : s.getRemoveMethod()) {
+                RemoveMethodInfo remove = new RemoveMethodInfo();
+                remove.beanMethod = toInfo(removeMethod.getBeanMethod());
+                remove.retainIfException = removeMethod.getRetainIfException();
+                stateful.removeMethods.add(remove);
+            }
+
         } else {
             bean = new StatelessBeanInfo();
         }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java Tue Mar 13 05:07:19 2007
@@ -86,10 +86,15 @@
     private Class mdbInterface;
     private Class serviceEndpointInterface;
 
-    private Method postConstruct;
-    private Method preDestroy;
-    private Method prePassivate;
-    private Method postActivate;
+    private final List<Method> aroundInvoke = new ArrayList<Method>();
+
+    private final List<Method> postConstruct = new ArrayList<Method>();
+    private final List<Method> preDestroy = new ArrayList<Method>();
+
+    private final List<Method> postActivate = new ArrayList<Method>();
+    private final List<Method> prePassivate = new ArrayList<Method>();
+
+    private final List<Method> removeMethods = new ArrayList<Method>();
 
     private Method ejbTimeout;
     private EjbTimerService ejbTimerService;
@@ -117,6 +122,7 @@
     private final Map<Method, Byte> methodTransactionAttributes = new HashMap<Method, Byte>();
     private final Map<Method, TransactionPolicy> methodTransactionPolicies = new HashMap<Method, TransactionPolicy>();
     private final Map<Method, List<InterceptorData>> methodInterceptors = new HashMap<Method, List<InterceptorData>>();
+    private final List<InterceptorData> callbackInterceptors = new ArrayList<InterceptorData>();
     private final Map<Method, Method> methodMap = new HashMap<Method, Method>();
     private final Map<String, List<String>> securityRoleReferenceMap = new HashMap<String, List<String>>();
     private String jarPath;
@@ -171,24 +177,8 @@
 //            this.homeInterface = BusinessRemoteHome.class;
 //        }
 
-        if (SessionBean.class.isAssignableFrom(beanClass)){
-            try {
-                this.preDestroy = SessionBean.class.getMethod("ejbRemove");
-                this.prePassivate = SessionBean.class.getMethod("ejbPassivate");
-                this.postActivate = SessionBean.class.getMethod("ejbActivate");
-            } catch (NoSuchMethodException e) {
-                throw new IllegalStateException(e);
-            }
-        }
         createMethodMap();
 
-        if (EnterpriseBean.class.isAssignableFrom(beanClass)){
-            try {
-                preDestroy = beanClass.getMethod("ejbRemove");
-            } catch (NoSuchMethodException e) {
-                throw new SystemException(e);
-            }
-        }
         if (TimedObject.class.isAssignableFrom(beanClass)) {
             try {
                 this.ejbTimeout = beanClass.getMethod("ejbTimeout", Timer.class);
@@ -205,13 +195,6 @@
         this.activationProperties.putAll(activationProperties);
         this.componentType = BeanType.MESSAGE_DRIVEN;
 
-        if (MessageDrivenBean.class.isAssignableFrom(beanClass)){
-            try {
-                this.preDestroy = beanClass.getMethod("ejbRemove");
-            } catch (NoSuchMethodException e) {
-                throw new IllegalStateException(e);
-            }
-        }
         if (TimedObject.class.isAssignableFrom(beanClass)) {
             try {
                 this.ejbTimeout = beanClass.getMethod("ejbTimeout");
@@ -550,6 +533,30 @@
         methodTransactionPolicies.put(method, policy);
     }
 
+    public List<Method> getAroundInvoke() {
+        return aroundInvoke;
+    }
+
+    public List<Method> getPostConstruct() {
+        return postConstruct;
+    }
+
+    public List<Method> getPreDestroy() {
+        return preDestroy;
+    }
+
+    public List<Method> getPostActivate() {
+        return postActivate;
+    }
+
+    public List<Method> getPrePassivate() {
+        return prePassivate;
+    }
+
+    public List<Method> getRemoveMethods() {
+        return removeMethods;
+    }
+
     public List<InterceptorData> getMethodInterceptors(Method method) {
         return methodInterceptors.get(method);
     }
@@ -566,6 +573,16 @@
         return interceptors;
     }
 
+    public List<InterceptorData> getCallbackInterceptors() {
+        return callbackInterceptors;
+    }
+
+    public void setCallbackInterceptors(List<InterceptorData> callbackInterceptors) {
+        this.callbackInterceptors.clear();
+        this.callbackInterceptors.addAll(callbackInterceptors);
+        this.interceptors.addAll(callbackInterceptors);
+    }
+
     private javax.ejb.EJBHome createEJBHomeRef() {
 
         EjbHomeProxyHandler handler = null;
@@ -694,11 +711,6 @@
             } catch (NoSuchMethodException e) {
                 // if there isn't an ejbCreate method that is fine
             }
-            try {
-                preDestroy = MessageDrivenBean.class.getDeclaredMethod("ejbRemove");
-            } catch (NoSuchMethodException e) {
-                // this won't happen
-            }
         }
 
         try {
@@ -778,6 +790,10 @@
         }
     }
 
+    public void mapMethods(Method interfaceMethod, Method beanMethod){
+        methodMap.put(interfaceMethod, beanMethod);
+    }
+
     private void mapObjectInterface(Class intrface) {
         if (intrface == BusinessLocalHome.class || intrface == BusinessRemoteHome.class){
             return;
@@ -825,39 +841,6 @@
 
     public Method getCreateMethod() {
         return createMethod;
-    }
-
-    public Method getPostActivate() {
-        return postActivate;
-    }
-
-    public void setPostActivate(Method postActivate) {
-        this.postActivate = postActivate;
-    }
-
-    public Method getPostConstruct() {
-        // TODO: Need to truly enforce the backwards compatibility rules
-        return (postConstruct == null)? getCreateMethod(): postConstruct;
-    }
-
-    public void setPostConstruct(Method postConstruct) {
-        this.postConstruct = postConstruct;
-    }
-
-    public Method getPreDestroy() {
-        return preDestroy;
-    }
-
-    public void setPreDestroy(Method preDestroy) {
-        this.preDestroy = preDestroy;
-    }
-
-    public Method getPrePassivate() {
-        return prePassivate;
-    }
-
-    public void setPrePassivate(Method prePassivate) {
-        this.prePassivate = prePassivate;
     }
 
     public Method getMatchingPostCreateMethod(Method createMethod) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/Operation.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/Operation.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/Operation.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/Operation.java Tue Mar 13 05:07:19 2007
@@ -18,6 +18,7 @@
 
 public enum Operation {
     INJECTION,
+    POST_CONSTRUCT,
     BUSINESS,
     BUSINESS_WS,
     TIMEOUT,

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorData.java Tue Mar 13 05:07:19 2007
@@ -70,7 +70,7 @@
     public List<Method> getMethods(Operation operation) {
         switch(operation) {
             case BUSINESS: return getAroundInvoke();
-            case CREATE: return getPostConstruct();
+            case POST_CONSTRUCT: return getPostConstruct();
             case REMOVE: return getPreDestroy();
             case ACTIVATE: return getPostActivate();
             case PASSIVATE: return getPrePassivate();

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorStack.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorStack.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorStack.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/interceptor/InterceptorStack.java Tue Mar 13 05:07:19 2007
@@ -35,6 +35,8 @@
     private final Method targetMethod;
 
     public InterceptorStack(Object beanInstance, Method targetMethod, Operation operation, List<InterceptorData> interceptorDatas, Map<String, Object> interceptorInstances) {
+        if (interceptorDatas == null) throw new NullPointerException("interceptorDatas is null");
+        if (interceptorInstances == null) throw new NullPointerException("interceptorInstances is null");
         this.beanInstance = beanInstance;
         this.targetMethod = targetMethod;
 

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/mdb/MdbInstanceFactory.java Tue Mar 13 05:07:19 2007
@@ -20,19 +20,26 @@
 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.spi.SecurityService;
 import org.apache.openejb.Injection;
 import org.apache.openejb.util.Logger;
 import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Option;
 import org.apache.xbean.recipe.StaticRecipe;
+import org.apache.xbean.recipe.ConstructionException;
 
 import javax.ejb.MessageDrivenBean;
+import javax.ejb.SessionBean;
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.resource.spi.UnavailableException;
 import javax.transaction.TransactionManager;
 import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
 
 /**
  * A MdbInstanceFactory creates instances of message driven beans for a single instance. This class differs from other
@@ -132,10 +139,15 @@
         try {
             // call post destroy method
             callContext.setCurrentOperation(Operation.REMOVE);
-            Method preDestroy = callContext.getDeploymentInfo().getPreDestroy();
-            if (preDestroy != null){
-                preDestroy.invoke(bean);
-            }
+
+            Method remove = bean instanceof MessageDrivenBean ? MessageDrivenBean.class.getMethod("ejbRemove"): null;
+
+            List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+            ArrayList interceptorDatas = new ArrayList(); // TODO
+            HashMap interceptorInstances = new HashMap(); // TODO
+            InterceptorStack interceptorStack = new InterceptorStack(bean, remove, Operation.REMOVE, interceptorDatas, interceptorInstances);
+
+            interceptorStack.invoke();
         } catch (Throwable re) {
             MdbInstanceFactory.logger.error("The bean instance " + bean + " threw a system exception:" + re, re);
         } finally {
@@ -197,13 +209,43 @@
             }
             Object bean = objectRecipe.create();
 
-            // call the post construct method
-            Method postConstruct = deploymentInfo.getPostConstruct();
-            if (postConstruct != null){
-                callContext.setCurrentOperation(Operation.CREATE);
-                postConstruct.invoke(bean);
+            HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
+            for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+                if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
+
+                Class clazz = interceptorData.getInterceptorClass();
+                ObjectRecipe interceptorRecipe = new ObjectRecipe(clazz);
+                try {
+                    Object interceptorInstance = interceptorRecipe.create(clazz.getClassLoader());
+                    interceptorInstances.put(clazz.getName(), interceptorInstance);
+                } catch (ConstructionException e) {
+                    throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
+                }
             }
 
+            // TODO: We need to keep these somehwere
+            interceptorInstances.put(beanClass.getName(), bean);
+
+            try {
+                callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
+
+                List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+                InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
+                interceptorStack.invoke();
+            } catch (Exception e) {
+                throw e;
+            }
+
+            try {
+                if (bean instanceof MessageDrivenBean){
+                    callContext.setCurrentOperation(Operation.CREATE);
+                    Method create = deploymentInfo.getCreateMethod();
+                    InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList(), new HashMap());
+                    interceptorStack.invoke();
+                }
+            } catch (Exception e) {
+                throw e;
+            }
 
             return bean;
         } catch (Throwable e) {

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Tue Mar 13 05:07:19 2007
@@ -94,8 +94,8 @@
     private Map<Method, MethodType> getLifecycelMethodsOfInterface(CoreDeploymentInfo deploymentInfo) {
         Map<Method, MethodType> methods = new HashMap<Method, MethodType>();
 
-        Method preDestroy = deploymentInfo.getPreDestroy();
-        if (preDestroy != null) {
+        List<Method> preDestroys = deploymentInfo.getPreDestroy();
+        for (Method preDestroy : preDestroys) {
             methods.put(preDestroy, MethodType.REMOVE);
 
             Class businessLocal = deploymentInfo.getBusinessLocalInterface();
@@ -264,30 +264,21 @@
             Index<EntityManagerFactory, EntityManager> entityManagers = createEntityManagers(deploymentInfo);
 
             // allocate a new instance
-            Object bean = instanceManager.newInstance(primaryKey, deploymentInfo.getBeanClass());
-            instanceManager.setEntityManagers(primaryKey, entityManagers);
+            Object o = instanceManager.newInstance(primaryKey, deploymentInfo.getBeanClass());
+            StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) o;
 
+            instanceManager.setEntityManagers(primaryKey, entityManagers);
 
-            StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) bean;
+            if (!callMethod.getDeclaringClass().equals(DeploymentInfo.BusinessLocalHome.class) && !callMethod.getDeclaringClass().equals(DeploymentInfo.BusinessRemoteHome.class)){
 
-            // Invoke postConstructs or create(...)
-            if (instance.bean instanceof SessionBean) {
-                Method runMethod = deploymentInfo.getMatchingBeanMethod(callMethod);
+                Method createOrInit = deploymentInfo.getMatchingBeanMethod(callMethod);
 
-                List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(runMethod);
-                InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, Operation.CREATE, interceptors, instance.interceptors);
+                InterceptorStack interceptorStack = new InterceptorStack(instance.bean, createOrInit, Operation.CREATE, new ArrayList(), new HashMap());
 
-                _invoke(callMethod, interceptorStack, args, bean, createContext);
-            } else {
-                Method postConstruct = deploymentInfo.getPostConstruct();
-                if (postConstruct != null) {
-                    List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(postConstruct);
-                    InterceptorStack interceptorStack = new InterceptorStack(instance.bean, null, Operation.CREATE, interceptors, instance.interceptors);
-                    _invoke(callMethod, interceptorStack, null, bean, createContext);
-                }
+                _invoke(callMethod, interceptorStack, args, instance, createContext);
             }
 
-            instanceManager.poolInstance(primaryKey, bean);
+            instanceManager.poolInstance(primaryKey, instance);
 
             Class callingClass = callMethod.getDeclaringClass();
             Class objectInterface = deploymentInfo.getObjectInterface(callingClass);
@@ -307,24 +298,21 @@
         try {
             checkAuthorization(deploymentInfo, callMethod, securityIdentity);
             try {
-                Object bean = instanceManager.obtainInstance(primKey, callContext);
-                if (bean != null) {
+                StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) instanceManager.obtainInstance(primKey, callContext);
+                if (instance != null) {
                     callContext.setCurrentOperation(Operation.REMOVE);
-                    Method preDestroy = callContext.getDeploymentInfo().getPreDestroy();
-                    if (preDestroy != null) {
-                        StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) bean;
-                        List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(preDestroy);
-
-                        InterceptorStack interceptorStack;
-                        if (SessionBean.class.isAssignableFrom(deploymentInfo.getBeanClass())){
-                            interceptorStack = new InterceptorStack(instance.bean, preDestroy, Operation.REMOVE, interceptors, instance.interceptors);
-                        } else {
-                            // The preDestroy will already be in the stack
-                            interceptorStack = new InterceptorStack(instance.bean, null, Operation.REMOVE, interceptors, instance.interceptors);
-                        }
 
-                        _invoke(callMethod, interceptorStack, null, bean, callContext);
+                    Method remove = null;
+
+                    try {
+                        remove = instance.bean instanceof SessionBean ? SessionBean.class.getMethod("ejbRemove"): null;
+                    } catch (NoSuchMethodException neverHappen) {
                     }
+
+                    List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+                    InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.REMOVE, callbackInterceptors, instance.interceptors);
+
+                    _invoke(callMethod, interceptorStack, new Object[]{}, instance, callContext);
                 }
             } finally {
                 // todo destroy extended persistence contexts

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContext.java Tue Mar 13 05:07:19 2007
@@ -60,6 +60,7 @@
         states[Operation.BEFORE_COMPLETION.ordinal()] = new BeforeCompletion();
         states[Operation.AFTER_COMPLETION.ordinal()] = new AfterCompletion();
         states[Operation.TIMEOUT.ordinal()] = new TimeoutStatelessState();
+        states[Operation.REMOVE.ordinal()] = new LifecycleStatelessState();
     }
 
     /**

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java Tue Mar 13 05:07:19 2007
@@ -47,7 +47,6 @@
 import javax.persistence.EntityManagerFactory;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.rmi.NoSuchObjectException;
 import java.rmi.RemoteException;
@@ -180,6 +179,12 @@
 
             interceptorInstances.put(beanClass.getName(), bean);
 
+            callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
+
+            List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+            InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
+            interceptorStack.invoke();
+            
             bean = new Instance(bean, interceptorInstances);
 
         } catch (Throwable callbackException) {
@@ -279,25 +284,15 @@
         callContext.setCurrentOperation(Operation.ACTIVATE);
         try {
             CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-            Method postActivate = deploymentInfo.getPostActivate();
-            if (postActivate != null) {
-                try {
-                    StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) entry.bean;
-                    List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(postActivate);
 
-                    InterceptorStack interceptorStack;
-                    if (SessionBean.class.isAssignableFrom(deploymentInfo.getBeanClass())){
-                        interceptorStack = new InterceptorStack(instance.bean, postActivate, Operation.ACTIVATE, interceptors, instance.interceptors);
-                    } else {
-                        // The preDestroy will already be in the stack
-                        interceptorStack = new InterceptorStack(instance.bean, null, Operation.ACTIVATE, interceptors, instance.interceptors);
-                    }
+            StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) entry.bean;
+            Method remove = instance.bean instanceof SessionBean? SessionBean.class.getMethod("ejbActivate"): null;
+
+            List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+            InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.ACTIVATE, callbackInterceptors, instance.interceptors);
+
+            interceptorStack.invoke();
 
-                    interceptorStack.invoke();
-                } catch (InvocationTargetException e) {
-                    throw e.getTargetException();
-                }
-            }
         } catch (Throwable callbackException) {
             /*
             In the event of an exception, OpenEJB is required to log the exception, evict the instance,
@@ -320,16 +315,16 @@
     protected void handleTimeout(BeanEntry entry, ThreadContext threadContext) {
         Operation currentOperation = threadContext.getCurrentOperation();
         threadContext.setCurrentOperation(Operation.REMOVE);
+        CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
+        Instance instance = (Instance) entry.bean;
 
         try {
-            Method preDestroy = threadContext.getDeploymentInfo().getPreDestroy();
-            if (preDestroy != null) {
-                try {
-                    preDestroy.invoke(entry.bean);
-                } catch (InvocationTargetException e) {
-                    throw e.getTargetException();
-                }
-            }
+            Method remove = instance.bean instanceof SessionBean? SessionBean.class.getMethod("ejbRemove"): null;
+
+            List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+            InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.REMOVE, callbackInterceptors, instance.interceptors);
+
+            interceptorStack.invoke();
         } catch (Throwable callbackException) {
             /*
               Exceptions are processed "quietly"; they are not reported to the client since
@@ -401,7 +396,6 @@
         BeanEntry currentEntry;
         final Operation currentOperation = threadContext.getCurrentOperation();
         CoreDeploymentInfo deploymentInfo = threadContext.getDeploymentInfo();
-        Method prePassivate = deploymentInfo.getPrePassivate();
         try {
             for (int i = 0; i < bulkPassivationSize; ++i) {
                 currentEntry = lruQueue.first();
@@ -414,25 +408,15 @@
                 } else {
                     threadContext.setCurrentOperation(Operation.PASSIVATE);
                     try {
-                        if (prePassivate != null) {
-                            // TODO Are all beans in the stateTable the same type?
-                            try {
-                                StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) currentEntry.bean;
-                                List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(prePassivate);
-
-                                InterceptorStack interceptorStack;
-                                if (SessionBean.class.isAssignableFrom(deploymentInfo.getBeanClass())){
-                                    interceptorStack = new InterceptorStack(instance.bean, prePassivate, Operation.PASSIVATE, interceptors, instance.interceptors);
-                                } else {
-                                    // The preDestroy will already be in the stack
-                                    interceptorStack = new InterceptorStack(instance.bean, null, Operation.PASSIVATE, interceptors, instance.interceptors);
-                                }
-
-                                interceptorStack.invoke();
-                            } catch (InvocationTargetException e) {
-                                throw e.getTargetException();
-                            }
-                        }
+                        StatefulInstanceManager.Instance instance = (StatefulInstanceManager.Instance) currentEntry.bean;
+
+                        Method passivate = instance.bean instanceof SessionBean? SessionBean.class.getMethod("ejbPassivate"): null;
+
+                        List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+                        InterceptorStack interceptorStack = new InterceptorStack(instance.bean, passivate, Operation.PASSIVATE, callbackInterceptors, instance.interceptors);
+
+                        interceptorStack.invoke();
+
                     } catch (Throwable e) {
 
                         String logMessage = "An unexpected exception occured while invoking the ejbPassivate method on the Stateful SessionBean instance; " + e.getClass().getName() + " " + e.getMessage();

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContext.java Tue Mar 13 05:07:19 2007
@@ -64,6 +64,7 @@
         states[Operation.BUSINESS.ordinal()] = new BusinessStatelessState();
         states[Operation.BUSINESS_WS.ordinal()] = new BusinessWsStatelessState();
         states[Operation.TIMEOUT.ordinal()] = new TimeoutStatelessState();
+        states[Operation.REMOVE.ordinal()] = new LifecycleStatelessState();
     }
 
 }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Tue Mar 13 05:07:19 2007
@@ -44,6 +44,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.ArrayList;
 
 public class StatelessInstanceManager {
     private static final Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.util.resources");
@@ -157,18 +158,28 @@
 
                 interceptorInstances.put(beanClass.getName(), bean);
 
-                callContext.setCurrentOperation(Operation.CREATE);
 
-                Method postConstruct = deploymentInfo.getPostConstruct();
+                try {
+                    callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
 
-                if (postConstruct != null) {
-                    List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(postConstruct);
-                    if (!SessionBean.class.isAssignableFrom(beanClass)) {
-                        postConstruct = null;
-                    }
-                    InterceptorStack interceptorStack = new InterceptorStack(bean, postConstruct, Operation.CREATE, interceptors, interceptorInstances);
+                    List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+                    InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
                     interceptorStack.invoke();
+                } catch (Exception e) {
+                    throw e;
+                }
+
+                try {
+                    if (bean instanceof SessionBean){
+                        callContext.setCurrentOperation(Operation.CREATE);
+                        Method create = deploymentInfo.getCreateMethod();
+                        InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList(), new HashMap());
+                        interceptorStack.invoke();
+                    }
+                } catch (Exception e) {
+                    throw e;
                 }
+
                 bean = new Instance(bean, interceptorInstances);
             } catch (Throwable e) {
                 if (e instanceof java.lang.reflect.InvocationTargetException) {
@@ -211,29 +222,26 @@
             poolQueue.notifyWaitingThreads();
         } else {
             if (pool.size() >= poolLimit) {
-                freeInstance(callContext, bean);
+                freeInstance(callContext, (Instance)bean);
             } else {
                 pool.push(bean);
             }
         }
     }
 
-    public void freeInstance(ThreadContext callContext, Object bean) {
+    private void freeInstance(ThreadContext callContext, Instance instance) {
         try {
             callContext.setCurrentOperation(Operation.REMOVE);
             CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-            Method preDestroy = deploymentInfo.getPreDestroy();
-            if (preDestroy != null) {
-                List<InterceptorData> interceptors = deploymentInfo.getMethodInterceptors(preDestroy);
-                if (!SessionBean.class.isAssignableFrom(deploymentInfo.getBeanClass())) {
-                    preDestroy = null;
-                }
-                InterceptorStack interceptorStack = new InterceptorStack(((Instance) bean).bean, preDestroy, Operation.REMOVE, interceptors, ((Instance) bean).interceptors);
-                interceptorStack.invoke();
-                preDestroy.invoke(bean);
-            }
+
+            Method remove = instance.bean instanceof SessionBean? deploymentInfo.getCreateMethod(): null;
+
+            List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+            InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.REMOVE, callbackInterceptors, instance.interceptors);
+
+            interceptorStack.invoke();
         } catch (Throwable re) {
-            logger.error("The bean instance " + bean + " threw a system exception:" + re, re);
+            logger.error("The bean instance " + instance + " threw a system exception:" + re, re);
         }
 
     }

Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java?view=diff&rev=517657&r1=517656&r2=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/assembler/classic/RedeployTest.java Tue Mar 13 05:07:19 2007
@@ -17,17 +17,17 @@
 package org.apache.openejb.assembler.classic;
 
 import junit.framework.TestCase;
+import org.apache.openejb.client.LocalInitialContextFactory;
 import org.apache.openejb.config.ConfigurationFactory;
 import org.apache.openejb.config.sys.Connector;
 import org.apache.openejb.config.sys.Resource;
-import org.apache.openejb.client.LocalInitialContextFactory;
-import org.apache.openejb.test.stateful.AnnotatedFieldInjectionStatefulBean;
-import org.apache.openejb.test.stateless.EncStatelessHome;
-import org.apache.openejb.test.stateless.EncStatelessObject;
 import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.test.stateful.AnnotatedFieldInjectionStatefulBean;
+import org.apache.openejb.test.stateful.EncStatefulHome;
+import org.apache.openejb.test.stateful.EncStatefulObject;
 
-import javax.naming.InitialContext;
 import javax.naming.Context;
+import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import java.io.File;
 import java.util.Properties;
@@ -90,8 +90,8 @@
         Properties properties = new Properties();
         properties.put(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
         InitialContext ctx = new InitialContext(properties);
-        EncStatelessHome home = (EncStatelessHome) ctx.lookup(AnnotatedFieldInjectionStatefulBean.class.getSimpleName());
-        EncStatelessObject ejbObject = home.create();
+        EncStatefulHome home = (EncStatefulHome) ctx.lookup(AnnotatedFieldInjectionStatefulBean.class.getSimpleName());
+        EncStatefulObject ejbObject = home.create("foo");
         ejbObject.lookupStringEntry();
 
         assembler.destroyApplication(file.getAbsolutePath());

Added: incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/Compat3to2Test.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/Compat3to2Test.java?view=auto&rev=517657
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/Compat3to2Test.java (added)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/Compat3to2Test.java Tue Mar 13 05:07:19 2007
@@ -0,0 +1,171 @@
+/**
+ * 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.stateful;
+
+import junit.framework.TestCase;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.ConnectionManagerInfo;
+import org.apache.openejb.assembler.classic.StatefulSessionContainerInfo;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatefulBean;
+
+import javax.naming.InitialContext;
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.ejb.CreateException;
+import javax.ejb.EJBException;
+import javax.ejb.EJBHome;
+import javax.ejb.EJBObject;
+import javax.ejb.PostActivate;
+import javax.ejb.PrePassivate;
+import javax.ejb.Init;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.rmi.RemoteException;
+import java.io.Serializable;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Compat3to2Test extends TestCase {
+
+    public void test() throws Exception {
+        System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, InitContextFactory.class.getName());
+
+        ConfigurationFactory config = new ConfigurationFactory();
+        Assembler assembler = new Assembler();
+
+        assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+        assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+        assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+        assembler.createConnectionManager(config.configureService(ConnectionManagerInfo.class));
+
+        // containers
+        StatefulSessionContainerInfo statefulContainerInfo = config.configureService(StatefulSessionContainerInfo.class);
+        statefulContainerInfo.properties.setProperty("PoolSize", "0");
+        statefulContainerInfo.properties.setProperty("BulkPassivate", "1");
+        assembler.createContainer(statefulContainerInfo);
+
+        assembler.createApplication(config.configureApplication(buildTestApp()));
+
+        calls.clear();
+
+        InitialContext ctx = new InitialContext();
+        TargetHome home = (TargetHome) ctx.lookup("TargetBean");
+        assertNotNull(home);
+
+        Target target = home.create("Fuzz");
+        assertNotNull(target);
+
+        String name = target.getName();
+        assertEquals("Fuzz", name);
+
+        target.remove();
+
+        assertCalls(Call.values());
+
+    }
+
+    private void assertCalls(Call... expectedCalls) {
+        List expected = Arrays.asList(expectedCalls);
+        assertEquals(join("\n", expected), join("\n", calls));
+    }
+
+    public EjbModule buildTestApp() {
+        EjbJar ejbJar = new EjbJar();
+
+        StatefulBean bean = ejbJar.addEnterpriseBean(new StatefulBean(TargetBean.class));
+        bean.setHomeAndRemote(TargetHome.class, Target.class);
+
+        return new EjbModule(this.getClass().getClassLoader(), this.getClass().getSimpleName(), "test", ejbJar, null);
+    }
+
+    public static List<Call> calls = new ArrayList<Call>();
+
+    public static enum Call {
+        Constructor, PostConstruct, EjbCreate, EjbPassivate1, EjbActivate1, BusinessMethod, EjbPassivate2, EjbActivate2, EjbRemove
+    }
+
+    public static class TargetBean implements Serializable {
+
+        private int activates = 0;
+        private int passivates = 0;
+
+        private String name;
+
+        public TargetBean() {
+            calls.add(Call.Constructor);
+        }
+
+        @PostConstruct
+        public void construct() {
+            calls.add(Call.PostConstruct);
+        }
+
+        @Init
+        public void beanCreate(String name) throws CreateException {
+            calls.add(Call.EjbCreate);
+            this.name = name;
+        }
+
+        public String getName() {
+            calls.add(Call.BusinessMethod);
+            return name;
+        }
+
+        @PostActivate
+        public void beanActivate() throws EJBException, RemoteException {
+            calls.add((Call) Enum.valueOf(Call.class, "EjbActivate" + (++activates)));
+        }
+
+        @PrePassivate
+        public void beanPassivate() throws EJBException, RemoteException {
+            calls.add((Call) Enum.valueOf(Call.class, "EjbPassivate" + (++passivates)));
+        }
+
+        @PreDestroy
+        public void beanRemove() throws EJBException, RemoteException {
+            calls.add(Call.EjbRemove);
+        }
+    }
+
+    public static interface TargetHome extends EJBHome {
+        Target create(String name) throws RemoteException, CreateException;
+    }
+
+    public static interface Target extends EJBObject {
+        String getName();
+    }
+
+    private String join(String delimeter, List items) {
+        StringBuffer sb = new StringBuffer();
+        for (Object item : items) {
+            sb.append(item.toString()).append(delimeter);
+        }
+        return sb.toString();
+    }
+}