com.sun.ejb.containers.StatelessSessionContainer Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
// Portions Copyright [2016-2021] [Payara Foundation and/or its affiliates]
package com.sun.ejb.containers;
import com.sun.ejb.ComponentContext;
import com.sun.ejb.EjbInvocation;
import com.sun.ejb.containers.util.pool.AbstractPool;
import com.sun.ejb.containers.util.pool.BlockingPool;
import com.sun.ejb.containers.util.pool.NonBlockingPool;
import com.sun.ejb.containers.util.pool.ObjectFactory;
import com.sun.ejb.monitoring.stats.EjbMonitoringStatsProvider;
import com.sun.ejb.monitoring.stats.EjbPoolStatsProvider;
import com.sun.ejb.monitoring.stats.StatelessSessionBeanStatsProvider;
import com.sun.enterprise.admin.monitor.callflow.ComponentType;
import com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType;
import com.sun.enterprise.deployment.runtime.BeanPoolDescriptor;
import com.sun.enterprise.security.SecurityManager;
import java.lang.reflect.Method;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import jakarta.ejb.CreateException;
import jakarta.ejb.EJBException;
import jakarta.ejb.EJBObject;
import jakarta.ejb.NoSuchObjectLocalException;
import jakarta.ejb.RemoveException;
import jakarta.ejb.SessionBean;
import jakarta.transaction.Status;
import jakarta.transaction.Transaction;
import org.glassfish.api.invocation.ComponentInvocation;
import org.glassfish.ejb.config.EjbContainer;
import org.glassfish.ejb.deployment.descriptor.EjbDescriptor;
import org.glassfish.ejb.deployment.descriptor.runtime.IASEjbExtraDescriptors;
/**
* This class provides container functionality specific to stateless SessionBeans.
*
* At deployment time, one instance of the StatelessSessionContainer is created
* for each stateless SessionBean type (i.e. deployment descriptor) in a JAR.
*
* The three states of a Stateless EJB (an EJB can be in only one state at a time):
*
* - POOLED : ready for invocations, no transaction in progress
*
- INVOKING : processing an invocation
*
- DESTROYED : does not exist
*
*
* This container services invocations using a pool of EJB instances.
* An instance is returned to the pool immediately after the invocation
* completes, so the # of instances needed = # of concurrent invocations.
*
* A Stateless Bean can hold open DB connections across invocations.
* It is assumed that the Resource Manager can handle multiple incomplete transactions
* on the same connection.
*/
public class StatelessSessionContainer extends BaseContainer {
private static final byte[] statelessInstanceKey = {0, 0, 0, 1};
// All stateless EJBs have the same instanceKey, since all stateless EJBs
// are identical. Note: the first byte of instanceKey must be left empty.
// All stateless EJB instances of a particular class (i.e. all bean
// instances created by this container instance) have the same
// EJBObject/EJBLocalObject instance since they are all identical.
private EJBLocalObjectImpl theEJBLocalObjectImpl = null;
private EJBLocalObjectImpl theEJBLocalBusinessObjectImpl = null;
private EJBLocalObjectImpl theOptionalEJBLocalBusinessObjectImpl = null;
// Data members for RemoteHome view
private EJBObjectImpl theEJBObjectImpl = null;
private EJBObject theEJBStub = null;
// Data members for Remote business view. Any objects representing the
// Remote business interface are not subtypes of EJBObject.
private EJBObjectImpl theRemoteBusinessObjectImpl = null;
private final Map theRemoteBusinessStubs = new HashMap<>();
private AbstractPool pool;
private IASEjbExtraDescriptors iased = null;
private BeanPoolDescriptor beanPoolDes = null;
private EjbContainer ejbContainer = null;
private PoolProperties poolProp = null;
/**
* This constructor is called from the JarManager when a Jar is deployed.
* @exception Exception on error
*/
StatelessSessionContainer(EjbDescriptor desc, ClassLoader loader, SecurityManager sm) throws Exception {
this(ContainerType.STATELESS, desc, loader, sm);
}
protected StatelessSessionContainer( //
ContainerType conType, EjbDescriptor desc, ClassLoader loader, SecurityManager sm) throws Exception {
super(conType, desc, loader, sm);
ejbContainer = ejbContainerUtilImpl.getEjbContainer();
super.createCallFlowAgent(ComponentType.SLSB);
}
public String getMonitorAttributeValues() {
StringBuilder sbuf = new StringBuilder();
sbuf.append("STATELESS ").append(ejbDescriptor.getName());
sbuf.append(pool.getAllAttrValues());
sbuf.append("]");
return sbuf.toString();
}
@Override
protected boolean suspendTransaction(EjbInvocation inv) throws Exception {
// EJB2.0 section 7.5.7 says that ejbCreate/ejbRemove etc are called
// without a Tx. So suspend the client's Tx if any.
// Note: ejbRemove cannot be called when EJB is associated with
// a Tx, according to EJB2.0 section 7.6.4. This check is done in
// the container's implementation of removeBean().
return !inv.invocationInfo.isBusinessMethod;
}
@Override
protected boolean resumeTransaction(EjbInvocation inv) throws Exception {
return !inv.invocationInfo.isBusinessMethod;
}
@Override
public boolean scanForEjbCreateMethod() {
return true;
}
@Override
protected EjbMonitoringStatsProvider getMonitoringStatsProvider(String appName, String modName, String ejbName) {
return new StatelessSessionBeanStatsProvider(this, getContainerId(), appName, modName, ejbName);
}
@Override
protected void initializeHome() throws Exception {
super.initializeHome();
if (isRemote) {
if (hasRemoteHomeView) {
// Create theEJBObjectImpl
theEJBObjectImpl = instantiateEJBObjectImpl();
// connect the EJBObject to the ProtocolManager (creates the stub too).
// Note: cant do this in constructor above because
// beanId is not set at that time.
theEJBStub = (EJBObject) remoteHomeRefFactory.createRemoteReference(statelessInstanceKey);
theEJBObjectImpl.setStub(theEJBStub);
}
if (hasRemoteBusinessView) {
theRemoteBusinessObjectImpl = instantiateRemoteBusinessObjectImpl();
for (RemoteBusinessIntfInfo next : remoteBusinessIntfInfo.values()) {
java.rmi.Remote stub = next.referenceFactory.createRemoteReference(statelessInstanceKey);
theRemoteBusinessStubs.put(next.generatedRemoteIntf.getName(), stub);
theRemoteBusinessObjectImpl.setStub(next.generatedRemoteIntf.getName(), stub);
}
}
}
if (isLocal) {
if (hasLocalHomeView) {
theEJBLocalObjectImpl = instantiateEJBLocalObjectImpl();
}
if (hasLocalBusinessView) {
theEJBLocalBusinessObjectImpl = instantiateEJBLocalBusinessObjectImpl();
}
if (hasOptionalLocalBusinessView) {
theOptionalEJBLocalBusinessObjectImpl = instantiateOptionalEJBLocalBusinessObjectImpl();
}
}
createBeanPool();
registerMonitorableComponents();
}
protected void createBeanPool() {
ObjectFactory sessionCtxFactory = new SessionContextFactory();
iased = ejbDescriptor.getIASEjbExtraDescriptors();
if (iased != null) {
beanPoolDes = iased.getBeanPool();
}
poolProp = new PoolProperties(ejbContainer, beanPoolDes);
String val = ejbDescriptor.getEjbBundleDescriptor().getEnterpriseBeansProperty(SINGLETON_BEAN_POOL_PROP);
if (poolProp.maxWaitTimeInMillis != -1) {
pool = new BlockingPool( //
getContainerId(), ejbDescriptor.getName(), sessionCtxFactory, //
poolProp.steadyPoolSize, poolProp.poolResizeQuantity, poolProp.maxPoolSize, //
poolProp.poolIdleTimeoutInSeconds, loader, Boolean.parseBoolean(val), poolProp.maxWaitTimeInMillis);
} else {
pool = new NonBlockingPool( //
getContainerId(), ejbDescriptor.getName(), sessionCtxFactory, //
poolProp.steadyPoolSize, poolProp.poolResizeQuantity, poolProp.maxPoolSize, //
poolProp.poolIdleTimeoutInSeconds, loader, Boolean.parseBoolean(val));
}
}
@Override
protected void registerMonitorableComponents() {
super.registerMonitorableComponents();
poolProbeListener = new EjbPoolStatsProvider( //
pool, getContainerId(), containerInfo.appName, containerInfo.modName, containerInfo.ejbName);
poolProbeListener.register();
_logger.log(Level.FINE, "[SLSB Container] registered monitorable");
}
@Override
public void onReady() {
}
@Override
public EJBObjectImpl createRemoteBusinessObjectImpl() throws CreateException, RemoteException {
// No access check since this is an internal operation.
ejbBeanCreatedEvent();
return theRemoteBusinessObjectImpl;
}
private void ejbBeanCreatedEvent() {
ejbProbeNotifier.ejbBeanCreatedEvent( //
getContainerId(), containerInfo.appName, containerInfo.modName, containerInfo.ejbName);
}
@Override
public EJBObjectImpl createEJBObjectImpl() throws CreateException, RemoteException {
// Need to do access control check here because BaseContainer.preInvoke
// is not called for stateless sessionbean creates.
authorizeRemoteMethod(EJBHome_create);
ejbBeanCreatedEvent();
// For stateless EJBs, EJB2.0 Section 7.8 says that
// Home.create() need not do any real creation.
// If necessary, a stateless bean is created below during getContext().
return theEJBObjectImpl;
}
/**
* Called during client creation request through EJB LocalHome view.
*/
@Override
public EJBLocalObjectImpl createEJBLocalObjectImpl() throws CreateException {
// Need to do access control check here because BaseContainer.preInvoke
// is not called for stateless sessionbean creates.
authorizeLocalMethod(EJBLocalHome_create);
ejbBeanCreatedEvent();
// For stateless EJBs, EJB2.0 Section 7.8 says that
// Home.create() need not do any real creation.
// If necessary, a stateless bean is created below during getContext().
return theEJBLocalObjectImpl;
}
/**
* Called during internal creation of session bean
*/
@Override
public EJBLocalObjectImpl createEJBLocalBusinessObjectImpl(boolean localBeanView) throws CreateException {
ejbBeanCreatedEvent();
// No access checks needed because this is called as a result
// of an internal creation, not a user-visible create method.
return (localBeanView) ? theOptionalEJBLocalBusinessObjectImpl : theEJBLocalBusinessObjectImpl;
}
// Called from EJBObjectImpl.remove, EJBLocalObjectImpl.remove,
// EJBHomeImpl.remove(Handle).
@Override
protected void removeBean(EJBLocalRemoteObject ejbo, Method removeMethod, boolean local)
throws RemoveException, EJBException, RemoteException {
if (local) {
authorizeLocalMethod(BaseContainer.EJBLocalObject_remove);
} else {
authorizeRemoteMethod(BaseContainer.EJBObject_remove);
}
ejbProbeNotifier.ejbBeanDestroyedEvent( //
getContainerId(), containerInfo.appName, containerInfo.modName, containerInfo.ejbName);
}
/**
* Force destroy the EJB. Called from 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.
*/
@Override
protected void forceDestroyBean(EJBContextImpl sc) {
if (sc.getState() == EJBContextImpl.BeanState.DESTROYED) {
return;
}
// mark context as destroyed
sc.setState(EJBContextImpl.BeanState.DESTROYED);
//sessionCtxPool.destroyObject(sc);
pool.destroyObject(sc);
}
/**
* Called when a remote invocation arrives for an EJB.
*/
@Override
protected EJBObjectImpl getEJBObjectImpl(byte[] instanceKey) {
return theEJBObjectImpl;
}
@Override
EJBObjectImpl getEJBRemoteBusinessObjectImpl(byte[] instanceKey) {
return theRemoteBusinessObjectImpl;
}
/**
* Called from EJBLocalObjectImpl.getLocalObject() while deserializing
* a local object reference.
*/
@Override
protected EJBLocalObjectImpl getEJBLocalObjectImpl(Object key) {
return theEJBLocalObjectImpl;
}
/**
* Called from EJBLocalObjectImpl.getLocalObject() while deserializing
* a local business object reference.
*/
@Override
EJBLocalObjectImpl getEJBLocalBusinessObjectImpl(Object key) {
return theEJBLocalBusinessObjectImpl;
}
/**
* Called from EJBLocalObjectImpl.getLocalObject() while deserializing
* a local business object reference.
*/
@Override
EJBLocalObjectImpl getOptionalEJBLocalBusinessObjectImpl(Object key) {
return theOptionalEJBLocalBusinessObjectImpl;
}
/**
* Called from preInvoke which is called from the EJBObject
* for local and remote invocations.
*/
@Override
protected ComponentContext _getContext(EjbInvocation inv) {
try {
SessionContextImpl sessionCtx = (SessionContextImpl) pool.getObject(null);
sessionCtx.setState(EJBContextImpl.BeanState.INVOKING);
return sessionCtx;
} catch (Exception ex) {
throw new EJBException(ex);
}
}
@Override
protected SessionContextImpl _constructEJBContextImpl(Object instance) {
return new SessionContextImpl(instance, this);
}
/**
* called when an invocation arrives and there are no instances
* left to deliver the invocation to.
* Called from SessionContextFactory.create() !
*/
private SessionContextImpl createStatelessEJB() throws CreateException {
EjbInvocation ejbInv = null;
SessionContextImpl context;
try {
context = (SessionContextImpl) createEjbInstanceAndContext();
Object ejb = context.getEJB();
// this allows JNDI lookups from setSessionContext, ejbCreate
ejbInv = super.createEjbInvocation(ejb, context);
invocationManager.preInvoke(ejbInv);
// 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 context.setEJBStub
// because the bean is not allowed to do EJBContext.getEJBObject
setSessionContext(ejb, context);
// Perform injection right after where setSessionContext
// would be called. This is important since injection methods
// have the same "operations allowed" permissions as
// setSessionContext.
injectEjbInstance(context);
if (isRemote) {
if (hasRemoteHomeView) {
context.setEJBObjectImpl(theEJBObjectImpl);
context.setEJBStub(theEJBStub);
}
if (hasRemoteBusinessView) {
context.setEJBRemoteBusinessObjectImpl(theRemoteBusinessObjectImpl);
}
}
if (isLocal) {
if (hasLocalHomeView) {
context.setEJBLocalObjectImpl(theEJBLocalObjectImpl);
}
if (hasLocalBusinessView) {
context.setEJBLocalBusinessObjectImpl(theEJBLocalBusinessObjectImpl);
}
if (hasOptionalLocalBusinessView) {
context.setOptionalEJBLocalBusinessObjectImpl(theOptionalEJBLocalBusinessObjectImpl);
}
}
// all stateless beans have the same id and same InstanceKey
context.setInstanceKey(statelessInstanceKey);
//Call ejbCreate() or @PostConstruct method
intercept(CallbackType.POST_CONSTRUCT, context);
// Set the state to POOLED after ejbCreate so that
// EJBContext methods not allowed will throw exceptions
context.setState(EJBContextImpl.BeanState.POOLED);
} catch (Throwable th) {
_logger.log(Level.SEVERE, "ejb.stateless_ejbcreate_exception", logParams);
CreateException creEx = new CreateException("Could not create stateless EJB");
creEx.initCause(th);
throw creEx;
} finally {
if (ejbInv != null) {
invocationManager.postInvoke(ejbInv);
}
}
context.touch();
return context;
}
private void setSessionContext(Object ejb, SessionContextImpl context)
throws Exception {
if (ejb instanceof SessionBean) {
((SessionBean) ejb).setSessionContext(context);
}
}
@Override
protected void doTimerInvocationInit(EjbInvocation inv, Object primaryKey)
throws Exception {
if (isRemote) {
inv.isLocal = false;
} else {
inv.ejbObject = theEJBLocalObjectImpl;
inv.isLocal = true;
}
}
@Override
public boolean userTransactionMethodsAllowed(ComponentInvocation inv) {
boolean utMethodsAllowed = false;
if (isBeanManagedTran) {
if (inv instanceof EjbInvocation) {
EjbInvocation ejbInv = (EjbInvocation) inv;
EJBContextImpl sc = (EJBContextImpl) ejbInv.context;
// If Invocation, only ejbRemove not allowed.
utMethodsAllowed = !sc.isInEjbRemove();
} else {
// This will prevent setSessionContext/ejbCreate access
utMethodsAllowed = false;
}
}
return utMethodsAllowed;
}
/**
* Called from preInvoke which is called from the EJBObject
* for local and remote invocations.
*/
@Override
public void releaseContext(EjbInvocation inv) {
SessionContextImpl sc = (SessionContextImpl) inv.context;
// check if the bean was destroyed
if (sc.getState() == EJBContextImpl.BeanState.DESTROYED) {
return;
}
sc.setState(EJBContextImpl.BeanState.POOLED);
// prevent java.util.ConcurrentModificationException from JMS
// or others that hold on to invocation references, and thus possibly
// reference to the contexts that are out of scope
sc.resetResourceList();
// Stateless beans cant have transactions across invocations
sc.setTransaction(null);
sc.touch();
pool.returnObject(sc);
}
@Override
protected boolean isIdentical(EJBObjectImpl ejbo, EJBObject other) throws RemoteException {
if (other == ejbo.getStub()) {
return true;
}
try {
// other may be a stub for a remote object.
// Although all stateless sessionbeans for a bean type
// are identical, we dont know whether other is of the
// same bean type as ejbo.
return getProtocolManager().isIdentical(ejbo.getStub(), other);
} catch (Exception ex) {
if (_logger.isLoggable(Level.SEVERE)) {
_logger.log(Level.SEVERE, "ejb.ejb_getstub_exception", logParams);
_logger.log(Level.SEVERE, "", ex);
}
throw new RemoteException("Error during isIdentical.", ex);
}
}
/**
* Check if the given EJBObject/LocalObject has been removed.
* @exception NoSuchObjectLocalException if the object has been removed.
*/
@Override
protected void checkExists(EJBLocalRemoteObject ejbObj) {
// For stateless session beans, EJBObject/EJBLocalObj are never removed.
// So do nothing.
}
@Override
protected void afterBegin(EJBContextImpl context) {
// Stateless SessionBeans cannot implement SessionSynchronization!!
// EJB2.0 Spec 7.8.
}
@Override
protected void beforeCompletion(EJBContextImpl context) {
// Stateless SessionBeans cannot implement SessionSynchronization!!
// EJB2.0 Spec 7.8.
}
@Override
protected void afterCompletion(EJBContextImpl ctx, int status) {
// Stateless SessionBeans cannot implement SessionSynchronization!!
// EJB2.0 Spec 7.8.
// We dissociate the transaction from the bean in releaseContext above
}
// default
@Override
public boolean passivateEJB(ComponentContext context) {
return false;
}
/**
* @param ctx
* @param instanceKey
* @deprecated not called and not used in Payara 5
*/
@Deprecated
// default
public void activateEJB(Object ctx, Object instanceKey) {
// nothing to do
}
@Override
protected void doConcreteContainerShutdown(boolean appBeingUndeployed) {
try {
if (hasRemoteHomeView) {
// destroy EJBObject refs
// XXX invocations still in progress will get exceptions ??
remoteHomeRefFactory.destroyReference(theEJBObjectImpl.getStub(), theEJBObjectImpl.getEJBObject());
}
if (hasRemoteBusinessView) {
for (RemoteBusinessIntfInfo next : remoteBusinessIntfInfo.values()) {
next.referenceFactory.destroyReference(
theRemoteBusinessObjectImpl.getStub(next.generatedRemoteIntf.getName()),
theRemoteBusinessObjectImpl.getEJBObject(next.generatedRemoteIntf.getName()));
}
}
if (pool != null) {
pool.close();
poolProbeListener.unregister();
}
} catch (Throwable t) {
_logger.log(Level.FINE, "Exception during conrete StatelessSessionBean cleanup", t);
}
}
public long getMethodReadyCount() {
return pool.getSize();
}
protected class SessionContextFactory implements ObjectFactory {
@Override
public Object create(Object param) {
try {
return createStatelessEJB();
} catch (CreateException ex) {
throw new EJBException(ex);
}
}
@Override
public void destroy(Object obj) {
SessionContextImpl sessionCtx = (SessionContextImpl) obj;
// Note: stateless SessionBeans cannot have incomplete transactions
// in progress. So it is ok to destroy the EJB.
Object sb = sessionCtx.getEJB();
if (sessionCtx.getState() != EJBContextImpl.BeanState.DESTROYED) {
//Called from pool implementation to reduce the pool size.
//So need to call ejb.ejbRemove()
// mark context as destroyed
sessionCtx.setState(EJBContextImpl.BeanState.DESTROYED);
EjbInvocation ejbInv = null;
try {
// NOTE : Context class-loader is already set by Pool
ejbInv = createEjbInvocation(sb, sessionCtx);
invocationManager.preInvoke(ejbInv);
sessionCtx.setInEjbRemove(true);
intercept(CallbackType.PRE_DESTROY, sessionCtx);
} catch ( Throwable t ) {
_logger.log(Level.FINE, "ejbRemove exception", t);
} finally {
sessionCtx.setInEjbRemove(false);
if( ejbInv != null ) {
invocationManager.postInvoke(ejbInv);
}
}
} else {
//Called from forceDestroyBean
//So NO need to call ejb.ejbRemove()
// mark the context's transaction for rollback
Transaction tx = sessionCtx.getTransaction();
try {
if ( (tx != null) &&
(tx.getStatus() != Status.STATUS_NO_TRANSACTION ) ) {
tx.setRollbackOnly();
}
} catch ( Exception ex ) {
_logger.log(Level.FINE,"forceDestroyBean exception", ex);
}
}
cleanupInstance(sessionCtx);
// tell the TM to release resources held by the bean
transactionManager.componentDestroyed(sessionCtx);
sessionCtx.setTransaction(null);
sessionCtx.deleteAllReferences();
}
} // SessionContextFactory{}
private static class PoolProperties {
int maxPoolSize;
int maxWaitTimeInMillis;
int poolIdleTimeoutInSeconds;
int poolResizeQuantity;
int steadyPoolSize;
public PoolProperties(EjbContainer ejbContainer, BeanPoolDescriptor beanPoolDes) {
maxWaitTimeInMillis = Integer.parseInt(ejbContainer.getMaxWaitTimeInMillis());
if (!Boolean.parseBoolean(ejbContainer.getLimitInstancesEnabled())) {
maxWaitTimeInMillis = -1;
}
maxPoolSize = Integer.parseInt(ejbContainer.getMaxPoolSize());
poolIdleTimeoutInSeconds = Integer.parseInt(ejbContainer.getPoolIdleTimeoutInSeconds());
poolResizeQuantity = Integer.parseInt(ejbContainer.getPoolResizeQuantity());
steadyPoolSize = Integer.parseInt(ejbContainer.getSteadyPoolSize());
if (beanPoolDes != null) {
int temp;
if ((temp = beanPoolDes.getMaxPoolSize()) != -1) {
maxPoolSize = temp;
}
if ((temp = beanPoolDes.getPoolIdleTimeoutInSeconds()) != -1) {
poolIdleTimeoutInSeconds = temp;
}
if ((temp = beanPoolDes.getPoolResizeQuantity()) != -1) {
poolResizeQuantity = temp;
}
if ((temp = beanPoolDes.getSteadyPoolSize()) != -1) {
steadyPoolSize = temp;
}
if ((temp = beanPoolDes.getMaxWaitTimeInMillis()) != -1) {
maxWaitTimeInMillis = temp;
}
}
}
} // PoolProperties{}
//Methods for StatelessSessionBeanStatsProvider
public int getMaxPoolSize() {
return (poolProp.maxPoolSize <= 0) ? Integer.MAX_VALUE : poolProp.maxPoolSize;
}
public int getSteadyPoolSize() {
return (poolProp.steadyPoolSize <= 0) ? 0 : poolProp.steadyPoolSize;
}
} // StatelessSessionContainer.java