Package com.sun.ejb.containers

Source Code of com.sun.ejb.containers.StatelessSessionContainer$PoolProperties

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. 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.html
* or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [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.
*/
package com.sun.ejb.containers;

import java.util.Collection;
import java.util.Iterator;
import java.util.logging.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import java.lang.reflect.Method;
import java.rmi.Remote;
import java.rmi.RemoteException;

import javax.ejb.*;
import javax.transaction.*;
import javax.rmi.PortableRemoteObject;

import com.sun.ejb.*;

import com.sun.ejb.containers.util.pool.*;

import com.sun.enterprise.util.Utility;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.*;
import com.sun.enterprise.deployment.*;
import static com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType;
import com.sun.enterprise.deployment.runtime.BeanPoolDescriptor;
import com.sun.enterprise.deployment.runtime.BeanCacheDescriptor;
import com.sun.enterprise.deployment.ServiceReferenceDescriptor;
import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;

import com.sun.enterprise.webservice.EjbRuntimeEndpointInfo;
import com.sun.enterprise.webservice.WebServiceEjbEndpointRegistry;
import com.sun.enterprise.webservice.ServiceInterfaceGenerator;
import com.sun.enterprise.webservice.WsUtil;
import com.sun.enterprise.webservice.ClientPipeCloser;
import java.lang.reflect.Proxy;

import com.sun.enterprise.log.Log;

import com.sun.logging.*;

import com.sun.enterprise.admin.monitor.*;
import com.sun.enterprise.config.ConfigException;
import com.sun.enterprise.config.serverbeans.*;
import com.sun.enterprise.server.ServerContext;
import com.sun.enterprise.server.ApplicationServer;
import com.sun.enterprise.util.io.FileUtils;

import com.sun.enterprise.appverification.factory.AppVerification;
import com.sun.enterprise.admin.monitor.callflow.ComponentType;

import com.sun.ejb.spi.stats.StatelessSessionBeanStatsProvider;

/** 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.
* <P>
* The 3 states of a Stateless EJB (an EJB can be in only 1 state at a time):
* 1. POOLED : ready for invocations, no transaction in progress
* 2. INVOKING : processing an invocation
* 3. DESTROYED : does not exist 
* <P>
* 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.
* <P>
* A Stateless Bean can hold open DB connections across invocations.
* Its assumed that the Resource Manager can handle
* multiple incomplete transactions on the same
* connection.
*
*/   

public final class StatelessSessionContainer
    extends BaseContainer
    implements StatelessSessionBeanStatsProvider
{
   
    private static final Logger _logger =
        LogDomains.getLogger(LogDomains.EJB_LOGGER);

    private static LocalStringManagerImpl localStrings =
  new LocalStringManagerImpl(StatelessSessionContainer.class);

    private static final int POOLED=1, INVOKING=2, DESTROYED=3;
    private static final int LOW_WATER_MARK = 100;

    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.
    private Method homeCreateMethod    = null;
    private Method localHomeCreateMethod = null;

    // 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;

    // Data members for RemoteHome view
    private EJBObjectImpl theEJBObjectImpl = null;
    private EJBObject theEJBObject = 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 java.rmi.Remote theRemoteBusinessObject = null;
    private Map<String, java.rmi.Remote> theRemoteBusinessStubs =
        new HashMap<String, java.rmi.Remote>();

    // Information about a web service ejb endpoint.  Used as a conduit
    // between webservice runtime and ejb container.  Contains a Remote
    // servant used by jaxrpc to call web service business method.
    private EjbRuntimeEndpointInfo webServiceEndpoint;


  private boolean isPoolClosed = false;   
  protected AbstractPool pool;

    private IASEjbExtraDescriptors iased    = null;
    private BeanCacheDescriptor beanCacheDes = null;
    private BeanPoolDescriptor beanPoolDes   = null;
    private Server svr              = null;
    private Config cfg              = 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)
  throws Exception
    {
        super(desc, loader);


        try {
            // get the ejbCreate method for stateless beans
            if ( hasLocalHomeView ) {
                localHomeCreateMethod =
                    localHomeIntf.getMethod("create", NO_PARAMS);
            }
            if ( hasRemoteHomeView ) {
                homeCreateMethod =
                    homeIntf.getMethod("create", NO_PARAMS);
            }
        } catch (Exception ex) {
            if(_logger.isLoggable(Level.SEVERE)) {
                _logger.log(Level.SEVERE,
                    "ejb.get_ejbcreate_method_exception",logParams);
                _logger.log(Level.SEVERE,"",ex);
            }
            throw ex;
        }

        EjbSessionDescriptor ed = (EjbSessionDescriptor)desc;
        iased = ed.getIASEjbExtraDescriptors();
        if( iased != null) {
            beanPoolDes = iased.getBeanPool();
        }
        try {
            ServerContext sc = ApplicationServer.getServerContext();
            //ROB: config changes
            //svr = ServerBeansFactory.getServerBean(sc.getConfigContext());
            cfg = ServerBeansFactory.getConfigBean(sc.getConfigContext());
        catch (ConfigException ex) {
            ex.printStackTrace();
        }
     //ROB: config changes
        //ejbContainer = svr.getEjbContainer();
      ejbContainer = cfg.getEjbContainer();

        super.setMonitorOn(ejbContainer.isMonitoringEnabled());

        super.createCallFlowAgent(ComponentType.SLSB);
    }

    public String getMonitorAttributeValues() {
        StringBuffer sbuf = new StringBuffer();
        sbuf.append("STATELESS ").append(ejbDescriptor.getName());
        sbuf.append(pool.getAllAttrValues());
        sbuf.append("]");

        return sbuf.toString();
    }

    protected void initializeHome()
        throws Exception
    {

        super.initializeHome();

        if ( isRemote ) {

            if( hasRemoteHomeView ) {
                // Create theEJBObjectImpl
                theEJBObjectImpl = instantiateEJBObjectImpl();
                theEJBObject = (EJBObject) theEJBObjectImpl.getEJBObject();
               
                // connect the EJBObject to the ProtocolManager
                // (creates the stub
                // too). Note: cant do this in constructor above because
                // containerId is not set at that time.
                theEJBStub = (EJBObject)
                    remoteHomeRefFactory.createRemoteReference
                       (statelessInstanceKey);
               
                theEJBObjectImpl.setStub(theEJBStub);
            }

            if( hasRemoteBusinessView ) {

                theRemoteBusinessObjectImpl =
                    instantiateRemoteBusinessObjectImpl();

                theRemoteBusinessObject =
                    theRemoteBusinessObjectImpl.getEJBObject();
               
                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();
            }
        }
        ObjectFactory sessionCtxFactory = new SessionContextFactory();
        poolProp = new PoolProperties();
        pool= new NonBlockingPool(ejbDescriptor.getName(),
           sessionCtxFactory, poolProp.steadyPoolSize,
           poolProp.poolResizeQuantity, poolProp.maxPoolSize,
           poolProp.poolIdleTimeoutInSeconds, loader);

       registerMonitorableComponents();
    }

    public void initializeWebService() throws Exception {

        if( isWebServiceEndpoint ) {

            EjbBundleDescriptor bundle =
                ejbDescriptor.getEjbBundleDescriptor();
            WebServicesDescriptor webServices = bundle.getWebServices();
            Collection myEndpoints =
                webServices.getEndpointsImplementedBy(ejbDescriptor);
            //FindBugs [Deadstore] Long ejbId = new Long(ejbDescriptor.getUniqueId());
           
            // An ejb can only be exposed through 1 web service endpoint
            Iterator iter = myEndpoints.iterator();
            com.sun.enterprise.deployment.WebServiceEndpoint next =
           (com.sun.enterprise.deployment.WebServiceEndpoint) iter.next();

            Class serviceEndpointIntfClass =
                    loader.loadClass(next.getServiceEndpointInterface());           

            if (!serviceEndpointIntfClass.isInterface()) {
                ServiceInterfaceGenerator generator = new ServiceInterfaceGenerator(loader, ejbClass);
                serviceEndpointIntfClass = WsUtil.generateAndLoad(generator, loader);
                if (serviceEndpointIntfClass==null) {
                    throw new RuntimeException("Error generating the SEI");
                }
            }
           
            Class tieClass=null;
           
            WebServiceInvocationHandler invocationHandler =
                    new WebServiceInvocationHandler(ejbClass, next,
                                                    serviceEndpointIntfClass,
                    webServiceInvocationInfoMap);
           
           
            invocationHandler.setContainer(this);
            Object servant = (Object) Proxy.newProxyInstance
                    (loader, new Class[] { serviceEndpointIntfClass },
                    invocationHandler);
           
            // starting in 2.0, there is no more generated Ties
            if (next.getTieClassName()!=null) {               
                tieClass = loader.loadClass(next.getTieClassName());               
            }
                   
            webServiceEndpoint = WebServiceEjbEndpointRegistry.getRegistry().createEjbEndpointInfo(next, this, servant, tieClass);
                                          
            WebServiceEjbEndpointRegistry.getRegistry().
                registerEjbWebServiceEndpoint(webServiceEndpoint);
        }
     
    }

    protected void registerMonitorableComponents() {
  registryMediator.registerProvider(this);
  registryMediator.registerProvider(pool);
        super.registerMonitorableComponents();
  super.populateMethodMonitorMap();
        _logger.log(Level.FINE, "[SLSB Container] registered monitorable");
    }

    public void onReady() {
    }

    public EJBObjectImpl createRemoteBusinessObjectImpl()
        throws CreateException, RemoteException
    {
        // No access check since this is an internal operation.

  statCreateCount++;

        return theRemoteBusinessObjectImpl;
    }

 
    /**
     *
     */
    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);

        if ( AppVerification.doInstrument() ) {
            AppVerification.getInstrumentLogger().doInstrumentForEjb(
                ejbDescriptor, homeCreateMethod, null);
        }

  statCreateCount++;

        // 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.
     */
    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);

        if ( AppVerification.doInstrument() ) {
            AppVerification.getInstrumentLogger().doInstrumentForEjb(
                ejbDescriptor, localHomeCreateMethod, null);
        }

        // 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
     */
    public EJBLocalObjectImpl createEJBLocalBusinessObjectImpl()
        throws CreateException
   
        // No access checks needed because this is called as a result
        // of an internal creation, not a user-visible create method.
        return theEJBLocalBusinessObjectImpl;
    }


    // Called from EJBObjectImpl.remove, EJBLocalObjectImpl.remove,
    // EJBHomeImpl.remove(Handle).
    void removeBean(EJBLocalRemoteObject ejbo, Method removeMethod,
      boolean local)
  throws RemoveException, EJBException, RemoteException
    {
        if( local ) {
            authorizeLocalMethod(BaseContainer.EJBLocalObject_remove);
        } else {
            authorizeRemoteMethod(BaseContainer.EJBObject_remove);
        }
  statRemoveCount++;
    }

    /**
     * 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.
     */
    void forceDestroyBean(EJBContextImpl sc) {
        if ( sc.getState() == DESTROYED )
                return;

        // mark context as destroyed
        sc.setState(DESTROYED);

        //sessionCtxPool.destroyObject(sc);
        pool.destroyObject(sc);
    }


    /**
     * Called when a remote invocation arrives for an EJB.
     */
    EJBObjectImpl getEJBObjectImpl(byte[] instanceKey) {
        return theEJBObjectImpl;
    }
   
    EJBObjectImpl getEJBRemoteBusinessObjectImpl(byte[] instanceKey) {
        return theRemoteBusinessObjectImpl;
    }

    /**
    * Called from EJBLocalObjectImpl.getLocalObject() while deserializing
    * a local object reference.
    */
    EJBLocalObjectImpl getEJBLocalObjectImpl(Object key) {
        return theEJBLocalObjectImpl;
    }

    /**
    * Called from EJBLocalObjectImpl.getLocalObject() while deserializing
    * a local business object reference.
    */
    EJBLocalObjectImpl getEJBLocalBusinessObjectImpl(Object key) {
        return theEJBLocalBusinessObjectImpl;
    }


    /**
    * Called from preInvoke which is called from the EJBObject
    * for local and remote invocations.
    */
    protected ComponentContext _getContext(Invocation inv) {
        try {
            SessionContextImpl sessionCtx =
                (SessionContextImpl) pool.getObject(null);
            sessionCtx.setState(INVOKING);
            return sessionCtx;
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }


    /**
    * 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
    {
        CreateException creEx = null;
        Method invokedMethod = null;
        ComponentInvocation ci = null;
        SessionContextImpl context;

        try {
            // create new stateless EJB
            Object ejb = ejbClass.newInstance();

            // create SessionContext and set it in the EJB
            context = new SessionContextImpl(ejb, this);
            context.setInterceptorInstances(
                    interceptorManager.createInterceptorInstances());
           
            // this allows JNDI lookups from setSessionContext, ejbCreate
            ci = new ComponentInvocation(ejb, this, context);
            invocationManager.preInvoke(ci);

            // 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
            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);
            }

            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);
                }
            }

            // all stateless beans have the same id and same InstanceKey
            context.setInstanceKey(statelessInstanceKey);
            if (ejbMethodStatsManager.isMethodMonitorOn()) {
                invokedMethod = (isLocal) ? localHomeCreateMethod : homeCreateMethod;
                ejbMethodStatsManager.preInvoke(invokedMethod);
            }
            //Call ejbCreate() or @PostConstruct method
            interceptorManager.intercept(
                    CallbackType.POST_CONSTRUCT, context);

            // Set the state to POOLED after ejbCreate so that
            // EJBContext methods not allowed will throw exceptions
            context.setState(POOLED);
        } catch ( Throwable th ) {
            _logger.log(Level.INFO, "ejb.stateless_ejbcreate_exception", th);
            creEx = new CreateException("Could not create stateless EJB");
            creEx.initCause(th);
            throw creEx;
        } finally {
            if ((invokedMethod != null) && (ejbMethodStatsManager.isMethodMonitorOn())) {
                ejbMethodStatsManager.postInvoke(invokedMethod, creEx);
            }
            if ( ci != null ) {
                invocationManager.postInvoke(ci);
            }
        }
        context.touch();
        return context;
    }

    void doTimerInvocationInit(Invocation inv, RuntimeTimerState timerState)
        throws Exception
  {
        if( isRemote ) {
            inv.ejbObject = theEJBObjectImpl;
            inv.isLocal = false;
        } else {
            inv.ejbObject = theEJBLocalObjectImpl;
            inv.isLocal = true;
        }
    }

    public boolean userTransactionMethodsAllowed(ComponentInvocation inv) {
        boolean utMethodsAllowed = false;
        if( isBeanManagedTran ) {
            if( inv instanceof Invocation ) {
                Invocation i = (Invocation) inv;
                EJBContextImpl sc = (EJBContextImpl) i.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.
     */
    public void releaseContext(Invocation inv) {
        SessionContextImpl sc = (SessionContextImpl)inv.context;

        // check if the bean was destroyed
        if ( sc.getState()==DESTROYED )
            return;

            sc.setState(POOLED);

            // Stateless beans cant have transactions across invocations
            sc.setTransaction(null);
            sc.touch();

            pool.returnObject(sc);
    }


    boolean isIdentical(EJBObjectImpl ejbo, EJBObject other)
        throws RemoteException
    {
        if ( other == ejbo.getStub() ) {
            return true;
        }else {
            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.
                if ( protocolMgr.isIdentical(ejbo.getStub(), other) )
                        return true;
                else
                        return false;
            } 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.
    */
    void checkExists(EJBLocalRemoteObject ejbObj)
    {
        // For stateless session beans, EJBObject/EJBLocalObj are never removed.
        // So do nothing.
    }


    void afterBegin(EJBContextImpl context) {
        // Stateless SessionBeans cannot implement SessionSynchronization!!
        // EJB2.0 Spec 7.8.
    }

    void beforeCompletion(EJBContextImpl context) {
        // Stateless SessionBeans cannot implement SessionSynchronization!!
        // EJB2.0 Spec 7.8.
    }

    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
    public boolean passivateEJB(ComponentContext context) {
        return false;
    }  
   
    // default
    public void activateEJB(Object ctx, Object instanceKey) {}

    public void appendStats(StringBuffer sbuf) {
  sbuf.append("\nStatelessContainer: ")
      .append("CreateCount=").append(statCreateCount).append("; ")
      .append("RemoveCount=").append(statRemoveCount).append("; ")
      .append("]");
    }

    public void undeploy() {
        //Change the container state to ensure that all new invocations will be rejected
        super.setUndeployedState();

        try {
            if( isWebServiceEndpoint && (webServiceEndpoint != null) ) {
                String endpointAddress =
                    webServiceEndpoint.getEndpointAddressUri();
                WebServiceEjbEndpointRegistry.getRegistry().
                    unregisterEjbWebServiceEndpoint(endpointAddress);
            }
           
            EjbBundleDescriptor desc = ejbDescriptor.getEjbBundleDescriptor();
            if (desc != null && desc.getServiceReferenceDescriptors()!= null) {
                for (Object srd : desc.getServiceReferenceDescriptors()) {
                    ClientPipeCloser.getInstance()
                    .cleanupClientPipe((ServiceReferenceDescriptor)srd);
                }
            }
           
            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()));
                }
            }

            isPoolClosed = true;

            pool.close();

        } finally {
            super.undeploy();

            this.homeCreateMethod      = null;
            this.localHomeCreateMethod = null;
            this.theEJBLocalObjectImpl = null;
            this.theEJBObjectImpl      = null;
            this.theEJBStub            = null;
            this.pool                  = null;
            this.iased                 = null;
            this.beanCacheDes          = null;
            this.beanPoolDes           = null;
            this.svr                   = null;
            this.ejbContainer          = null;
            this.poolProp              = null;

        }
    }

    public long getMethodReadyCount() {
  return pool.getSize();
    }

    private class SessionContextFactory
        implements ObjectFactory
    {

        public Object create(Object param) {
            try {
                    return createStatelessEJB();
            } catch (CreateException ex) {
                    throw new EJBException(ex);
            }
        }

        public void destroy(Object obj) {
            boolean methodCalled = false; //for monitoring  
           
            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() != DESTROYED) {
                //Called from pool implementation to reduce the pool size.
                //So need to call ejb.ejbRemove()
                // mark context as destroyed
                sessionCtx.setState(DESTROYED);
                Invocation inv = null;
                try {
                    // NOTE : Context class-loader is already set by Pool
                    inv = new Invocation(sb, StatelessSessionContainer.this);
                    inv.context = sessionCtx;
                    if (ejbMethodStatsManager.isMethodMonitorOn()){
                        methodCalled = true;
                        ejbMethodStatsManager.preInvoke(inv.method);
                    }
                    invocationManager.preInvoke(inv);
                    sessionCtx.setInEjbRemove(true);       
  
                    interceptorManager.intercept(
                            CallbackType.PRE_DESTROY, sessionCtx);

                } catch ( Throwable t ) {
                     _logger.log(Level.FINE, "ejbRemove exception", t);
                } finally {
                    sessionCtx.setInEjbRemove(false);
                    if( inv != null ) {
                       if (methodCalled && (ejbMethodStatsManager.isMethodMonitorOn())) {
                            ejbMethodStatsManager.postInvoke(inv.method, inv.exception);
                        }                       
                        invocationManager.postInvoke(inv);
                    }
                }
            } 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);
                }
            }

            // tell the TM to release resources held by the bean
            transactionManager.ejbDestroyed(sessionCtx);

            sessionCtx.setTransaction(null);

            sessionCtx.deleteAllReferences();
            sessionCtx = null;
        }
    } // SessionContextFactory{}

    private class PoolProperties {
        int maxPoolSize;
        int poolIdleTimeoutInSeconds;
        int poolResizeQuantity;
        int steadyPoolSize;

        public PoolProperties() {

            maxPoolSize = new Integer(ejbContainer.getMaxPoolSize()).intValue();
            poolIdleTimeoutInSeconds = new Integer(
                ejbContainer.getPoolIdleTimeoutInSeconds()).intValue();
            poolResizeQuantity = new Integer(
                ejbContainer.getPoolResizeQuantity()).intValue();
            steadyPoolSize = new Integer(
                ejbContainer.getSteadyPoolSize()).intValue();
            if(beanPoolDes != null) {
                int temp = 0;
                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;
                }
            }
        }
    } // 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
TOP

Related Classes of com.sun.ejb.containers.StatelessSessionContainer$PoolProperties

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.