KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > ejb > containers > StatelessSessionContainer


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.ejb.containers;
24
25 import java.util.Collection JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.logging.*;
28 import java.util.HashMap JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Vector JavaDoc;
31
32 import java.lang.reflect.Method JavaDoc;
33 import java.rmi.Remote JavaDoc;
34 import java.rmi.RemoteException JavaDoc;
35
36 import javax.ejb.*;
37 import javax.transaction.*;
38 import javax.rmi.PortableRemoteObject JavaDoc;
39
40 import com.sun.ejb.*;
41
42 import com.sun.ejb.containers.util.pool.*;
43
44 import com.sun.enterprise.util.Utility;
45 import com.sun.enterprise.util.LocalStringManagerImpl;
46 import com.sun.enterprise.*;
47 import com.sun.enterprise.deployment.*;
48 import static com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType;
49 import com.sun.enterprise.deployment.runtime.BeanPoolDescriptor;
50 import com.sun.enterprise.deployment.runtime.BeanCacheDescriptor;
51 import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;
52
53 import com.sun.enterprise.webservice.EjbRuntimeEndpointInfo;
54 import com.sun.enterprise.webservice.WebServiceEjbEndpointRegistry;
55 import com.sun.enterprise.webservice.ServiceInterfaceGenerator;
56 import com.sun.enterprise.webservice.WsUtil;
57 import java.lang.reflect.Proxy JavaDoc;
58
59 import com.sun.enterprise.log.Log;
60
61 import com.sun.logging.*;
62
63 import com.sun.enterprise.admin.monitor.*;
64 import com.sun.enterprise.config.ConfigException;
65 import com.sun.enterprise.config.serverbeans.*;
66 import com.sun.enterprise.server.ServerContext;
67 import com.sun.enterprise.server.ApplicationServer;
68 import com.sun.enterprise.util.io.FileUtils;
69
70 import com.sun.enterprise.appverification.factory.AppVerification;
71 import com.sun.enterprise.admin.monitor.callflow.ComponentType;
72
73 import com.sun.ejb.spi.stats.StatelessSessionBeanStatsProvider;
74
75 /** This class provides container functionality specific to stateless
76  * SessionBeans.
77  * At deployment time, one instance of the StatelessSessionContainer is created
78  * for each stateless SessionBean type (i.e. deployment descriptor) in a JAR.
79  * <P>
80  * The 3 states of a Stateless EJB (an EJB can be in only 1 state at a time):
81  * 1. POOLED : ready for invocations, no transaction in progress
82  * 2. INVOKING : processing an invocation
83  * 3. DESTROYED : does not exist
84  * <P>
85  * This container services invocations using a pool of EJB instances.
86  * An instance is returned to the pool immediately after the invocation
87  * completes, so the # of instances needed = # of concurrent invocations.
88  * <P>
89  * A Stateless Bean can hold open DB connections across invocations.
90  * Its assumed that the Resource Manager can handle
91  * multiple incomplete transactions on the same
92  * connection.
93  *
94  */

