StatefulSessionContainerpublic final class StatefulSessionContainer extends BaseContainer implements com.sun.ejb.spi.sfsb.initialization.SFSBContainerInitialization, com.sun.ejb.spi.stats.StatefulSessionBeanStatsProvider, com.sun.ejb.spi.container.SFSBContainerCallback, com.sun.appserv.util.cache.CacheListenerThis class provides container functionality specific to stateful
SessionBeans.
At deployment time, one instance of the StatefulSessionContainer is created
for each stateful SessionBean type (i.e. deployment descriptor) in a JAR.
The 5 states of a Stateful EJB (an EJB can be in only 1 state at a time):
1. PASSIVE : has been passivated
2. READY : ready for invocations, no transaction in progress
3. INVOKING : processing an invocation
4. INCOMPLETE_TX : ready for invocations, transaction in progress
5. DESTROYED : does not exist |
Fields Summary |
---|
private static final Logger | _logger | static final int | PASSIVE | static final int | READY | static final int | INVOKING | static final int | INCOMPLETE_TX | static final int | DESTROYED | public static final int | MIN_PASSIVATION_BATCH_COUNT | private long | instanceCount | protected ArrayList | passivationCandidates | private Object | asyncTaskSemaphore | private int | asyncTaskCount | private int | asyncCummTaskCount | private int | passivationBatchCount | private int | containerTrimCount | private com.sun.ejb.containers.util.cache.LruSessionCache | sessionBeanCache | private com.sun.ejb.spi.sfsb.store.SFSBStoreManager | sfsbStoreManager | private com.sun.ejb.spi.sfsb.util.SFSBUUIDUtil | uuidGenerator | private ArrayList | scheduledTimerTasks | protected int | statMethodReadyCount | private Level | TRACE_LEVEL | private String | ejbName | private com.sun.ejb.spi.sfsb.util.CheckpointPolicy | checkpointPolicy | private int | removalGracePeriodInSeconds | private com.sun.ejb.base.stats.StatefulSessionStoreMonitor | sfsbStoreMonitor | private final String | traceInfoPrefix | private static Map | extendedEMReferenceCountMap | private static Map | eemKey2EEMMap |
Constructors Summary |
---|
public StatefulSessionContainer(EjbDescriptor desc, ClassLoader loader)This constructor is called from the JarManager when a Jar is deployed.
super(desc, loader);
super.createCallFlowAgent(ComponentType.SFSB);
this.ejbName = desc.getName();
this.traceInfoPrefix = "sfsb-" + ejbName + ": ";
|
Methods Summary |
---|
public ComponentContext | _getContext(Invocation inv)Called from preInvoke which is called from the EJBObject
for local and remote invocations.
EJBLocalRemoteObject ejbo = inv.ejbObject;
SessionContextImpl sc = ejbo.getContext();
Object sessionKey = ejbo.getKey();
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Trying to get context");
}
if (sc == null) {
// This is possible if the EJB was destroyed or passivated.
// Try to activate it again.
sc = (SessionContextImpl) sessionBeanCache.lookupEJB(
sessionKey, this, ejbo);
}
if ((sc == null) || (sc.getState()==DESTROYED)) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Context already destroyed");
}
// EJB2.0 section 7.6
throw new NoSuchObjectLocalException("The EJB does not exist."
+ " session-key: " + sessionKey);
}
SessionContextImpl context = null;
synchronized (sc) {
SessionContextImpl newSC = sc;
if ( sc.getState() == PASSIVE ) {
// This is possible if the EJB was passivated after
// the last lookupEJB. Try to activate it again.
newSC = (SessionContextImpl) sessionBeanCache.lookupEJB(
sessionKey, this, ejbo);
if (newSC == null) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Context does not exist");
}
// EJB2.0 section 7.6
throw new NoSuchObjectLocalException(
"The EJB does not exist. key: " + sessionKey);
}
}
// acquire the lock again, in case a new sc was returned.
synchronized (newSC) { //newSC could be same as sc
// Check & set the state of the EJB
if (newSC.getState()==DESTROYED ) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Got destroyed context");
}
throw new NoSuchObjectLocalException
("The EJB does not exist. session-key: " + sessionKey);
} else if (newSC.getState() == INVOKING ) {
handleConcurrentInvocation(inv, sessionKey);
}
if (newSC.getState() == READY) {
decrementMethodReadyStat();
}
if (checkpointPolicy.isHAEnabled()) {
doVersionCheck(inv, sessionKey, sc);
}
newSC.setState(INVOKING);
context = newSC;
}
}
// touch the context here so timestamp is set & timeout is prevented
context.touch();
if ((context.existsInStore()) && (removalGracePeriodInSeconds > 0)) {
long now = System.currentTimeMillis();
long threshold = now - (removalGracePeriodInSeconds * 1000);
if (context.getLastPersistedAt() <= threshold) {
try {
sfsbStoreManager.updateLastAccessTime(sessionKey, now);
context.setLastPersistedAt(System.currentTimeMillis());
} catch (SFSBStoreManagerException sfsbEx) {
_logger.log(Level.WARNING,
"Couldn't update timestamp for: " + sessionKey
+ "; Exception: " + sfsbEx);
_logger.log(Level.FINE,
"Couldn't update timestamp for: " + sessionKey, sfsbEx);
}
}
}
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, context, "Got Context!!");
}
return context;
| private SessionContextImpl | _getContextForInstance(byte[] instanceKey)Called when a remote invocation arrives for an EJB.
Object sessionKey = uuidGenerator.byteArrayToKey(instanceKey, 0, -1);
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, "[SFSBContainer] Got request for: "
+ sessionKey);
}
while (true) {
SessionContextImpl sc = (SessionContextImpl)
sessionBeanCache.lookupEJB(sessionKey, this, null);
if ( sc == null ) {
// EJB2.0 section 7.6
// Note: the NoSuchObjectLocalException gets converted to a
// remote exception by the protocol manager.
throw new NoSuchObjectLocalException(
"Invalid Session Key ( " + sessionKey + ")");
}
synchronized (sc) {
switch (sc.getState()) {
case PASSIVE: //Next cache.lookup() == different_ctx
case DESTROYED: //Next cache.lookup() == null
break;
default:
return sc;
}
}
}
| public void | activateEJB(java.lang.Object sessionKey, com.sun.ejb.spi.container.StatefulEJBContext sfsbCtx, java.lang.Object cookie)
SessionContextImpl context = (SessionContextImpl)
sfsbCtx.getSessionContext();
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(context, "Attempting to activate");
}
EJBLocalRemoteObject ejbObject = (EJBLocalRemoteObject) cookie;
Object ejb = context.getEJB();
ComponentInvocation ci = new ComponentInvocation(ejb, this, context);
invocationManager.preInvoke(ci);
try {
// we're sure that no concurrent thread can be using this bean
// so no need to synchronize.
// No need to call enlistComponentResources here because
// ejbActivate executes in unspecified tx context (spec 6.6.1)
// Set the timestamp here, else Recycler might remove this bean!
context.touch();
context.setContainer(this);
context.setState(READY);
incrementMethodReadyStat();
context.setInstanceKey(sessionKey);
context.setExistsInStore(true);
if ( ejbObject == null ) {
// This MUST be a remote invocation
if( hasRemoteHomeView ) {
createEJBObjectImpl(context);
} else {
createRemoteBusinessObjectImpl(context);
}
}
else if ( ejbObject instanceof EJBObjectImpl ) {
EJBObjectImpl eo = (EJBObjectImpl) ejbObject;
ejbObject.setContext(context);
ejbObject.setKey(sessionKey);
byte[] sessionOID = uuidGenerator.keyToByteArray(sessionKey);
if( eo.isRemoteHomeView() ) {
// introduce context and EJBObject to each other
context.setEJBObjectImpl(eo);
EJBObject ejbStub = (EJBObject)
remoteHomeRefFactory.createRemoteReference
(sessionOID);
eo.setStub(ejbStub);
context.setEJBStub(ejbStub);
if( hasRemoteBusinessView ) {
createRemoteBusinessObjectImpl(context);
}
} else {
context.setEJBRemoteBusinessObjectImpl(eo);
for(RemoteBusinessIntfInfo next :
remoteBusinessIntfInfo.values()) {
java.rmi.Remote stub = next.referenceFactory
.createRemoteReference(sessionOID);
eo.setStub(next.generatedRemoteIntf.getName(), stub);
}
if( hasRemoteHomeView ) {
createEJBObjectImpl(context);
}
}
if ( isLocal ) { // create localObj too
if( hasLocalHomeView ) {
createEJBLocalObjectImpl(context);
}
if( hasLocalBusinessView ) {
createEJBLocalBusinessObjectImpl(context);
}
}
}
else if ( ejbObject instanceof EJBLocalObjectImpl ) {
EJBLocalObjectImpl elo = (EJBLocalObjectImpl) ejbObject;
ejbObject.setContext(context);
ejbObject.setKey(sessionKey);
if( elo.isLocalHomeView() ) {
context.setEJBLocalObjectImpl(elo);
if( hasLocalBusinessView ) {
createEJBLocalBusinessObjectImpl(context);
}
} else {
context.setEJBLocalBusinessObjectImpl(elo);
if( hasLocalHomeView ) {
createEJBLocalObjectImpl(context);
}
}
if ( hasRemoteHomeView ) { // create remote obj too
createEJBObjectImpl(context);
}
if ( hasRemoteBusinessView ) {
createRemoteBusinessObjectImpl(context);
}
}
//Now populate the EEM maps in this context
repopulateEEMMapsInContext(sessionKey, context);
try {
interceptorManager.intercept(
CallbackType.POST_ACTIVATE, context);
} catch (Throwable th) {
EJBException ejbEx = new EJBException("Error during activation"
+ sessionKey);
ejbEx.initCause(th);
throw ejbEx;
}
long now = System.currentTimeMillis();
try {
sfsbStoreManager.updateLastAccessTime(sessionKey, now);
context.setLastPersistedAt(now);
} catch (SFSBStoreManagerException sfsbEx) {
_logger.log(Level.WARNING,
"Couldn't update timestamp for: " + sessionKey
+ ";Exception: " + sfsbEx);
_logger.log(Level.FINE,
"Couldn't update timestamp for: " + sessionKey, sfsbEx);
}
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(context, "Successfully activated");
}
_logger.log(Level.FINE, "Activated: " + sessionKey);
}
catch ( Exception ex ) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(context, "Failed to activate");
}
_logger.log(Level.SEVERE, "ejb.sfsb_activation_error",
new Object[] { sessionKey });
_logger.log(Level.SEVERE, "sfsb activation error. Key: "
+ sessionKey, ex);
throw new EJBException("Unable to activate EJB for key: "
+ sessionKey, ex);
}
finally {
invocationManager.postInvoke(ci);
}
| void | afterBegin(EJBContextImpl context)
// TX_BEAN_MANAGED EJBs cannot implement SessionSynchronization
if ( isBeanManagedTran )
return;
// Note: this is only called for business methods.
// For SessionBeans non-business methods are never called with a Tx.
Object ejb = context.getEJB();
if ( ejb instanceof SessionSynchronization ) {
SessionSynchronization sync = (SessionSynchronization)ejb;
try {
sync.afterBegin();
} catch ( Exception ex ) {
// Error during afterBegin, so discard bean: EJB2.0 18.3.3
forceDestroyBean(context);
throw new EJBException("Error during SessionSynchronization." +
".afterBegin(), EJB instance discarded",
ex);
}
}
//Register CMT Beans for end of Tx Checkpointing
//Note:- We will never reach here for TX_BEAN_MANAGED
if (checkpointPolicy.isHAEnabled()) {
ContainerSynchronization cSync = null;
try {
cSync = containerFactory.
getContainerSync(context.getTransaction());
cSync.registerForTxCheckpoint(
(SessionContextImpl) context);
} catch (javax.transaction.RollbackException rollEx) {
_logger.log(Level.WARNING, "Cannot register bean for "
+ "checkpointing", rollEx);
} catch (javax.transaction.SystemException sysEx) {
_logger.log(Level.WARNING, "Cannot register bean for "
+ "checkpointing", sysEx);
}
}
| void | afterCompletion(EJBContextImpl context, int status)
if (context.getState() == DESTROYED) {
return;
}
SessionContextImpl sc = (SessionContextImpl)context;
Object ejb = sc.getEJB();
boolean committed = (status == Status.STATUS_COMMITTED)
|| (status == Status.STATUS_NO_TRANSACTION);
sc.setTransaction(null);
// SessionSync calls on TX_BEAN_MANAGED SessionBeans
// are not allowed.
if ( !isBeanManagedTran && (ejb instanceof SessionSynchronization) ) {
// Check for a concurrent invocation
// because afterCompletion can be called asynchronously
// during rollback because of transaction timeout
if ((sc.getState() == INVOKING) && (!sc.isTxCompleting())) {
// Cant invoke ejb.afterCompletion now because there is
// already some invocation in progress on the ejb.
sc.setAfterCompletionDelayed(true);
sc.setCompletedTxStatus(committed);
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(sc, "AfterCompletion delayed");
}
return;
}
callEjbAfterCompletion(sc, committed);
}
//callEjbAfterCompletion can set state as DESTROYED
if (sc.getState() != DESTROYED) {
if (checkpointPolicy.isHAEnabled()) {
if (isBeanManagedTran) {
sc.setTxCheckpointDelayed(true);
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(sc, "(BMT)Checkpoint delayed");
}
}
} else {
if (! isBeanManagedTran) {
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(sc, "Released context");
}
sc.setState(READY);
incrementMethodReadyStat();
}
}
}
| private void | afterInstanceCreation(SessionContextImpl context)
context.setState(READY);
Invocation i = null;
try {
// Need to do preInvoke because setSessionContext can access JNDI
i = new Invocation(context.getEJB(), this);
i.context = context;
invocationManager.preInvoke(i);
// PostConstruct must be called after state set to something
// other than NOT_INITIALIZED
interceptorManager.intercept(CallbackType.POST_CONSTRUCT, context);
} catch(Throwable t) {
EJBException ejbEx = new EJBException();
ejbEx.initCause(t);
throw ejbEx;
} finally {
if ( i != null ) {
invocationManager.postInvoke(i);
}
}
statCreateCount++;
incrementMethodReadyStat();
| public void | appendStats(java.lang.StringBuffer sbuf)
sbuf.append("\nStatefulContainer: ")
.append("CreateCount=").append(statCreateCount).append("; ")
.append("RemoveCount=").append(statRemoveCount).append("; ")
.append("Size=")
.append(sessionBeanCache.getNumBeansInCache()).append("; ")
.append("ReadyCount=")
.append(statMethodReadyCount).append("; ");
sbuf.append("]");
| void | beforeCompletion(EJBContextImpl context)
// SessionSync calls on TX_BEAN_MANAGED SessionBeans
// are not allowed
if ( isBeanManagedTran )
return;
Object ejb = context.getEJB();
if ( !(ejb instanceof SessionSynchronization) )
return;
// No need to check for a concurrent invocation
// because beforeCompletion can only be called after
// all business methods are completed.
Invocation inv = new Invocation(ejb, this);
inv.context = context;
invocationManager.preInvoke(inv);
try {
transactionManager.enlistComponentResources();
((SessionSynchronization)ejb).beforeCompletion();
} catch ( Exception ex ) {
// Error during beforeCompletion, so discard bean: EJB2.0 18.3.3
try {
forceDestroyBean(context);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
throw new EJBException("Error during SessionSynchronization." +
"beforeCompletion, EJB instance discarded",
ex);
} finally {
invocationManager.postInvoke(inv);
}
| private void | callEjbAfterCompletion(SessionContextImpl context, boolean status)
Object ejb = context.getEJB();
ComponentInvocation ci = new ComponentInvocation(ejb, this, context);
invocationManager.preInvoke(ci);
try {
context.setInAfterCompletion(true);
((SessionSynchronization)ejb).afterCompletion(status);
// reset flags
context.setAfterCompletionDelayed(false);
context.setTxCompleting(false);
}
catch (Exception ex) {
// Error during afterCompletion, so discard bean: EJB2.0 18.3.3
try {
forceDestroyBean(context);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error removing bean", e);
}
_logger.log(Level.INFO, "ejb.aftercompletion_exception",ex);
// No use throwing an exception here, since the tx has already
// completed, and afterCompletion may be called asynchronously
// when there is no client to receive the exception.
}
finally {
context.setInAfterCompletion(false);
invocationManager.postInvoke(ci);
}
| public final boolean | canPassivateEJB(ComponentContext context)
SessionContextImpl sc = (SessionContextImpl)context;
return (sc.getState() == READY);
| void | checkExists(EJBLocalRemoteObject ejbObj)Check if the given EJBObject/LocalObject has been removed.
if ( ejbObj.isRemoved() )
throw new NoSuchObjectLocalException("Bean has been removed");
| private boolean | checkpointEJB(SessionContextImpl sc)
boolean checkpointed = false;
try {
if ((containerState != CONTAINER_STARTED) && (containerState != CONTAINER_STOPPED)) {
_logger.log(Level.FINE, "passivateEJB() returning because "
+ "containerState: " + containerState);
return false;
}
if (sc.getState() == DESTROYED) {
return false;
}
Object ejb = sc.getEJB();
long checkpointStartTime = -1;
if (sfsbStoreMonitor.isMonitoringOn()) {
checkpointStartTime = System.currentTimeMillis();
}
ComponentInvocation ci = new ComponentInvocation(ejb, this, sc);
invocationManager.preInvoke(ci);
synchronized (sc) {
try {
// dont passivate if there is a Tx/invocation in progress
// for this instance.
if (sc.getState() != READY) {
return false;
}
// passivate the EJB
sc.setState(PASSIVE);
decrementMethodReadyStat();
interceptorManager.intercept(
CallbackType.PRE_PASSIVATE, sc);
sc.setLastPersistedAt(System.currentTimeMillis());
byte[] serializedState = null;
try {
long newCtxVersion = sc.incrementAndGetVersion();
serializedState = IOUtils.serializeObject(sc, true);
SFSBBeanState beanState =
sfsbStoreManager.createSFSBBeanState(
sc.getInstanceKey(), sc.getLastAccessTime(),
!sc.existsInStore(), serializedState);
beanState.setVersion(newCtxVersion);
sfsbStoreManager.checkpointSave(beanState);
//Now that we have successfully stored.....
sc.setLastPersistedAt(System.currentTimeMillis());
sc.setExistsInStore(true);
checkpointed = true;
} catch (EMNotSerializableException emNotSerEx) {
_logger.log(Level.WARNING,
"Error during checkpoint(, but session not destroyed)", emNotSerEx);
} catch (NotSerializableException notSerEx) {
throw notSerEx;
} catch (Exception ignorableEx) {
_logger.log(Level.WARNING,
"Error during checkpoint", ignorableEx);
}
interceptorManager.intercept(
CallbackType.POST_ACTIVATE, sc);
sc.setState(READY);
incrementMethodReadyStat();
sfsbStoreMonitor.setCheckpointSize(serializedState.length);
sfsbStoreMonitor.incrementCheckpointCount(true);
} catch (Throwable ex) {
sfsbStoreMonitor.incrementCheckpointCount(false);
_logger.log(Level.WARNING, "ejb.sfsb_checkpoint_error",
new Object[] { ejbDescriptor.getName() });
_logger.log(Level.WARNING, "sfsb checkpoint error. Key: "
+ sc.getInstanceKey(), ex);
try {
forceDestroyBean(sc);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
} finally {
invocationManager.postInvoke(ci);
if (checkpointStartTime != -1) {
long timeSpent = System.currentTimeMillis()
- checkpointStartTime;
sfsbStoreMonitor.setCheckpointTime(timeSpent);
}
}
} //synchronized
} catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.sfsb_passivation_error",
new Object[] { ejbDescriptor.getName() });
_logger.log(Level.WARNING, "sfsb passivation error", ex);
}
return checkpointed;
| private static final java.lang.String | convertCtxStateToString(SessionContextImpl sc)
switch (sc.getState()) {
case PASSIVE: return "PASSIVE";
case READY: return "READY";
case INVOKING: return "INVOKING";
case INCOMPLETE_TX: return "INCOMPLETE_TX";
case DESTROYED: return "DESTROYED";
}
return "UNKNOWN-STATE";
| private SessionContextImpl | createBeanInstance()Create a new Session Bean and set Session Context.
Invocation i=null;
try {
// create new (stateful) EJB
Object ejb = ejbClass.newInstance();
// create SessionContext and set it in the EJB
SessionContextImpl context = new SessionContextImpl(ejb, this);
context.setInterceptorInstances(
interceptorManager.createInterceptorInstances());
Object sessionKey = uuidGenerator.createSessionKey();
createExtendedEMs(context, sessionKey);
// Need to do preInvoke because setSessionContext can access JNDI
i = new Invocation(ejb, this);
i.context = context;
invocationManager.preInvoke(i);
// setSessionContext will be called without a Tx as required
// by the spec, because the EJBHome.create would have been called
// after the container suspended any client Tx.
// setSessionContext is also called before createEJBObject because
// the bean is not allowed to do EJBContext.getEJBObject here
if( ejb instanceof SessionBean ) {
((SessionBean)ejb).setSessionContext(context);
}
// Perform injection right after where setSessionContext
// would be called. This is important since injection methods
// have the same "operations allowed" permissions as
// setSessionContext.
injectionManager.injectInstance(ejb, ejbDescriptor, false);
for (Object interceptorInstance : context.getInterceptorInstances()) {
injectionManager.injectInstance(interceptorInstance,
ejbDescriptor, false);
}
// Set the timestamp before inserting into bean store, else
// Recycler might go crazy and remove this bean!
context.touch();
// Add the EJB into the session store
// and get the instanceKey for this EJB instance.
// XXX The store operation could be avoided for local-only beans.
sessionBeanCache.put(sessionKey, context);
context.setInstanceKey(sessionKey);
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, "[SFSBContainer] Created "
+ "session: " + sessionKey);
}
return context;
} catch (Exception ex) {
throw ex;
} catch (Throwable t) {
EJBException ejbEx = new EJBException();
ejbEx.initCause(t);
throw ejbEx;
} finally {
if ( i != null ) {
invocationManager.postInvoke(i);
}
}
| EJBLocalObjectImpl | createEJBLocalBusinessObjectImpl()Internal creation event for Local Business view of SFSB
try {
SessionContextImpl context = createBeanInstance();
EJBLocalObjectImpl localBusinessObjImpl =
createEJBLocalBusinessObjectImpl(context);
afterInstanceCreation(context);
return localBusinessObjImpl;
}
catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.create_ejblocalobject_exception",
ejbDescriptor.getName());
_logger.log(Level.WARNING, "create ejblocal object exception", ex);
if ( ex instanceof EJBException )
throw (EJBException)ex;
else {
CreateException ce =
new CreateException("ERROR creating stateful SessionBean");
ce.initCause(ex);
throw ce;
}
}
| private EJBLocalObjectImpl | createEJBLocalBusinessObjectImpl(SessionContextImpl context)
if ( context.getEJBLocalBusinessObjectImpl() != null )
return context.getEJBLocalBusinessObjectImpl();
EJBLocalObjectImpl localBusinessObjImpl =
instantiateEJBLocalBusinessObjectImpl();
context.setEJBLocalBusinessObjectImpl(localBusinessObjImpl);
localBusinessObjImpl.setContext(context);
localBusinessObjImpl.setKey(context.getInstanceKey());
if( hasLocalHomeView ) {
createEJBLocalObjectImpl(context);
}
if ( hasRemoteHomeView ) {
createEJBObjectImpl(context); // enable remote invocations too
}
if( hasRemoteBusinessView ) {
createRemoteBusinessObjectImpl(context);
}
return localBusinessObjImpl;
| EJBLocalObjectImpl | createEJBLocalObjectImpl()This is called from the generated "HelloEJBLocalHomeImpl" create method
via EJBLocalHomeImpl.createEJBObject.
Note: for stateful beans, the HelloEJBLocalHomeImpl.create calls
ejbCreate on the new bean after createEJBLocalObjectImpl() returns.
Return the EJBLocalObject for the bean.
try {
SessionContextImpl context = createBeanInstance();
EJBLocalObjectImpl localObjImpl =
createEJBLocalObjectImpl(context);
afterInstanceCreation(context);
return localObjImpl;
}
catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.create_ejblocalobject_exception",
ejbDescriptor.getName());
_logger.log(Level.WARNING, "create ejblocal object exception", ex);
if ( ex instanceof EJBException )
throw (EJBException)ex;
else {
CreateException ce =
new CreateException("ERROR creating stateful SessionBean");
ce.initCause(ex);
throw ce;
}
}
| private EJBLocalObjectImpl | createEJBLocalObjectImpl(SessionContextImpl context)
if ( context.getEJBLocalObjectImpl() != null )
return context.getEJBLocalObjectImpl();
// create EJBLocalObject
EJBLocalObjectImpl localObjImpl = instantiateEJBLocalObjectImpl();
// introduce context and EJBLocalObject to each other
context.setEJBLocalObjectImpl(localObjImpl);
localObjImpl.setContext(context);
localObjImpl.setKey(context.getInstanceKey());
if ( hasLocalBusinessView ) {
createEJBLocalBusinessObjectImpl(context);
}
if ( hasRemoteHomeView ) {
createEJBObjectImpl(context); // enable remote invocations too
}
if( hasRemoteBusinessView ) {
createRemoteBusinessObjectImpl(context);
}
return localObjImpl;
| private EJBObjectImpl | createEJBObjectImpl(SessionContextImpl context)
if ( context.getEJBObjectImpl() != null )
return context.getEJBObjectImpl();
// create EJBObject
EJBObjectImpl ejbObjImpl = instantiateEJBObjectImpl();
// introduce context and EJBObject to each other
context.setEJBObjectImpl(ejbObjImpl);
ejbObjImpl.setContext(context);
Object sessionKey = context.getInstanceKey();
ejbObjImpl.setKey(sessionKey);
// connect the EJBObject to the ProtocolManager
// (creates the client-side stub too)
byte[] sessionOID = uuidGenerator.keyToByteArray(sessionKey);
EJBObject ejbStub = (EJBObject)
remoteHomeRefFactory.createRemoteReference(sessionOID);
context.setEJBStub(ejbStub);
ejbObjImpl.setStub(ejbStub);
if (hasRemoteBusinessView ) {
createRemoteBusinessObjectImpl(context);
}
if ( isLocal ) {
if( hasLocalHomeView ) {
// enable local home invocations too
createEJBLocalObjectImpl(context);
}
if( hasLocalBusinessView ) {
// enable local business invocations too
createEJBLocalBusinessObjectImpl(context);
}
}
return ejbObjImpl;
| EJBObjectImpl | createEJBObjectImpl()This is called from the generated "HelloEJBHomeImpl" create method
via EJBHomeImpl.createEJBObject.
Note: for stateful beans, the HelloEJBHomeImpl.create calls
ejbCreate on the new bean after createEJBObject() returns.
Return the EJBObject for the bean.
try {
SessionContextImpl context = createBeanInstance();
EJBObjectImpl ejbObjImpl = createEJBObjectImpl(context);
afterInstanceCreation(context);
return ejbObjImpl;
}
catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.create_ejbobject_exception",
ejbDescriptor.getName());
_logger.log(Level.WARNING, "create object exception", ex);
if ( ex instanceof EJBException )
throw (EJBException)ex;
else {
CreateException ce =
new CreateException("ERROR creating stateful SessionBean");
ce.initCause(ex);
throw ce;
}
}
| private void | createExtendedEMs(SessionContextImpl ctx, java.lang.Object sessionKey)
Set<EntityManagerReferenceDescriptor> emRefs
= ejbDescriptor.getEntityManagerReferenceDescriptors();
Iterator<EntityManagerReferenceDescriptor> iter = emRefs.iterator();
Set<EEMRefInfo> eemRefInfos = new HashSet<EEMRefInfo>();
while (iter.hasNext()) {
EntityManagerReferenceDescriptor refDesc = iter.next();
if (refDesc.getPersistenceContextType() ==
PersistenceContextType.EXTENDED) {
String unitName = refDesc.getUnitName();
EntityManagerFactory emf =
EntityManagerFactoryWrapper.lookupEntityManagerFactory(
ComponentInvocation.EJB_INVOCATION,
unitName, ejbDescriptor);
if (emf != null) {
EntityManager em = findExtendedEMFromInvList(emf);
if (em == null) {
try {
Map properties = refDesc.getProperties();
em = emf.createEntityManager(properties);
if (em == null) {
throw new EJBException
("EM is null. Couldn't create EntityManager for"
+ " refName: " + refDesc.getName()
+ "; unitname: " + unitName);
}
} catch (Throwable th) {
EJBException ejbEx = new EJBException
("Couldn't create EntityManager for"
+ " refName: " + refDesc.getName()
+ "; unitname: " + unitName);
ejbEx.initCause(th);
throw ejbEx;
}
}
String emRefName = refDesc.getName();
long containerID = this.getContainerId();
EEMRefInfo refInfo = null;
synchronized (extendedEMReferenceCountMap) {
refInfo = extendedEMReferenceCountMap.get(em);
if (refInfo != null) {
refInfo.refCount++;
} else {
refInfo = new EEMRefInfo(emRefName, refDesc.getUnitName(), containerID,
sessionKey, em, emf);
refInfo.refCount = 1;
extendedEMReferenceCountMap.put(em, refInfo);
eemKey2EEMMap.put(refInfo.getKey(), refInfo.getEntityManager());
}
}
ctx.addExtendedEntityManagerMapping(emf, refInfo);
eemRefInfos.add(refInfo);
} else {
throw new EJBException("EMF is null. Couldn't get extended EntityManager for"
+ " refName: " + refDesc.getName()
+ "; unitname: " + unitName);
}
}
}
if (eemRefInfos.size() > 0) {
ctx.setEEMRefInfos(eemRefInfos);
}
| EJBObjectImpl | createRemoteBusinessObjectImpl()
try {
SessionContextImpl context = createBeanInstance();
EJBObjectImpl ejbBusinessObjImpl =
createRemoteBusinessObjectImpl(context);
afterInstanceCreation(context);
return ejbBusinessObjImpl;
}
catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.create_ejbobject_exception",
ejbDescriptor.getName());
_logger.log(Level.WARNING, "create object exception", ex);
if ( ex instanceof EJBException )
throw (EJBException)ex;
else {
CreateException ce =
new CreateException("ERROR creating stateful SessionBean");
ce.initCause(ex);
throw ce;
}
}
| private EJBObjectImpl | createRemoteBusinessObjectImpl(SessionContextImpl context)
if ( context.getEJBRemoteBusinessObjectImpl() != null )
return context.getEJBRemoteBusinessObjectImpl();
// create EJBObject
EJBObjectImpl ejbBusinessObjImpl =
instantiateRemoteBusinessObjectImpl();
context.setEJBRemoteBusinessObjectImpl(ejbBusinessObjImpl);
ejbBusinessObjImpl.setContext(context);
Object sessionKey = context.getInstanceKey();
ejbBusinessObjImpl.setKey(sessionKey);
// connect the Remote object to the ProtocolManager
// (creates the client-side stub too)
byte[] sessionOID = uuidGenerator.keyToByteArray(sessionKey);
for(RemoteBusinessIntfInfo next : remoteBusinessIntfInfo.values()) {
java.rmi.Remote stub = next.referenceFactory.
createRemoteReference(sessionOID);
ejbBusinessObjImpl.setStub(next.generatedRemoteIntf.getName(),
stub);
}
if (hasRemoteHomeView ) {
createEJBObjectImpl(context);
}
if ( isLocal ) {
if( hasLocalHomeView ) {
// enable local home invocations too
createEJBLocalObjectImpl(context);
}
if( hasLocalBusinessView ) {
// enable local business invocations too
createEJBLocalBusinessObjectImpl(context);
}
}
return ejbBusinessObjImpl;
| public void | decrementMethodReadyStat()
statMethodReadyCount--;
| private void | decrementRefCountsForEEMs(SessionContextImpl context)
Collection<EEMRefInfo> allRefInfos = context.getAllEEMRefInfos();
for (EEMRefInfo refInfo : allRefInfos) {
EEMRefInfoKey key = refInfo.getKey();
synchronized (extendedEMReferenceCountMap) {
EEMRefInfo cachedRefInfo = extendedEMReferenceCountMap.get(
refInfo.eem);
if (cachedRefInfo != null) {
cachedRefInfo.refCount--;
if (cachedRefInfo.refCount == 0) {
extendedEMReferenceCountMap.remove(refInfo.eem);
eemKey2EEMMap.remove(key);
}
}
}
}
| private void | destroyExtendedEMsForContext(SessionContextImpl sc)
for (EntityManager em : sc.getExtendedEntityManagers()) {
synchronized (extendedEMReferenceCountMap) {
if (extendedEMReferenceCountMap.containsKey(em)) {
EEMRefInfo refInfo = extendedEMReferenceCountMap.get(em);
if (refInfo.refCount > 1) {
refInfo.refCount--;
_logger.log(Level.FINE,
"Decremented RefCount ExtendedEM em: " + em);
} else {
_logger.log(Level.FINE, "DESTROYED ExtendedEM em: "
+ em);
refInfo = extendedEMReferenceCountMap.remove(em);
eemKey2EEMMap.remove(refInfo.getKey());
try {
em.close();
} catch (Throwable th) {
_logger.log(Level.FINE,
"Exception during em.close()", th);
}
}
}
}
}
| private void | doVersionCheck(Invocation inv, java.lang.Object sessionKey, SessionContextImpl sc)
EJBLocalRemoteObject ejbLRO = inv.ejbObject;
long clientVersion = SFSBVersionManager.NO_VERSION;
if (! inv.isLocal) {
clientVersion = SFSBVersionManager.getRequestClientVersion();
SFSBVersionManager.clearRequestClientVersion();
SFSBVersionManager.clearResponseClientVersion();
}
if (ejbLRO != null) {
if (clientVersion == SFSBVersionManager.NO_VERSION) {
clientVersion = ejbLRO.getSfsbClientVersion();
}
long ctxVersion = sc.getVersion();
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, "doVersionCheck(): for: {" + ejbDescriptor.getName()
+ "." + inv.method.getName() + " <=> " + sessionKey + "} clientVersion: "
+ clientVersion + " == " + ctxVersion);
}
if (clientVersion > ctxVersion) {
throw new NoSuchObjectLocalException(
"Found only a stale version " + " clientVersion: "
+ clientVersion + " contextVersion: "
+ ctxVersion);
}
}
| private javax.persistence.EntityManager | findExtendedEMFromInvList(javax.persistence.EntityManagerFactory emf)
EntityManager em = null;
ComponentInvocation compInv = (ComponentInvocation)
invocationManager.getCurrentInvocation();
if (compInv != null) {
if (compInv.getInvocationType() == ComponentInvocation.EJB_INVOCATION) {
if (compInv.context instanceof SessionContextImpl) {
SessionContextImpl ctxImpl = (SessionContextImpl) compInv.context;
if (ctxImpl.container instanceof StatefulSessionContainer) {
em = ctxImpl.getExtendedEntityManager(emf);
}
}
}
}
return em;
| void | forceDestroyBean(EJBContextImpl ctx)Force destroy the EJB and rollback any Tx it was associated with
Called from removeBean, timeoutBean and BaseContainer.postInvokeTx.
Note: EJB2.0 section 18.3.1 says that discarding an EJB
means that no methods other than finalize() should be invoked on it.
SessionContextImpl sc = (SessionContextImpl)ctx;
synchronized ( sc ) {
if ( sc.getState() == DESTROYED )
return;
// mark context as destroyed so no more invocations happen on it
sc.setState(DESTROYED);
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, "[SFSBContainer] (Force)Destroying "
+ "session: " + sc.getInstanceKey());
}
Transaction prevTx = sc.getTransaction();
try {
if ( prevTx != null && prevTx.getStatus() !=
Status.STATUS_NO_TRANSACTION ) {
prevTx.setRollbackOnly();
}
} catch (SystemException ex) {
throw new EJBException(ex);
} catch (IllegalStateException ex) {
throw new EJBException(ex);
}
// remove the bean from the session store
Object sessionKey = sc.getInstanceKey();
sessionBeanCache.remove(sessionKey, sc.existsInStore());
if ( isRemote ) {
if( hasRemoteHomeView ) {
// disconnect the EJBObject from the context and vice versa
EJBObjectImpl ejbObjImpl = sc.getEJBObjectImpl();
ejbObjImpl.clearContext();
ejbObjImpl.setRemoved(true);
sc.setEJBObjectImpl(null);
// disconnect the EJBObject from the ProtocolManager
// so that no remote invocations can reach the EJBObject
remoteHomeRefFactory.destroyReference
(ejbObjImpl.getStub(), ejbObjImpl.getEJBObject());
}
if( hasRemoteBusinessView ) {
EJBObjectImpl ejbBusinessObjImpl =
sc.getEJBRemoteBusinessObjectImpl();
ejbBusinessObjImpl.clearContext();
ejbBusinessObjImpl.setRemoved(true);
sc.setEJBRemoteBusinessObjectImpl(null);
for(RemoteBusinessIntfInfo next :
remoteBusinessIntfInfo.values()) {
// disconnect from the ProtocolManager
// so that no remote invocations can get through
next.referenceFactory.destroyReference
(ejbBusinessObjImpl.getStub
(next.generatedRemoteIntf.getName()),
ejbBusinessObjImpl.getEJBObject
(next.generatedRemoteIntf.getName()));
}
}
}
if ( isLocal ) {
if( hasLocalHomeView ) {
// disconnect the EJBLocalObject from the context
// and vice versa
EJBLocalObjectImpl localObjImpl =
(EJBLocalObjectImpl)sc.getEJBLocalObjectImpl();
localObjImpl.clearContext();
localObjImpl.setRemoved(true);
sc.setEJBLocalObjectImpl(null);
}
if( hasLocalBusinessView ) {
// disconnect the EJBLocalObject from the context
// and vice versa
EJBLocalObjectImpl localBusinessObjImpl =
(EJBLocalObjectImpl)sc.getEJBLocalBusinessObjectImpl();
localBusinessObjImpl.clearContext();
localBusinessObjImpl.setRemoved(true);
sc.setEJBLocalBusinessObjectImpl(null);
}
}
destroyExtendedEMsForContext(sc);
// tell the TM to release resources held by the bean
transactionManager.ejbDestroyed(sc);
if (checkpointPolicy.isHAEnabled()) {
//Remove any SFSBClientVersions
SFSBClientVersionManager.removeClientVersion(getContainerId(), sessionKey);
}
}
| public com.sun.ejb.spi.container.ContainerService | getContainerService()
return ContainerFactoryImpl.getContainerService();
| EJBLocalObjectImpl | getEJBLocalBusinessObjectImpl(java.lang.Object sessionKey)
// Create an EJBLocalObject reference which
// is *not* associated with a SessionContext. That way, the
// session bean context lookup will be done lazily whenever
// the reference is actually accessed. This avoids I/O in the
// case that the reference points to a passivated session bean.
// It's also consistent with the deserialization approach used
// throughout the container. e.g. a timer reference is deserialized
// from its handle without checking it against the timer database.
EJBLocalObjectImpl localBusinessObjImpl;
try {
localBusinessObjImpl = instantiateEJBLocalBusinessObjectImpl();
localBusinessObjImpl.setKey(sessionKey);
} catch ( Exception ex ) {
EJBException ejbEx = new EJBException();
ejbEx.initCause(ex);
throw ejbEx;
}
return localBusinessObjImpl;
| EJBLocalObjectImpl | getEJBLocalObjectImpl(java.lang.Object sessionKey)Called from EJBLocalObjectImpl.getLocalObject() while deserializing
a local object reference.
// Create an EJBLocalObject reference which
// is *not* associated with a SessionContext. That way, the
// session bean context lookup will be done lazily whenever
// the reference is actually accessed. This avoids I/O in the
// case that the reference points to a passivated session bean.
// It's also consistent with the deserialization approach used
// throughout the container. e.g. a timer reference is deserialized
// from its handle without checking it against the timer database.
EJBLocalObjectImpl localObjImpl;
try {
localObjImpl = instantiateEJBLocalObjectImpl();
localObjImpl.setKey(sessionKey);
} catch ( Exception ex ) {
EJBException ejbEx = new EJBException();
ejbEx.initCause(ex);
throw ejbEx;
}
return localObjImpl;
| EJBObjectImpl | getEJBObjectImpl(byte[] instanceKey)
SessionContextImpl sc = _getContextForInstance(instanceKey);
return (sc != null) ? sc.getEJBObjectImpl() : null;
| EJBObjectImpl | getEJBRemoteBusinessObjectImpl(byte[] instanceKey)
SessionContextImpl sc = _getContextForInstance(instanceKey);
return (sc != null) ? sc.getEJBRemoteBusinessObjectImpl() : null;
| public int | getMaxCacheSize()
return sessionBeanCache.getMaxCacheSize();
| public long | getMethodReadyCount()
return statMethodReadyCount;
| public java.lang.String | getMonitorAttributeValues()
StringBuffer sbuf = new StringBuffer();
//sbuf.append(storeHelper.getMonitorAttributeValues());
sbuf.append(" { asyncTaskCount=").append(asyncTaskCount)
.append("; asyncCummTaskCount=").append(asyncCummTaskCount)
.append("; passivationBatchCount=").append(passivationBatchCount)
.append("; passivationQSz=").append(passivationCandidates.size())
.append("; trimEventCount=").append(containerTrimCount)
.append(" }");
return sbuf.toString();
| public final int | getPassivationBatchCount()
return this.passivationBatchCount;
| public long | getPassiveCount()
return (sfsbStoreMonitor == null)
? 0 : sfsbStoreMonitor.getNumPassivations();
| protected java.lang.String[] | getPre30LifecycleMethodNames()
return new String[] {
null, "ejbRemove", "ejbPassivate", "ejbActivate"
};
| com.sun.ejb.spi.sfsb.store.SFSBBeanState | getSFSBBeanState(SessionContextImpl sc)
//No need to synchronize
SFSBBeanState sfsbBeanState = null;
try {
if ((containerState != CONTAINER_STARTED) && (containerState != CONTAINER_STOPPED)) {
_logger.log(Level.FINE, "getSFSBBeanState() returning because "
+ "containerState: " + containerState);
return null;
}
if (sc.getState() == DESTROYED) {
return null;
}
Object ejb = sc.getEJB();
ComponentInvocation ci = new ComponentInvocation(ejb, this, sc);
invocationManager.preInvoke(ci);
synchronized (sc) {
try {
interceptorManager.intercept(
CallbackType.PRE_PASSIVATE, sc);
sc.setLastPersistedAt(System.currentTimeMillis());
long newCtxVersion = sc.incrementAndGetVersion();
byte[] serializedState = IOUtils.serializeObject(sc, true);
sfsbBeanState = sfsbStoreManager.createSFSBBeanState(
sc.getInstanceKey(), System.currentTimeMillis(),
!sc.existsInStore(), serializedState);
sfsbBeanState.setVersion(newCtxVersion);
interceptorManager.intercept(
CallbackType.POST_ACTIVATE, sc);
//Do not set sc.setExistsInStore() here
} catch (java.io.NotSerializableException serEx) {
_logger.log(Level.WARNING, "Error during checkpoint ("
+ ejbDescriptor.getName() + ". Key: "
+ sc.getInstanceKey() + ") " + serEx);
_logger.log(Level.FINE, "sfsb checkpoint error. Key: "
+ sc.getInstanceKey(), serEx);
try {
forceDestroyBean(sc);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
} catch (Throwable ex) {
_logger.log(Level.WARNING, "ejb.sfsb_checkpoint_error",
new Object[] { ejbDescriptor.getName() });
_logger.log(Level.WARNING, "sfsb checkpoint error. key: "
+ sc.getInstanceKey(), ex);
try {
forceDestroyBean(sc);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
} finally {
invocationManager.postInvoke(ci);
}
} //synchronized
} catch (Throwable th) {
_logger.log(Level.WARNING, "ejb.sfsb_checkpoint_error",
new Object[] { ejbDescriptor.getName() });
_logger.log(Level.WARNING, "sfsb checkpoint error", th);
}
return sfsbBeanState;
| public com.sun.ejb.spi.sfsb.store.SFSBStoreManager | getSFSBStoreManager()
return this.sfsbStoreManager;
| private void | handleConcurrentInvocation(Invocation inv, java.lang.Object sessionKey)
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sessionKey, "Another invocation in progress");
}
String errMsg = "SessionBean is executing another request. "
+ "[session-key: " + sessionKey + "]";
ConcurrentAccessException conEx = new ConcurrentAccessException(errMsg);
if (inv.isBusinessInterface) {
throw conEx;
} else {
// there is an invocation in progress for this instance
// throw an exception (EJB2.0 section 7.5.6).
throw new EJBException(conEx);
}
| private void | handleEndOfMethodCheckpoint(SessionContextImpl sc, Invocation inv)
int txAttr = inv.invocationInfo.txAttr;
switch (txAttr) {
case TX_NEVER:
case TX_SUPPORTS:
case TX_NOT_SUPPORTED:
if (inv.invocationInfo.checkpointEnabled) {
checkpointEJB(sc);
}
break;
case TX_BEAN_MANAGED:
if (sc.isTxCheckpointDelayed()
|| inv.invocationInfo.checkpointEnabled)
{
checkpointEJB(sc);
sc.setTxCheckpointDelayed(false);
}
break;
default:
if (inv.invocationInfo.isCreateHomeFinder) {
if (inv.invocationInfo.checkpointEnabled) {
checkpointEJB(sc);
}
}
break;
}
if (sc.getState() != DESTROYED) {
sc.setState(READY);
incrementMethodReadyStat();
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sc.getInstanceKey(), "Released context");
}
}
| public void | incrementMethodReadyStat()
statMethodReadyCount++;
| protected void | initializeHome()
super.initializeHome();
loadCheckpointInfo();
registerMonitorableComponents();
| public void | invokePeriodically(long delay, long periodicity, java.lang.Runnable target)
java.util.Timer timer = ContainerFactoryImpl.getContainerService().getTimer();
TimerTask timerTask = new PeriodicTask(super.loader, target);
timer.scheduleAtFixedRate(timerTask, delay, periodicity);
scheduledTimerTasks.add(timerTask);
| public boolean | isHAEnabled()
return checkpointPolicy.isHAEnabled();
| boolean | isIdentical(EJBObjectImpl ejbo, EJBObject other)
if ( other == ejbo.getStub() )
return true;
else {
try {
// other may be a stub for a remote object.
if ( protocolMgr.isIdentical(ejbo.getStub(), other) )
return true;
else
return false;
} catch ( Exception ex ) {
_logger.log(Level.FINE,
"Exception while getting stub for ejb",ex);
throw new RemoteException("Error during isIdentical.", ex);
}
}
| protected void | loadCheckpointInfo()
try {
if (checkpointPolicy.isHAEnabled()) {
Iterator iter = invocationInfoMap.values().iterator();
while (iter.hasNext()) {
InvocationInfo info = (InvocationInfo) iter.next();
info.checkpointEnabled = false;
MethodDescriptor md = new MethodDescriptor(
info.method, info.methodIntf);
IASEjbExtraDescriptors extraDesc =
ejbDescriptor.getIASEjbExtraDescriptors();
if (extraDesc != null) {
CheckpointAtEndOfMethodDescriptor cpDesc =
extraDesc.getCheckpointAtEndOfMethodDescriptor();
if (cpDesc != null) {
info.checkpointEnabled =
cpDesc.isCheckpointEnabledFor(md);
}
}
if (info.checkpointEnabled) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "[SFSBContainer] "
+ info.method + " MARKED for "
+ "end-of-method-checkpoint");
}
}
}
}
} catch (Exception ex) {
_logger.log(Level.WARNING, "[SFSBContainer] Exception while "
+ " loading checkpoint info", ex);
}
| private final void | logTraceInfo(Invocation inv, java.lang.Object key, java.lang.String message)
_logger.log(TRACE_LEVEL, traceInfoPrefix + message
+ " for " + inv.method.getName() + "; key: " + key);
| private final void | logTraceInfo(SessionContextImpl sc, java.lang.String message)
_logger.log(TRACE_LEVEL, traceInfoPrefix + message
+ " for key: " + sc.getInstanceKey()
+ "; " + System.identityHashCode(sc));
| public void | onUndeploy(com.sun.ejb.spi.container.StatefulEJBContext sfsbCtx)
undeploy((SessionContextImpl) sfsbCtx.getSessionContext());
| public final boolean | passivateEJB(ComponentContext context)
SessionContextImpl sc = (SessionContextImpl)context;
boolean success = false;
try {
if ((containerState != CONTAINER_STARTED) && (containerState != CONTAINER_STOPPED)) {
_logger.log(TRACE_LEVEL, "passivateEJB() returning because "
+ "containerState: " + containerState);
return false;
}
if ( sc.getState() == DESTROYED )
return false;
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, traceInfoPrefix + "Passivating context "
+ sc.getInstanceKey() + "; current-state = "
+ convertCtxStateToString(sc));
}
Object ejb = sc.getEJB();
long passStartTime = -1;
if (sfsbStoreMonitor.isMonitoringOn()) {
passStartTime = System.currentTimeMillis();
}
ComponentInvocation ci = new ComponentInvocation(ejb, this, sc);
invocationManager.preInvoke(ci);
boolean failed = false;
success = false;
synchronized (sc) {
try {
// dont passivate if there is a Tx/invocation in progress
// for this instance.
if (! sc.canBePassivated()) {
return false;
}
// passivate the EJB
sc.setState(PASSIVE);
decrementMethodReadyStat();
interceptorManager.intercept(
CallbackType.PRE_PASSIVATE, sc);
sc.setLastPersistedAt(System.currentTimeMillis());
boolean saved = false;
try {
saved = sessionBeanCache.passivateEJB(sc, sc
.getInstanceKey());
} catch (EMNotSerializableException emNotSerEx) {
_logger.log(Level.WARNING, "Extended EM not serializable. "
+ "Exception: " + emNotSerEx);
_logger.log(Level.FINE, "Extended EM not serializable", emNotSerEx);
saved = false;
}
if (! saved) {
interceptorManager.intercept(
CallbackType.POST_ACTIVATE, sc);
sc.setState(READY);
incrementMethodReadyStat();
return false;
}
sfsbStoreMonitor.incrementPassivationCount(true);
transactionManager.ejbDestroyed( sc );
decrementRefCountsForEEMs(sc);
if ( isRemote ) {
if( hasRemoteHomeView ) {
// disconnect the EJBObject from the EJB
EJBObjectImpl ejbObjImpl = sc.getEJBObjectImpl();
ejbObjImpl.clearContext();
sc.setEJBObjectImpl(null);
// disconnect the EJBObject from ProtocolManager
// so that no state is held by ProtocolManager
remoteHomeRefFactory.destroyReference
(ejbObjImpl.getStub(),
ejbObjImpl.getEJBObject());
}
if( hasRemoteBusinessView ) {
// disconnect the EJBObject from the EJB
EJBObjectImpl ejbBusinessObjImpl =
sc.getEJBRemoteBusinessObjectImpl();
ejbBusinessObjImpl.clearContext();
sc.setEJBRemoteBusinessObjectImpl(null);
for(RemoteBusinessIntfInfo next :
remoteBusinessIntfInfo.values()) {
next.referenceFactory.destroyReference
(ejbBusinessObjImpl.getStub(),
ejbBusinessObjImpl.getEJBObject
(next.generatedRemoteIntf.getName()));
}
}
}
if ( isLocal ) {
long version = sc.getVersion();
if( hasLocalHomeView ) {
// disconnect the EJBLocalObject from the EJB
EJBLocalObjectImpl localObjImpl =
sc.getEJBLocalObjectImpl();
localObjImpl.setSfsbClientVersion(version);
localObjImpl.clearContext();
sc.setEJBLocalObjectImpl(null);
}
if( hasLocalBusinessView ) {
EJBLocalObjectImpl localBusinessObjImpl =
sc.getEJBLocalBusinessObjectImpl();
localBusinessObjImpl.setSfsbClientVersion(version);
localBusinessObjImpl.clearContext();
sc.setEJBLocalBusinessObjectImpl(null);
}
}
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(sc, "Successfully passivated");
}
} catch (java.io.NotSerializableException nsEx) {
sfsbStoreMonitor.incrementPassivationCount(false);
_logger.log(Level.WARNING, "Error during passivation: "
+ sc + "; " + nsEx);
_logger.log(Level.FINE, "sfsb passivation error", nsEx);
// Error during passivate, so discard bean: EJB2.0 18.3.3
try {
forceDestroyBean(sc);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
} catch (Throwable ex) {
sfsbStoreMonitor.incrementPassivationCount(false);
_logger.log(Level.WARNING, "ejb.sfsb_passivation_error",
new Object[] { ejbDescriptor.getName() + " <==> " + sc });
_logger.log(Level.WARNING, "sfsb passivation error. Key: "
+ sc.getInstanceKey(), ex);
// Error during passivate, so discard bean: EJB2.0 18.3.3
try {
forceDestroyBean(sc);
} catch ( Exception e ) {
_logger.log(Level.FINE, "error destroying bean", e);
}
} finally {
invocationManager.postInvoke(ci);
if (passStartTime != -1) {
long timeSpent = System.currentTimeMillis()
- passStartTime;
sfsbStoreMonitor.setPassivationTime(timeSpent);
}
}
} //synchronized
} catch (Exception ex) {
_logger.log(Level.WARNING, "ejb.sfsb_passivation_error",
new Object[] { ejbDescriptor.getName() });
_logger.log(Level.WARNING, "sfsb passivation error", ex);
}
return success;
| public final boolean | passivateEJB(com.sun.ejb.spi.container.StatefulEJBContext sfsbCtx)
return passivateEJB((ComponentContext) sfsbCtx.getSessionContext());
| public void | postInvokeTx(Invocation inv)
// Intercept postInvokeTx call to perform any @Remove logic
// before tx commits. super.postInvokeTx() must *always*
// be called.
// If this was an invocation of a remove-method
if( inv.invocationInfo.removalInfo != null ) {
InvocationInfo invInfo = inv.invocationInfo;
EjbRemovalInfo removeInfo = invInfo.removalInfo;
if( retainAfterRemoveMethod(inv, removeInfo) ) {
// Do nothing
} else {
// If there is a tx, remove bean from ContainerSynch so it
// won't receive any SessionSynchronization callbacks.
// We delay the PreDestroy callback and instance destruction
// until releaseContext so that PreDestroy won't run within
// the business method's tx.
SessionContextImpl sc = (SessionContextImpl)inv.context;
Transaction tx = sc.getTransaction();
if( tx != null ) {
ContainerSynchronization sync =
containerFactory.getContainerSync(tx);
sync.removeBean(sc);
}
}
}
super.postInvokeTx(inv);
| protected void | registerMonitorableComponents()
registryMediator.registerProvider(this);
registryMediator.registerProvider(sessionBeanCache);
super.registerMonitorableComponents();
super.populateMethodMonitorMap();
sfsbStoreMonitor = registryMediator.registerProvider(
sfsbStoreManager.getMonitorableSFSBStoreManager(),
checkpointPolicy.isHAEnabled());
sessionBeanCache.setStatefulSessionStoreMonitor(sfsbStoreMonitor);
_logger.log(Level.FINE, "[SFSBContainer] registered monitorable");
| public void | releaseContext(Invocation inv)Called from preInvoke which is called from the EJBObject for local and
remote invocations.
SessionContextImpl sc = (SessionContextImpl) inv.context;
// check if the bean was destroyed
if (sc.getState() == DESTROYED)
return;
// we're sure that no concurrent thread can be using this
// context, so no need to synchronize.
Transaction tx = sc.getTransaction();
try {
// If this was an invocation of a remove-method
if (inv.invocationInfo.removalInfo != null) {
InvocationInfo invInfo = inv.invocationInfo;
EjbRemovalInfo removeInfo = invInfo.removalInfo;
if (retainAfterRemoveMethod(inv, removeInfo)) {
_logger.log(Level.INFO, "Skipping destruction of SFSB "
+ invInfo.ejbName + " after @Remove method "
+ invInfo.method + " due to (retainIfException"
+ " == true) and exception " + inv.exception);
} else {
try {
// PRE-DESTROY runs in an unspecified tx context, so
// we call it here in releaseContext, after
// postInvokeTx has completed.
interceptorManager.intercept(CallbackType.PRE_DESTROY, sc);
} catch (Throwable t) {
_logger.log(Level.FINE, "@Remove.preDestroy exception",
t);
}
forceDestroyBean(sc);
}
}
if (tx == null || tx.getStatus() == Status.STATUS_NO_TRANSACTION) {
// The Bean executed with no tx, or with a tx and
// container.afterCompletion() was already called.
if (sc.getState() != READY) {
if (sc.isAfterCompletionDelayed()) {
// ejb.afterCompletion was not called yet
// because of container.afterCompletion may have
// been called concurrently with this invocation.
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sc,
"Calling delayed afterCompletion");
}
callEjbAfterCompletion(sc, sc.getCompletedTxStatus());
}
if (sc.getState() != DESTROYED) {
// callEjbAfterCompletion could make state as DESTROYED
sc.setState(READY);
handleEndOfMethodCheckpoint(sc, inv);
}
}
if ((sc.getState() != DESTROYED)
&& (checkpointPolicy.isHAEnabled())) {
syncClientVersion(inv, sc);
}
} else {
if ((sc.getState() != DESTROYED)
&& (checkpointPolicy.isHAEnabled())) {
syncClientVersion(inv, sc);
}
sc.setState(INCOMPLETE_TX);
if (_logger.isLoggable(TRACE_LEVEL)) {
logTraceInfo(inv, sc, "Marking state == INCOMPLETE_TX");
}
}
} catch (SystemException ex) {
throw new EJBException(ex);
}
| void | removeBean(EJBLocalRemoteObject ejbo, java.lang.reflect.Method removeMethod, boolean local)
Invocation i = new Invocation();
i.ejbObject = ejbo;
i.isLocal = local;
i.method = removeMethod;
// Method must be a remove method defined on one of :
// javax.ejb.EJBHome, javax.ejb.EJBObject, javax.ejb.EJBLocalHome,
// javax.ejb.EJBLocalObject
Class declaringClass = removeMethod.getDeclaringClass();
i.isHome = ( (declaringClass == javax.ejb.EJBHome.class) ||
(declaringClass == javax.ejb.EJBLocalHome.class) );
try {
preInvoke(i);
removeBean(i);
} catch(Exception e) {
_logger.log(Level.FINE,"ejb.preinvoke_exception",e);
i.exception = e;
} finally {
if ( AppVerification.doInstrument() ) {
AppVerification.getInstrumentLogger().doInstrumentForEjb
(ejbDescriptor, removeMethod, i.exception);
}
postInvoke(i);
}
if(i.exception != null) {
if(i.exception instanceof RemoveException) {
throw (RemoveException)i.exception;
}
else if(i.exception instanceof RuntimeException) {
throw (RuntimeException)i.exception;
}
else if(i.exception instanceof Exception) {
throw new EJBException((Exception)i.exception);
}
else {
EJBException ejbEx = new EJBException();
ejbEx.initCause(i.exception);
throw ejbEx;
}
}
| private void | removeBean(Invocation inv)Called from EJBObjectImpl.remove().
Note: preInvoke and postInvoke are called for remove().
// At this point the EJB's state is always INVOKING
// because EJBObjectImpl.remove() called preInvoke().
try {
statRemoveCount++;
SessionContextImpl sc = (SessionContextImpl)inv.context;
Transaction tc = sc.getTransaction();
if ( tc != null && tc.getStatus() !=
Status.STATUS_NO_TRANSACTION ) {
// EJB2.0 section 7.6.4: remove must always be called without
// a transaction.
throw new RemoveException
("Cannot remove EJB: transaction in progress");
}
// call ejbRemove on the EJB
if (_logger.isLoggable(TRACE_LEVEL)) {
_logger.log(TRACE_LEVEL, "[SFSBContainer] Removing "
+ "session: " + sc.getInstanceKey());
}
sc.setInEjbRemove(true);
try {
interceptorManager.intercept(
CallbackType.PRE_DESTROY, sc);
} catch(Throwable t) {
_logger.log(Level.FINE,
"exception thrown from SFSB PRE_DESTROY", t);
} finally {
sc.setInEjbRemove(false);
}
forceDestroyBean(sc);
}
catch ( EJBException ex ) {
_logger.log(Level.FINE,"EJBException in removing bean",ex);
throw ex;
}
catch ( RemoveException ex ) {
_logger.log(Level.FINE,"Remove exception while removing bean",ex);
throw ex;
}
catch (Exception ex) {
_logger.log(Level.FINE,"Some exception while removing bean",ex);
throw new EJBException(ex);
}
| public void | removeExpiredSessions()
try {
_logger.log(Level.FINE, "StatefulContainer Removing expired sessions....");
long val = sfsbStoreManager.removeExpiredSessions();
sfsbStoreMonitor.incrementExpiredSessionsRemoved(val);
_logger.log(Level.FINE, "StatefulContainer Removed " + val + " sessions....");
} catch (SFSBStoreManagerException sfsbEx) {
_logger.log(Level.WARNING, "Got exception from store manager",
sfsbEx);
}
| public void | removeTimedoutBean(EJBContextImpl ctx)
// check if there is an invocation in progress for
// this instance.
synchronized (ctx) {
if (ctx.getState() != INVOKING) {
try {
// call ejbRemove on the bean
Object ejb = ctx.getEJB();
ctx.setInEjbRemove(true);
interceptorManager.intercept(
CallbackType.PRE_DESTROY, ctx);
} catch ( Throwable t ) {
_logger.log(Level.FINE, "ejbRemove exception", t);
} finally {
ctx.setInEjbRemove(false);
}
if (_logger.isLoggable(TRACE_LEVEL)) {
SessionContextImpl sc = (SessionContextImpl) ctx;
_logger.log(TRACE_LEVEL, "[SFSBContainer] Removing TIMEDOUT "
+ "session: " + sc.getInstanceKey());
}
forceDestroyBean(ctx);
}
}
| private void | repopulateEEMMapsInContext(java.lang.Object sessionKey, SessionContextImpl context)
Collection<EEMRefInfo> allRefInfos = context.getAllEEMRefInfos();
for (EEMRefInfo refInfo : allRefInfos) {
EEMRefInfoKey key = refInfo.getKey();
synchronized (extendedEMReferenceCountMap) {
EntityManager eMgr = eemKey2EEMMap.get(key);
EEMRefInfo newRefInfo = null;
if (eMgr != null) {
EEMRefInfo cachedRefInfo = extendedEMReferenceCountMap.get(eMgr);
//cachedRefInfo cannot be null
context.addExtendedEntityManagerMapping(
cachedRefInfo.getEntityManagerFactory(),
cachedRefInfo);
cachedRefInfo.refCount++;
newRefInfo = cachedRefInfo;
} else {
//Deserialize em from the byte[]
String emRefName = key.emRefName;
String unitName = refInfo.getUnitName();
EntityManagerFactory emf = EntityManagerFactoryWrapper
.lookupEntityManagerFactory(ComponentInvocation.EJB_INVOCATION,
unitName, ejbDescriptor);
if (emf != null) {
ObjectInputStream ois = null;
ByteArrayInputStream bis = null;
try {
bis = new ByteArrayInputStream(refInfo.serializedEEM);
ois = new ObjectInputStream(bis);
eMgr = (EntityManager) ois.readObject();
newRefInfo = new EEMRefInfo(emRefName, unitName, super.getContainerId(),
sessionKey, eMgr, emf);
newRefInfo.refCount = 1;
extendedEMReferenceCountMap.put(eMgr, newRefInfo);
eemKey2EEMMap.put(newRefInfo.getKey(),
newRefInfo.getEntityManager());
} catch (Throwable th) {
EJBException ejbEx = new EJBException(
"Couldn't create EntityManager for"
+ " refName: " + emRefName);
ejbEx.initCause(th);
throw ejbEx;
} finally {
if (ois != null) { try { ois.close(); } catch (Throwable th) {} }
if (bis != null) { try { bis.close(); } catch (Throwable th) {} }
}
} else {
throw new EJBException(
"EMF is null. Couldn't get extended EntityManager for"
+ " refName: " + emRefName);
}
}
context.addExtendedEntityManagerMapping(
newRefInfo.getEntityManagerFactory(), newRefInfo);
}
}
| private boolean | retainAfterRemoveMethod(Invocation inv, EjbRemovalInfo rInfo)Should only be called when a method is known to be a remove method.
boolean retain =
( rInfo.getRetainIfException() &&
(inv.exceptionFromBeanMethod != null) &&
(isApplicationException(inv.exceptionFromBeanMethod)) );
return retain;
| public void | setCheckpointPolicy(com.sun.ejb.spi.sfsb.util.CheckpointPolicy policy)
this.checkpointPolicy = policy;
| public final void | setPassivationBatchCount(int count)
this.passivationBatchCount = count;
| public void | setRemovalGracePeriodInSeconds(int val)
this.removalGracePeriodInSeconds = val;
| public void | setSFSBStoreManager(com.sun.ejb.spi.sfsb.store.SFSBStoreManager storeManager)
this.sfsbStoreManager = storeManager;
| public void | setSFSBUUIDUtil(com.sun.ejb.spi.sfsb.util.SFSBUUIDUtil util)/
public void onShutdown() {
_logger.log(Level.FINE, "StatefulSessionContainer.onshutdown() called");
ClassLoader origClassLoader = Utility.setContextClassLoader(loader);
try {
cancelAllTimerTasks();
sessionBeanCache.shutdown();
while (true) {
ComponentContext ctx = null;
synchronized (asyncTaskSemaphore) {
int sz = passivationCandidates.size();
if (sz > 0) {
ctx = (ComponentContext)
passivationCandidates.remove(sz-1);
} else {
break;
}
}
passivateEJB(ctx);
}
super.onShutdown();
sessionBeanCache.destroy();
try {
sfsbStoreManager.shutdown();
} catch (SFSBStoreManagerException sfsbEx) {
_logger.log(Level.WARNING, "[" + ejbName + "]: Error during "
+ "storeManager.shutdown()", sfsbEx);
}
} catch (Throwable th) {
_logger.log(Level.WARNING, "[" + ejbName + "]: Error during "
+ " onShutdown()", th);
} finally {
Utility.setContextClassLoader(origClassLoader);
}
}
public void undeploy() {
_logger.log(Level.FINE, "StatefulSessionContainer.undeploy() called");
long myContainerId = getContainerId();
super.setUndeployedState();
ClassLoader origLoader = null;
try {
cancelAllTimerTasks();
sessionBeanCache.setUndeployedState();
origLoader = Utility.setContextClassLoader(loader);
Iterator iter = sessionBeanCache.values();
while (iter.hasNext()) {
SessionContextImpl ctx = (SessionContextImpl) iter.next();
invokePreDestroyAndUndeploy(ctx);
}
while (true) {
SessionContextImpl ctx = null;
synchronized (asyncTaskSemaphore) {
int sz = passivationCandidates.size();
if (sz > 0) {
ctx = (SessionContextImpl) passivationCandidates
.remove(sz - 1);
invokePreDestroyAndUndeploy(ctx);
} else {
break;
}
}
}
sessionBeanCache.destroy();
try {
sfsbStoreManager.removeAll();
} catch (SFSBStoreManagerException sfsbEx) {
_logger.log(Level.WARNING, "[" + ejbName + "]: Error during "
+ "storeManager.shutdown()", sfsbEx);
}
} finally {
super.undeploy();
SFSBClientVersionManager.removeAllEntries(myContainerId);
// helps garbage collection
// this.storeHelper = null;
this.passivationCandidates = null;
this.asyncTaskSemaphore = null;
this.sessionBeanCache = null;
if (origLoader != null) {
Utility.setContextClassLoader(origLoader);
}
}
}
private void invokePreDestroyAndUndeploy(SessionContextImpl ctx) {
try {
ctx.setInEjbRemove(true);
interceptorManager.intercept(CallbackType.PRE_DESTROY, ctx);
} catch (Throwable t) {
_logger.log(Level.FINE,
"exception thrown from SFSB PRE_DESTROY", t);
} finally {
ctx.setInEjbRemove(false);
}
try {
this.undeploy(ctx);
} catch (Exception ex) {
_logger.log(Level.WARNING, "[" + ejbName
+ "]: Error while " + " undeploying ctx. Key: "
+ ctx.getInstanceKey());
_logger.log(Level.FINE, "[" + ejbName + "]: Error while "
+ " undeploying ctx. Key: " + ctx.getInstanceKey(),
ex);
}
}
private void cancelAllTimerTasks() {
try {
int size = scheduledTimerTasks.size();
for (int i=0; i " + addTask);
}
if (addTask == false) {
return;
}
asyncTaskCount++;
asyncCummTaskCount++;
}
try {
ASyncPassivator work = new ASyncPassivator();
ContainerWorkPool.addLast(work);
} catch (Exception ex) {
synchronized (asyncTaskSemaphore) {
asyncTaskCount--;
}
_logger.log(Level.WARNING, "ejb.add_cleanup_task_error",ex);
}
}
private class ASyncPassivator implements Servicable {
public void prolog() { }
public void epilog() { }
public void service() { run(); }
public void run() {
final Thread currentThread = Thread.currentThread();
final ClassLoader previousClassLoader =
currentThread.getContextClassLoader();
final ClassLoader myClassLoader = loader;
boolean decrementedTaskCount = false;
try {
// We need to set the context class loader for
// this (deamon) thread!!
if(System.getSecurityManager() == null) {
currentThread.setContextClassLoader(loader);
} else {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public java.lang.Object run() {
currentThread.setContextClassLoader(loader);
return null;
}
});
}
ComponentContext ctx = null;
do {
synchronized (asyncTaskSemaphore) {
int sz = passivationCandidates.size();
if (sz > 0) {
ctx = (ComponentContext)
passivationCandidates.remove(sz-1);
} else {
return;
}
}
passivateEJB(ctx);
} while (true);
} catch (Throwable th) {
th.printStackTrace();
} finally {
if (! decrementedTaskCount) {
synchronized (asyncTaskSemaphore) {
asyncTaskCount--;
}
}
if(System.getSecurityManager() == null) {
currentThread.setContextClassLoader(previousClassLoader);
} else {
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public java.lang.Object run() {
currentThread.setContextClassLoader
(previousClassLoader);
return null;
}
});
}
}
}
}
//
this.uuidGenerator = util;
| public void | setSessionCache(com.sun.ejb.containers.util.cache.LruSessionCache cache)
this.sessionBeanCache = cache;
| private void | syncClientVersion(Invocation inv, SessionContextImpl sc)
EJBLocalRemoteObject ejbLRO = inv.ejbObject;
if (ejbLRO != null) {
ejbLRO.setSfsbClientVersion(sc.getVersion());
}
if ((! inv.isLocal) && (checkpointPolicy.isHAEnabled())) {
long version = sc.getVersion();
SFSBVersionManager.setResponseClientVersion(version);
SFSBClientVersionManager.setClientVersion(getContainerId(),
sc.getInstanceKey(), version);
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "Added [synced] version: "
+ sc.getVersion() + " for key: " + sc.getInstanceKey());
}
}
| void | txCheckpointCompleted(SessionContextImpl sc)
if (sc.getState() != DESTROYED) {
//We did persist this ctx in the store
sc.setExistsInStore(true);
sc.setState(READY);
incrementMethodReadyStat();
}
| public boolean | userTransactionMethodsAllowed(ComponentInvocation inv)
boolean utMethodsAllowed = false;
if( isBeanManagedTran ) {
if( inv instanceof Invocation ) {
Invocation i = (Invocation) inv;
SessionContextImpl sc = (SessionContextImpl) i.context;
// This will prevent setSessionContext access to
// UserTransaction methods.
utMethodsAllowed = (sc.getInstanceKey() != null);
} else {
utMethodsAllowed = true;
}
}
return utMethodsAllowed;
|
|