dain 2005/01/26 18:28:01
Modified: modules/core/src/java/org/openejb/mdb MDBContainer.java
MDBInstanceContext.java MDBInstanceFactory.java
MDBInterceptorBuilder.java
Log:
ENC is now passed around as a Map instead of a jndi Context. This allows the
ejb container to modify it and inject the kernel and class loader into
references.
Changed Stateless and MDB containers to use system chain for ejbCreate and
ejbRemove invocations.
Added test to verify that ejbRemove is propertly called from the cache code.
Revision Changes Path
1.21 +31 -7
openejb/modules/core/src/java/org/openejb/mdb/MDBContainer.java
Index: MDBContainer.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBContainer.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- MDBContainer.java 24 Jan 2005 21:16:48 -0000 1.20
+++ MDBContainer.java 26 Jan 2005 23:28:00 -0000 1.21
@@ -50,9 +50,10 @@
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
-
import javax.management.ObjectName;
+import javax.naming.Context;
import javax.resource.spi.UnavailableException;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.spi.endpoint.MessageEndpointFactory;
@@ -65,15 +66,18 @@
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
import org.apache.geronimo.kernel.Kernel;
-import org.apache.geronimo.timer.ThreadPooledTimer;
+import org.apache.geronimo.naming.java.SimpleReadOnlyContext;
+import org.apache.geronimo.naming.reference.ClassLoaderAwareReference;
+import org.apache.geronimo.naming.reference.KernelAwareReference;
import org.apache.geronimo.timer.PersistenceException;
+import org.apache.geronimo.timer.ThreadPooledTimer;
import org.apache.geronimo.transaction.TrackedConnectionAssociator;
import org.apache.geronimo.transaction.UserTransactionImpl;
import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.apache.geronimo.transaction.manager.WrapperNamedXAResource;
import org.apache.geronimo.transaction.manager.NamedXAResource;
-import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
+import org.apache.geronimo.transaction.manager.WrapperNamedXAResource;
import org.openejb.TwoChains;
import org.openejb.cache.InstancePool;
import org.openejb.dispatch.InterfaceMethodSignature;
@@ -102,8 +106,10 @@
String endpointInterfaceName,
InterfaceMethodSignature[] signatures,
boolean[] deliveryTransacted,
- MDBInstanceContextFactory contextFactory, MDBInterceptorBuilder
interceptorBuilder,
- InstancePool instancePool, UserTransactionImpl userTransaction,
+ MDBInstanceContextFactory contextFactory,
+ MDBInterceptorBuilder interceptorBuilder,
+ InstancePool instancePool,
+ Map componentContext, UserTransactionImpl userTransaction,
ActivationSpecWrapper activationSpecWrapper,
TransactionContextManager transactionContextManager,
TrackedConnectionAssociator trackedConnectionAssociator,
@@ -133,6 +139,22 @@
Class endpointInterface =
classLoader.loadClass(endpointInterfaceName);
endpointFactory = new EndpointFactory(this, endpointInterface,
classLoader);
+ // create ReadOnlyContext
+ Context enc = null;
+ if (componentContext != null) {
+ for (Iterator iterator = componentContext.values().iterator();
iterator.hasNext();) {
+ Object value = iterator.next();
+ if (value instanceof KernelAwareReference) {
+ ((KernelAwareReference) value).setKernel(kernel);
+ }
+ if (value instanceof ClassLoaderAwareReference) {
+ ((ClassLoaderAwareReference)
value).setClassLoader(classLoader);
+ }
+ }
+ enc = new SimpleReadOnlyContext(componentContext);
+ }
+ interceptorBuilder.setComponentContext(enc);
+
// build the interceptor chain
interceptorBuilder.setInstancePool(instancePool);
interceptorBuilder.setTrackedConnectionAssociator(trackedConnectionAssociator);
@@ -256,6 +278,7 @@
infoFactory.addAttribute("contextFactory",
MDBInstanceContextFactory.class, true);
infoFactory.addAttribute("interceptorBuilder",
MDBInterceptorBuilder.class, true);
infoFactory.addAttribute("instancePool", InstancePool.class, true);
+ infoFactory.addAttribute("componentContext", Map.class, true);
infoFactory.addAttribute("userTransaction",
UserTransactionImpl.class, true);
infoFactory.addAttribute("classLoader", ClassLoader.class, false);
@@ -276,6 +299,7 @@
"contextFactory",
"interceptorBuilder",
"instancePool",
+ "componentContext",
"userTransaction",
"ActivationSpecWrapper",
"TransactionContextManager",
1.9 +16 -1
openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceContext.java
Index: MDBInstanceContext.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceContext.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- MDBInstanceContext.java 5 Oct 2004 07:04:01 -0000 1.8
+++ MDBInstanceContext.java 26 Jan 2005 23:28:00 -0000 1.9
@@ -56,6 +56,7 @@
import org.apache.geronimo.transaction.context.TransactionContextManager;
import org.openejb.AbstractInstanceContext;
import org.openejb.EJBOperation;
+import org.openejb.EJBInvocation;
import org.openejb.dispatch.SystemMethodIndices;
import org.openejb.timer.BasicTimerService;
@@ -67,11 +68,15 @@
public final class MDBInstanceContext extends AbstractInstanceContext {
private final Object containerId;
private final MDBContext mdbContext;
+ private final EJBInvocation ejbCreateInvocation;
+ private final EJBInvocation ejbRemoveInvocation;
public MDBInstanceContext(Object containerId, MessageDrivenBean
instance, TransactionContextManager transactionContextManager,
UserTransactionImpl userTransaction, SystemMethodIndices systemMethodIndices,
Interceptor systemChain, Set unshareableResources, Set
applicationManagedSecurityResources, BasicTimerService timerService) {
super(systemMethodIndices, systemChain, unshareableResources,
applicationManagedSecurityResources, instance, null, timerService);
this.containerId = containerId;
this.mdbContext = new MDBContext(this, transactionContextManager,
userTransaction);
+ ejbCreateInvocation =
systemMethodIndices.getEJBCreateInvocation(this);
+ ejbRemoveInvocation =
systemMethodIndices.getEJBRemoveInvocation(this);
setContextInvocation =
systemMethodIndices.getSetContextInvocation(this, mdbContext);
unsetContextInvocation =
systemMethodIndices.getSetContextInvocation(this, null);
}
@@ -98,5 +103,15 @@
public void setOperation(EJBOperation operation) {
mdbContext.setState(operation);
+ }
+
+ public void ejbCreate() throws Throwable {
+ assert(getInstance() != null);
+ systemChain.invoke(ejbCreateInvocation);
+ }
+
+ public void ejbRemove() throws Throwable {
+ assert(getInstance() != null);
+ systemChain.invoke(ejbRemoveInvocation);
}
}
1.7 +16 -71
openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceFactory.java
Index: MDBInstanceFactory.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceFactory.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- MDBInstanceFactory.java 7 Jul 2004 22:17:34 -0000 1.6
+++ MDBInstanceFactory.java 26 Jan 2005 23:28:00 -0000 1.7
@@ -48,15 +48,9 @@
package org.openejb.mdb;
import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import javax.ejb.MessageDrivenBean;
-import net.sf.cglib.reflect.FastClass;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.naming.java.ReadOnlyContext;
-import org.apache.geronimo.naming.java.RootContext;
-import org.openejb.EJBOperation;
import org.openejb.cache.InstanceFactory;
/**
@@ -65,91 +59,42 @@
public class MDBInstanceFactory implements InstanceFactory, Serializable {
private static final Log log =
LogFactory.getLog(MDBInstanceFactory.class);
- private final ReadOnlyContext componentContext;
private final MDBInstanceContextFactory factory;
- private final Class beanClass;
- private transient final int createIndex;
- private transient final FastClass implClass;
-
- public MDBInstanceFactory(ReadOnlyContext componentContext,
MDBInstanceContextFactory factory, Class beanClass) {
- this.componentContext = componentContext;
+ public MDBInstanceFactory(MDBInstanceContextFactory factory) {
this.factory = factory;
- this.beanClass = beanClass;
-
- implClass = FastClass.create(beanClass);
- createIndex = implClass.getIndex("ejbCreate", new Class[0]);
}
public Object createInstance() throws Exception {
- ReadOnlyContext oldContext = RootContext.getComponentContext();
-
try {
- // Disassociate from JNDI Component Context whilst creating
instance
- RootContext.setComponentContext(null);
-
- // create the StatelessInstanceContext which contains the
instance
MDBInstanceContext ctx = (MDBInstanceContext)
factory.newInstance();
-
- try {
- ctx.setContext();
- } catch (Throwable t) {
- //TODO check this error handling
- if (t instanceof Exception) {
- throw (Exception) t;
- } else {
- throw (Error) t;
- }
- }
- MessageDrivenBean instance = (MessageDrivenBean)
ctx.getInstance();
- assert(instance != null);
-
- // Activate this components JNDI Component Context
- RootContext.setComponentContext(componentContext);
-
- //TODO make ejbcreate go through the stack also!
- ctx.setOperation(EJBOperation.EJBCREATE);
- try {
- implClass.invoke(createIndex, instance, null);
- } catch (InvocationTargetException ite) {
- Throwable t = ite.getTargetException();
- if (t instanceof Exception) {
- throw (Exception) t;
- } else {
- throw (Error) t;
- }
- } finally {
- ctx.setOperation(EJBOperation.INACTIVE);
- }
-
+ ctx.setContext();
+ ctx.ejbCreate();
return ctx;
- } finally {
- RootContext.setComponentContext(oldContext);
+ } catch (Throwable t) {
+ if (t instanceof Exception) {
+ throw (Exception) t;
+ } else if (t instanceof Error) {
+ throw (Error) t;
+ } else {
+ throw new Error("Unexpected throwable", t);
+ }
}
}
public void destroyInstance(Object instance) {
- MDBInstanceContext ctx = (MDBInstanceContext) instance;
- MessageDrivenBean beanInstance = (MessageDrivenBean)
ctx.getInstance();
-
- ctx.setOperation(EJBOperation.EJBREMOVE);
-
// Activate this components JNDI Component Context
- ReadOnlyContext oldContext = RootContext.getComponentContext();
- RootContext.setComponentContext(componentContext);
try {
- beanInstance.ejbRemove();
+ MDBInstanceContext ctx = (MDBInstanceContext) instance;
+ ctx.ejbRemove();
} catch (Throwable t) {
// We're destroying this instance, so just log and continue
log.warn("Unexpected error removing Message Driven instance", t);
- } finally {
- ctx.setOperation(EJBOperation.INACTIVE);
- RootContext.setComponentContext(oldContext);
}
- //TODO shouldn't we call setMessageDrivenContext(null);
+ // No should not we call setMessageDrivenContext(null);
}
private Object readResolve() {
- return new MDBInstanceFactory(componentContext, factory, beanClass);
+ return new MDBInstanceFactory(factory);
}
}
1.5 +4 -5
openejb/modules/core/src/java/org/openejb/mdb/MDBInterceptorBuilder.java
Index: MDBInterceptorBuilder.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBInterceptorBuilder.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- MDBInterceptorBuilder.java 27 Jul 2004 02:26:42 -0000 1.4
+++ MDBInterceptorBuilder.java 26 Jan 2005 23:28:00 -0000 1.5
@@ -49,10 +49,10 @@
import java.io.Serializable;
import javax.security.auth.Subject;
+import javax.naming.Context;
import org.apache.geronimo.core.service.Interceptor;
import org.apache.geronimo.naming.java.ComponentContextInterceptor;
-import org.apache.geronimo.naming.java.ReadOnlyContext;
import org.apache.geronimo.transaction.TrackedConnectionAssociator;
import org.openejb.ConnectionTrackingInterceptor;
import org.openejb.SystemExceptionInterceptor;
@@ -61,7 +61,6 @@
import org.openejb.dispatch.DispatchInterceptor;
import org.openejb.dispatch.VirtualOperation;
import org.openejb.security.EJBIdentityInterceptor;
-import org.openejb.security.EJBRunAsInterceptor;
/**
* @version $Revision$ $Date$
@@ -70,7 +69,7 @@
private String ejbName;
private VirtualOperation[] vtable;
private Subject runAs;
- private ReadOnlyContext componentContext;
+ private Context componentContext;
private boolean doAsCurrentCaller = false;
private transient TrackedConnectionAssociator
trackedConnectionAssociator;
private transient InstancePool instancePool;
@@ -89,7 +88,7 @@
this.runAs = runAs;
}
- public void setComponentContext(ReadOnlyContext componentContext) {
+ public void setComponentContext(Context componentContext) {
assert (componentContext != null) : "componentContext is null";
this.componentContext = componentContext;
}