95
96 public final class StatelessSessionContainer
97     extends BaseContainer
98     implements StatelessSessionBeanStatsProvider
99 {
100     
101     private static Logger _logger;
102     static {
103         _logger=LogDomains.getLogger(LogDomains.EJB_LOGGER);
104         _logger.log(Level.FINE," Loading StatelessSessionContainer...");
105     }
106
107     private static LocalStringManagerImpl localStrings =
108     new LocalStringManagerImpl(StatelessSessionContainer.class);
109
110     private static final int POOLED=1, INVOKING=2, DESTROYED=3;
111     private static final int LOW_WATER_MARK = 100;
112
113     private static final byte[] statelessInstanceKey = {0, 0, 0, 1};
114
115     // All stateless EJBs have the same instanceKey, since all stateless EJBs
116
// are identical. Note: the first byte of instanceKey must be left empty.
117
private Method JavaDoc homeCreateMethod = null;
118     private Method JavaDoc localHomeCreateMethod = null;
119
120     // All stateless EJB instances of a particular class (i.e. all bean
121
// instances created by this container instance) have the same
122
// EJBObject/EJBLocalObject instance since they are all identical.
123
private EJBLocalObjectImpl theEJBLocalObjectImpl = null;
124     private EJBLocalObjectImpl theEJBLocalBusinessObjectImpl = null;
125
126     // Data members for RemoteHome view
127
private EJBObjectImpl theEJBObjectImpl = null;
128     private EJBObject theEJBObject = null;
129     private EJBObject theEJBStub = null;
130
131     // Data members for Remote business view. Any objects representing the
132
// Remote business interface are not subtypes of EJBObject.
133
private EJBObjectImpl theRemoteBusinessObjectImpl = null;
134     private java.rmi.Remote JavaDoc theRemoteBusinessObject = null;
135     private Map JavaDoc<String JavaDoc, java.rmi.Remote JavaDoc> theRemoteBusinessStubs =
136         new HashMap JavaDoc<String JavaDoc, java.rmi.Remote JavaDoc>();
137
138     // Information about a web service ejb endpoint. Used as a conduit
139
// between webservice runtime and ejb container. Contains a Remote
140
// servant used by jaxrpc to call web service business method.
141
private EjbRuntimeEndpointInfo webServiceEndpoint;
142
143
144     private boolean isPoolClosed = false;
145     protected AbstractPool pool;
146
147     private IASEjbExtraDescriptors iased = null;
148     private BeanCacheDescriptor beanCacheDes = null;
149     private BeanPoolDescriptor beanPoolDes = null;
150     private Server svr = null;
151     private Config cfg = null;
152     private EjbContainer ejbContainer = null;
153
154     private PoolProperties poolProp = null;
155
156     /**
157      * This constructor is called from the JarManager when a Jar is deployed.
158      * @exception Exception on error
159      */

160     StatelessSessionContainer(EjbDescriptor desc, ClassLoader JavaDoc loader)
161     throws Exception JavaDoc
162     {
163         super(desc, loader);
164
165
166         try {
167             // get the ejbCreate method for stateless beans
168
if ( hasLocalHomeView ) {
169                 localHomeCreateMethod =
170                     localHomeIntf.getMethod("create", NO_PARAMS);
171             }
172             if ( hasRemoteHomeView ) {
173                 homeCreateMethod =
174                     homeIntf.getMethod("create", NO_PARAMS);
175             }
176         } catch (Exception JavaDoc ex) {
177             if(_logger.isLoggable(Level.SEVERE)) {
178                 _logger.log(Level.SEVERE,
179                     "ejb.get_ejbcreate_method_exception",logParams);
180                 _logger.log(Level.SEVERE,"",ex);
181             }
182             throw ex;
183         }
184
185         EjbSessionDescriptor ed = (EjbSessionDescriptor)desc;
186         iased = ed.getIASEjbExtraDescriptors();
187         if( iased != null) {
188             beanPoolDes = iased.getBeanPool();
189         }
190         try {
191             ServerContext sc = ApplicationServer.getServerContext();
192             //ROB: config changes
193
//svr = ServerBeansFactory.getServerBean(sc.getConfigContext());
194
cfg = ServerBeansFactory.getConfigBean(sc.getConfigContext());
195         } catch (ConfigException ex) {
196             ex.printStackTrace();
197         }
198        //ROB: config changes
199
//ejbContainer = svr.getEjbContainer();
200
ejbContainer = cfg.getEjbContainer();
201
202         super.setMonitorOn(ejbContainer.isMonitoringEnabled());
203
204         super.createCallFlowAgent(ComponentType.SLSB);
205     }
206
207     public String JavaDoc getMonitorAttributeValues() {
208         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
209         sbuf.append("STATELESS ").append(ejbDescriptor.getName());
210         sbuf.append(pool.getAllAttrValues());
211         sbuf.append("]");
212
213         return sbuf.toString();
214     }
215
216     protected void initializeHome()
217         throws Exception JavaDoc
218     {
219
220         super.initializeHome();
221
222         if ( isRemote ) {
223
224             if( hasRemoteHomeView ) {
225                 // Create theEJBObjectImpl
226
theEJBObjectImpl = instantiateEJBObjectImpl();
227                 theEJBObject = (EJBObject) theEJBObjectImpl.getEJBObject();
228                 
229                 // connect the EJBObject to the ProtocolManager
230
// (creates the stub
231
// too). Note: cant do this in constructor above because
232
// containerId is not set at that time.
233
theEJBStub = (EJBObject)
234                     remoteHomeRefFactory.createRemoteReference
235                        (statelessInstanceKey);
236                 
237                 theEJBObjectImpl.setStub(theEJBStub);
238             }
239
240             if( hasRemoteBusinessView ) {
241
242                 theRemoteBusinessObjectImpl =
243                     instantiateRemoteBusinessObjectImpl();
244
245                 theRemoteBusinessObject =
246                     theRemoteBusinessObjectImpl.getEJBObject();
247                 
248                 for(RemoteBusinessIntfInfo next :
249                         remoteBusinessIntfInfo.values()) {
250                     java.rmi.Remote JavaDoc stub = next.referenceFactory.
251                         createRemoteReference(statelessInstanceKey);
252                     theRemoteBusinessStubs.put
253                         (next.generatedRemoteIntf.getName(), stub);
254                     theRemoteBusinessObjectImpl.setStub
255                         (next.generatedRemoteIntf.getName(), stub);
256                 }
257
258             }
259
260         }
261
262         if ( isLocal ) {
263             if( hasLocalHomeView ) {
264                 theEJBLocalObjectImpl = instantiateEJBLocalObjectImpl();
265             }
266             if( hasLocalBusinessView ) {
267                 theEJBLocalBusinessObjectImpl =
268                     instantiateEJBLocalBusinessObjectImpl();
269             }
270         }
271
272         if( isWebServiceEndpoint ) {
273
274             EjbBundleDescriptor bundle =
275                 ejbDescriptor.getEjbBundleDescriptor();
276             WebServicesDescriptor webServices = bundle.getWebServices();
277             Collection JavaDoc myEndpoints =
278                 webServices.getEndpointsImplementedBy(ejbDescriptor);
279             Long JavaDoc ejbId = new Long JavaDoc(ejbDescriptor.getUniqueId());
280             
281             // An ejb can only be exposed through 1 web service endpoint
282
Iterator JavaDoc iter = myEndpoints.iterator();
283             com.sun.enterprise.deployment.WebServiceEndpoint next =
284                     (com.sun.enterprise.deployment.WebServiceEndpoint) iter.next();
285
286             Class JavaDoc serviceEndpointIntfClass =
287                     loader.loadClass(next.getServiceEndpointInterface());
288
289             if (!serviceEndpointIntfClass.isInterface()) {
290                 ServiceInterfaceGenerator generator = new ServiceInterfaceGenerator(loader, ejbClass);
291                 serviceEndpointIntfClass = WsUtil.generateAndLoad(generator, loader);
292                 if (serviceEndpointIntfClass==null) {
293                     throw new RuntimeException JavaDoc("Error generating the SEI");
294                 }
295             }
296             
297             Class JavaDoc tieClass=null;
298             
299             WebServiceInvocationHandler invocationHandler =
300                     new WebServiceInvocationHandler(ejbClass, next,
301                                                     serviceEndpointIntfClass,
302                     webServiceInvocationInfoMap);
303             
304             
305             invocationHandler.setContainer(this);
306             Object JavaDoc servant = (Object JavaDoc) Proxy.newProxyInstance
307                     (loader, new Class JavaDoc[] { serviceEndpointIntfClass },
308                     invocationHandler);
309             
310             // starting in 2.0, there is no more generated Ties
311
if (next.getTieClassName()!=null) {
312                 tieClass = loader.loadClass(next.getTieClassName());
313             }
314                     
315             webServiceEndpoint = WebServiceEjbEndpointRegistry.getRegistry().createEjbEndpointInfo(next, this, servant, tieClass);
316                                            
317             WebServiceEjbEndpointRegistry.getRegistry().
318                 registerEjbWebServiceEndpoint(webServiceEndpoint);
319         }
320       
321         ObjectFactory sessionCtxFactory = new SessionContextFactory();
322         poolProp = new PoolProperties();
323         pool= new NonBlockingPool(ejbDescriptor.getName(),
324            sessionCtxFactory, poolProp.steadyPoolSize,
325            poolProp.poolResizeQuantity, poolProp.maxPoolSize,
326            poolProp.poolIdleTimeoutInSeconds, loader);
327
328     registerMonitorableComponents();
329     }
330
331     protected void registerMonitorableComponents() {
332     registryMediator.registerProvider(this);
333     registryMediator.registerProvider(pool);
334         super.registerMonitorableComponents();
335     super.populateMethodMonitorMap();
336         _logger.log(Level.FINE, "[SLSB Container] registered monitorable");
337     }
338
339     public void onReady() {
340     }
341
342     public EJBObjectImpl createRemoteBusinessObjectImpl()
343         throws CreateException, RemoteException JavaDoc
344     {
345         // No access check since this is an internal operation.
346

347     statCreateCount++;
348
349         return theRemoteBusinessObjectImpl;
350     }
351
352     
353     /**
354      *
355      */

356     public EJBObjectImpl createEJBObjectImpl()
357         throws CreateException, RemoteException JavaDoc
358     {
359         // Need to do access control check here because BaseContainer.preInvoke
360
// is not called for stateless sessionbean creates.
361
authorizeRemoteMethod(EJBHome_create);
362
363         if ( AppVerification.doInstrument() ) {
364             AppVerification.getInstrumentLogger().doInstrumentForEjb(
365                 ejbDescriptor, homeCreateMethod, null);
366         }
367
368     statCreateCount++;
369
370         // For stateless EJBs, EJB2.0 Section 7.8 says that
371
// Home.create() need not do any real creation.
372
// If necessary, a stateless bean is created below during getContext().
373
return theEJBObjectImpl;
374     }
375
376     /**
377      * Called during client creation request through EJB LocalHome view.
378      */

379     public EJBLocalObjectImpl createEJBLocalObjectImpl()
380         throws CreateException
381     {
382         // Need to do access control check here because BaseContainer.preInvoke
383
// is not called for stateless sessionbean creates.
384
authorizeLocalMethod(EJBLocalHome_create);
385
386         if ( AppVerification.doInstrument() ) {
387             AppVerification.getInstrumentLogger().doInstrumentForEjb(
388                 ejbDescriptor, localHomeCreateMethod, null);
389         }
390
391         // For stateless EJBs, EJB2.0 Section 7.8 says that
392
// Home.create() need not do any real creation.
393
// If necessary, a stateless bean is created below during getContext().
394
return theEJBLocalObjectImpl;
395     }
396
397     /**
398      * Called during internal creation of session bean
399      */

400     public EJBLocalObjectImpl createEJBLocalBusinessObjectImpl()
401         throws CreateException
402     {
403         // No access checks needed because this is called as a result
404
// of an internal creation, not a user-visible create method.
405
return theEJBLocalBusinessObjectImpl;
406     }
407
408
409     // Called from EJBObjectImpl.remove, EJBLocalObjectImpl.remove,
410
// EJBHomeImpl.remove(Handle).
411
void removeBean(EJBLocalRemoteObject ejbo, Method JavaDoc removeMethod,
412         boolean local)
413     throws RemoveException, EJBException
414     {
415     statRemoveCount++;
416     }
417
418     /**
419      * Force destroy the EJB. Called from postInvokeTx.
420      * Note: EJB2.0 section 18.3.1 says that discarding an EJB
421      * means that no methods other than finalize() should be invoked on it.
422      */

423     void forceDestroyBean(EJBContextImpl sc) {
424         if ( sc.getState() == DESTROYED )
425                 return;
426
427         // mark context as destroyed
428
sc.setState(DESTROYED);
429
430         //sessionCtxPool.destroyObject(sc);
431
pool.destroyObject(sc);
432     }
433
434
435     /**
436      * Called when a remote invocation arrives for an EJB.
437      */

438     EJBObjectImpl getEJBObjectImpl(byte[] instanceKey) {
439         return theEJBObjectImpl;
440     }
441     
442     EJBObjectImpl getEJBRemoteBusinessObjectImpl(byte[] instanceKey) {
443         return theRemoteBusinessObjectImpl;
444     }
445
446     /**
447     * Called from EJBLocalObjectImpl.getLocalObject() while deserializing
448     * a local object reference.
449     */

450     EJBLocalObjectImpl getEJBLocalObjectImpl(Object JavaDoc key) {
451         return theEJBLocalObjectImpl;
452     }
453
454     /**
455     * Called from EJBLocalObjectImpl.getLocalObject() while deserializing
456     * a local business object reference.
457     */

458     EJBLocalObjectImpl getEJBLocalBusinessObjectImpl(Object JavaDoc key) {
459         return theEJBLocalBusinessObjectImpl;
460     }
461
462
463     /**
464     * Called from preInvoke which is called from the EJBObject
465     * for local and remote invocations.
466     */

467     protected ComponentContext _getContext(Invocation inv) {
468         try {
469             SessionContextImpl sessionCtx =
470                 (SessionContextImpl) pool.getObject(null);
471             sessionCtx.setState(INVOKING);
472             return sessionCtx;
473         } catch (Exception JavaDoc ex) {
474             throw new EJBException(ex);
475         }
476     }
477
478
479     /**
480     * called when an invocation arrives and there are no instances
481     * left to deliver the invocation to.
482     * Called from SessionContextFactory.create() !
483     */

484     private SessionContextImpl createStatelessEJB()
485         throws CreateException
486     {
487         ComponentInvocation ci = null;
488         SessionContextImpl context;
489
490         try {
491             // create new stateless EJB
492
Object JavaDoc ejb = ejbClass.newInstance();
493
494             // create SessionContext and set it in the EJB
495
context = new SessionContextImpl(ejb, this);
496             context.setInterceptorInstances(
497                     interceptorManager.createInterceptorInstances());
498             
499             // this allows JNDI lookups from setSessionContext, ejbCreate
500
ci = new ComponentInvocation(ejb, this, context);
501             invocationManager.preInvoke(ci);
502
503             // setSessionContext will be called without a Tx as required
504
// by the spec, because the EJBHome.create would have been called
505
// after the container suspended any client Tx.
506
// setSessionContext is also called before context.setEJBStub
507
// because the bean is not allowed to do EJBContext.getEJBObject
508
if( ejb instanceof SessionBean ) {
509                 ((SessionBean)ejb).setSessionContext(context);
510             }
511
512             // Perform injection right after where setSessionContext
513
// would be called. This is important since injection methods
514
// have the same "operations allowed" permissions as
515
// setSessionContext.
516
injectionManager.injectInstance(ejb, ejbDescriptor, false);
517             for (Object JavaDoc interceptorInstance : context.getInterceptorInstances()) {
518                 injectionManager.injectInstance(interceptorInstance,
519                         ejbDescriptor, false);
520             }
521
522             if ( isRemote ) {
523                 if( hasRemoteHomeView ) {
524                     context.setEJBObjectImpl(theEJBObjectImpl);
525                     context.setEJBStub(theEJBStub);
526                 }
527                 if( hasRemoteBusinessView ) {
528                     context.setEJBRemoteBusinessObjectImpl
529                         (theRemoteBusinessObjectImpl);
530                 }
531             }
532             if ( isLocal ) {
533                 if( hasLocalHomeView ) {
534                     context.setEJBLocalObjectImpl(theEJBLocalObjectImpl);
535                 }
536                 if( hasLocalBusinessView ) {
537                     context.setEJBLocalBusinessObjectImpl
538                         (theEJBLocalBusinessObjectImpl);
539                 }
540             }
541
542             // all stateless beans have the same id and same InstanceKey
543
context.setInstanceKey(statelessInstanceKey);
544
545             //Call ejbCreate() or @PostConstruct method
546
interceptorManager.intercept(
547                     CallbackType.POST_CONSTRUCT, context);
548
549             // Set the state to POOLED after ejbCreate so that
550
// EJBContext methods not allowed will throw exceptions
551
context.setState(POOLED);
552         } catch ( Throwable JavaDoc th ) {
553             _logger.log(Level.INFO, "ejb.stateless_ejbcreate_exception", th);
554             CreateException creEx = new CreateException("Could not create stateless EJB");
555             creEx.initCause(th);
556             throw creEx;
557         } finally {
558             if ( ci != null ) {
559                 invocationManager.postInvoke(ci);
560             }
561         }
562         context.touch();
563         return context;
564     }
565
566     void doTimerInvocationInit(Invocation inv, RuntimeTimerState timerState)
567         throws Exception JavaDoc
568     {
569         if( isRemote ) {
570             inv.ejbObject = theEJBObjectImpl;
571             inv.isLocal = false;
572         } else {
573             inv.ejbObject = theEJBLocalObjectImpl;
574             inv.isLocal = true;
575         }
576     }
577
578     public boolean userTransactionMethodsAllowed(ComponentInvocation inv) {
579         boolean utMethodsAllowed = false;
580         if( isBeanManagedTran ) {
581             if( inv instanceof Invocation ) {
582                 Invocation i = (Invocation) inv;
583                 EJBContextImpl sc = (EJBContextImpl) i.context;
584                 // If Invocation, only ejbRemove not allowed.
585
utMethodsAllowed = !sc.isInEjbRemove();
586             } else {
587                 // This will prevent setSessionContext/ejbCreate access
588
utMethodsAllowed = false;
589             }
590         }
591         return utMethodsAllowed;
592     }
593
594     /**
595      * Called from preInvoke which is called from the EJBObject
596      * for local and remote invocations.
597      */

598     public void releaseContext(Invocation inv) {
599         SessionContextImpl sc = (SessionContextImpl)inv.context;
600
601         // check if the bean was destroyed
602
if ( sc.getState()==DESTROYED )
603             return;
604
605             sc.setState(POOLED);
606
607             // Stateless beans cant have transactions across invocations
608
sc.setTransaction(null);
609             sc.touch();
610
611             pool.returnObject(sc);
612     }
613
614
615     boolean isIdentical(EJBObjectImpl ejbo, EJBObject other)
616         throws RemoteException JavaDoc
617     {
618         if ( other == ejbo.getStub() ) {
619             return true;
620         }else {
621             try {
622                 // other may be a stub for a remote object.
623
// Although all stateless sessionbeans for a bean type
624
// are identical, we dont know whether other is of the
625
// same bean type as ejbo.
626
if ( protocolMgr.isIdentical(ejbo.getStub(), other) )
627                         return true;
628                 else
629                         return false;
630             } catch ( Exception JavaDoc ex ) {
631                 if(_logger.isLoggable(Level.SEVERE)) {
632                     _logger.log(Level.SEVERE,"ejb.ejb_getstub_exception",
633                         logParams);
634                     _logger.log(Level.SEVERE,"",ex);
635                 }
636                 throw new RemoteException JavaDoc("Error during isIdentical.", ex);
637             }
638         }
639     }
640
641     /**
642     * Check if the given EJBObject/LocalObject has been removed.
643     * @exception NoSuchObjectLocalException if the object has been removed.
644     */

645     void checkExists(EJBLocalRemoteObject ejbObj)
646     {
647         // For stateless session beans, EJBObject/EJBLocalObj are never removed.
648
// So do nothing.
649
}
650
651
652     void afterBegin(EJBContextImpl context) {
653         // Stateless SessionBeans cannot implement SessionSynchronization!!
654
// EJB2.0 Spec 7.8.
655
}
656
657     void beforeCompletion(EJBContextImpl context) {
658         // Stateless SessionBeans cannot implement SessionSynchronization!!
659
// EJB2.0 Spec 7.8.
660
}
661
662     void afterCompletion(EJBContextImpl ctx, int status) {
663         // Stateless SessionBeans cannot implement SessionSynchronization!!
664
// EJB2.0 Spec 7.8.
665

666         // We dissociate the transaction from the bean in releaseContext above
667
}
668
669     // default
670
public boolean passivateEJB(ComponentContext context) {
671         return false;
672     }
673     
674     // default
675
public void activateEJB(Object JavaDoc ctx, Object JavaDoc instanceKey) {}
676
677     public void appendStats(StringBuffer JavaDoc sbuf) {
678     sbuf.append("\nStatelessContainer: ")
679         .append("CreateCount=").append(statCreateCount).append("; ")
680         .append("RemoveCount=").append(statRemoveCount).append("; ")
681         .append("]");
682     }
683
684     public void undeploy() {
685         //Change the container state to ensure that all new invocations will be rejected
686
super.setUndeployedState();
687
688         try {
689             if( isWebServiceEndpoint && (webServiceEndpoint != null) ) {
690                 String JavaDoc endpointAddress =
691                     webServiceEndpoint.getEndpointAddressUri();
692                 WebServiceEjbEndpointRegistry.getRegistry().
693                     unregisterEjbWebServiceEndpoint(endpointAddress);
694             }
695             if ( hasRemoteHomeView ) {
696                     // destroy EJBObject refs
697
// XXX invocations still in progress will get exceptions ??
698
remoteHomeRefFactory.destroyReference
699                     (theEJBObjectImpl.getStub(),
700                      theEJBObjectImpl.getEJBObject());
701             }
702             if ( hasRemoteBusinessView ) {
703                 for(RemoteBusinessIntfInfo next :
704                         remoteBusinessIntfInfo.values()) {
705                     next.referenceFactory.destroyReference
706                         (theRemoteBusinessObjectImpl.getStub
707                             (next.generatedRemoteIntf.getName()),
708                          theRemoteBusinessObjectImpl.getEJBObject
709                             (next.generatedRemoteIntf.getName()));
710                 }
711             }
712
713             isPoolClosed = true;
714
715             pool.close();
716
717         } finally {
718             super.undeploy();
719
720             this.homeCreateMethod = null;
721             this.localHomeCreateMethod = null;
722             this.theEJBLocalObjectImpl = null;
723             this.theEJBObjectImpl = null;
724             this.theEJBStub = null;
725             this.pool = null;
726             this.iased = null;
727             this.beanCacheDes = null;
728             this.beanPoolDes = null;
729             this.svr = null;
730             this.ejbContainer = null;
731             this.poolProp = null;
732
733         }
734     }
735
736     public long getMethodReadyCount() {
737     return pool.getSize();
738     }
739
740     private class SessionContextFactory
741         implements ObjectFactory
742     {
743
744         public Object JavaDoc create(Object JavaDoc param) {
745             try {
746                     return createStatelessEJB();
747             } catch (CreateException ex) {
748                     throw new EJBException(ex);
749             }
750         }
751
752         public void destroy(Object JavaDoc obj) {
753             SessionContextImpl sessionCtx = (SessionContextImpl) obj;
754             // Note: stateless SessionBeans cannot have incomplete transactions
755
// in progress. So it is ok to destroy the EJB.
756

757             Object JavaDoc sb = sessionCtx.getEJB();
758             if (sessionCtx.getState() != DESTROYED) {
759                 //Called from pool implementation to reduce the pool size.
760
//So need to call ejb.ejbRemove()
761
// mark context as destroyed
762
sessionCtx.setState(DESTROYED);
763                 Invocation inv = null;
764                 try {
765                     // NOTE : Context class-loader is already set by Pool
766
inv = new Invocation(sb, StatelessSessionContainer.this);
767                     inv.context = sessionCtx;
768                     invocationManager.preInvoke(inv);
769                     sessionCtx.setInEjbRemove(true);
770    
771                     interceptorManager.intercept(
772                             CallbackType.PRE_DESTROY, sessionCtx);
773
774                 } catch ( Throwable JavaDoc t ) {
775                      _logger.log(Level.FINE, "ejbRemove exception", t);
776                 } finally {
777                     sessionCtx.setInEjbRemove(false);
778                     if( inv != null ) {
779                         invocationManager.postInvoke(inv);
780                     }
781                 }
782             } else {
783                 //Called from forceDestroyBean
784
//So NO need to call ejb.ejbRemove()
785
// mark the context's transaction for rollback
786
Transaction tx = sessionCtx.getTransaction();
787                 try {
788                     if ( (tx != null) &&
789                         (tx.getStatus() != Status.STATUS_NO_TRANSACTION ) ) {
790                         tx.setRollbackOnly();
791                     }
792                 } catch ( Exception JavaDoc ex ) {
793                      _logger.log(Level.FINE,"forceDestroyBean exception", ex);
794                 }
795             }
796
797             // tell the TM to release resources held by the bean
798
transactionManager.ejbDestroyed(sessionCtx);
799
800             sessionCtx.setTransaction(null);
801
802             sessionCtx.deleteAllReferences();
803             sessionCtx = null;
804         }
805     } // SessionContextFactory{}
806

807     private class PoolProperties {
808         int maxPoolSize;
809         int poolIdleTimeoutInSeconds;
810         int poolResizeQuantity;
811         int steadyPoolSize;
812
813         public PoolProperties() {
814
815             maxPoolSize = new Integer JavaDoc(ejbContainer.getMaxPoolSize()).intValue();
816             poolIdleTimeoutInSeconds = new Integer JavaDoc(
817                 ejbContainer.getPoolIdleTimeoutInSeconds()).intValue();
818             poolResizeQuantity = new Integer JavaDoc(
819                 ejbContainer.getPoolResizeQuantity()).intValue();
820             steadyPoolSize = new Integer JavaDoc(
821                 ejbContainer.getSteadyPoolSize()).intValue();
822             if(beanPoolDes != null) {
823                 int temp = 0;
824                 if (( temp = beanPoolDes.getMaxPoolSize()) != -1) {
825                         maxPoolSize = temp;
826                 }
827                 if (( temp = beanPoolDes.getPoolIdleTimeoutInSeconds()) != -1) {
828                         poolIdleTimeoutInSeconds = temp;
829                 }
830
831                 if (( temp = beanPoolDes.getPoolResizeQuantity()) != -1) {
832                         poolResizeQuantity = temp;
833                 }
834                 if (( temp = beanPoolDes.getSteadyPoolSize()) != -1) {
835                         steadyPoolSize = temp;
836                 }
837             }
838         }
839     } // PoolProperties{}
840

841     //Methods for StatelessSessionBeanStatsProvider
842
public int getMaxPoolSize() {
843         return (poolProp.maxPoolSize <= 0)
844         ? Integer.MAX_VALUE
845         : poolProp.maxPoolSize;
846     }
847
848     public int getSteadyPoolSize() {
849         return (poolProp.steadyPoolSize <= 0)
850         ? 0
851         : poolProp.steadyPoolSize;
852     }
853     
854 } // StatelessSessionContainer.java
855

856
Popular Tags