JBoss is a very excellent J2EE Application Server to study its source code helps us better understand the various technologies of J2EE. This series is analyzed from four aspects: 1.EJB Container implementation 2.Transaction implementation 3.Persistence mapping 4.client to the server-side Invocation
-------------------------------------------------- ---------------- first say 1 point: EJB Container implementation. 1.1 EJB POOL We know that EJB Container will maintain an EJB pool, sharing between multiple clients, avoiding the overhead of destroying objects frequently. Let's look at Jboss achieve Pool: EJB points EntityBean, MDB, Stateless / Stateful Session Bean, and the corresponding Jboss also have EntityInstancePool, MessageDrivenInstancePool, StatefulSessionInstancePool, StatelessSessionInstancePool Let's start with a common base class AbstractInstancePool four classes. looks: class AbstractInstancePool implements the interface InstancePool, this interface has the following methods: EnterpriseContext get () throws Exception; void free (EnterpriseContext ctx); void discard (EnterpriseContext ctx); int getCurrentSize (); public int getMaxSize (); -------------------------------------------------- ----------------- First, the EnterpriseContext is explained. EnterpriseContext's role is to link specific EJB Instance and its metadata. This class is: Public Abstract Class EnterpriseContext, there are 4 subclasses, EntityEnterpriseContext, MessageNenerPriseContext, StateEternalNterpriseContext, StatelessSessionNterpriseContext. There correspond to four types of EJBs, respectively. There are several important member variables in EnterpriseContext. / ** The ejb instance * / Object instance; / ** the contacter using this context * / container con; // Container This class is JBoss to represent the class that provides Transaction, Security, Pool, etc., let's return. Will say anything. / *** Only StatelessSession Beans Have No ID, Stateful and Entity DO * / Object ID;
/ ** THE Transaction Associated with the instance * / transaction transaction; // transaction, let's say later.
// Constructors ----------------------------------------------------------------------------- ---
Public EnterpriseContext (Object Instance, Container Con) {this.constance = instance; this.con = con;} public object getInstance () {return instance;} public container getContainer ()
Public void setid (Object ID) {this.id = id;}
Public Object getId () {returnid;}
Public void settrarsaction {this.trarsaction = Transaction;}
Public Transaction GetTransaction () {Return Transaction;
/ ** * get the ejbcontext object * / public abstract ejbcontext getEjbContext (); // implemented by subclass
// Return javax.ejb.ejbcontext, note that this EJBCONText is the Context that the EJB specification is required to provide EJB, which doesn't matter if you entries EnterpriseContext yourself.
/ ** The instance is being used. This locks it / 's state * / int locked = 0; public void lock () {locate ;}
Public void unlock () {locked -;
Public boolean islocked () {return locked! = 0;} // LOCK This member variable indicates that there is no one in this ejb instance. // This variable is used to give Reentrance, as well as canpassviate. / ** * Before Reusing this context We clear it of previous State Called * by pool.free () * No EJB Instance and Transaction when picking out from pool. No EJB INSTANCE and TRANSACTION Information * Clear this information when it returns Pool. * / public void clear () {this.id = null; this.locked = 0; this.transaction = null;} // --------------------- -------------------------------------------------- -------------- Protected Boolean IscontainerManagedtx () {beanmetadata MD = (beanmetadata) Con. GetBeanMetadata (); return md.iscontainerManageDTX ();} // Corresponding to the associated Container Metadata, determined whether cmt. // Note that CON is a Container member variable, can not be connected, connection general abbreviation is conn, // I am confused at the beginning :) // beanmetadata These metadata subclasses are from XML The Metadata constructed in the configuration, // is not mysterious. This class has two INNER CLASS, EJBCONTEXTIMPL IMPLEments EJBCONTEXT, UserTransaction IMPLEments Utertransaction. EjbContextImpl, etc. explain the Container, and the next section is said to be said by UserTransaction. Let us now take a look at EnterpriseContext: First class is more than a few subclasses of member variables: EntityEnterpriseContext: Private EjBobject EjBobject; Private Ejblocalobject EjblocalObject; Private EntityContext CTX;
StatefulsessionenTerpriseContext Private EJBObject EjBobject; Private EjblocalObject EjBlocalObject; Private SessionContext CTX;
STATELESSSESSIONENTERPRISECONText EjBobject EjBobject; EjblocalObject EjblocalObject; sessionContext CTX;
MessageDrivenEnterpriseContext: private MessageDrivenContext ctx; in addition it seems there is no corresponding MDB EJBObject / EJBLocalObject, all the others have learned :) EJB knows, syntactically EJB instance is implements EntityBean / SessionBean / MessageDrivenBean (which has a 3 interface common interface: public interface EnterpriseBean extends Serializable, EnterpriseBean a Marker interface inside nothing, it seems, like Serializable interface, only instructions to achieve it is EJB and EntityBean / SessionBean / MessageDrivenBean a corresponding void ejbActivate () throws EJBException, RemoteException. void ejbload () THROWS EJBEXCEPTION, RemoteException; Some methods need to be implemented. (Although it is often empty implementation :), a lot of things made by the container) As for EJBOBJECT / EJBLOCALOBJECT, it is not directly implemented in syntax, representing EJB Instance Exposure Remote / Local interface. Since these EJB Instances do these interfaces directly, how these interfaces are associated with the specific EJB Instance, and we will know when the Container class is known. -------------------------------------------------- -------------------------------- EnterpriseContext Sub-class EntityEnterpriseContext constructor PUBLIC EntityEnterpriseContext (Object Instance, Container Con) throws RemoteException {super (instance, con); ctx = new entryxTextImpl (); // This is the subclass of EJBContextImpl, no rising :) (EntityBean) .SetentityContext (ctx); // Take a look, original set ... Context is what ejbcreate (), ejbel (), ejbactive (), what is called here? Next, we slowly find it, this can be spread around :)} // The three lines of the three lines of the other subclasses are also true, it is similar. For StatelessSessionternalPriseContext and MessageDrivenenterpriseContext, close
Method ejbcreate = instance.getClass (). GetMethod (/ "ejbcreate /", new class [0]); ejbcreate.invoke (Instance, New Object [0]); // Look, come to an ejbcreate :), for StatelessSessionBean, up to a ejbCreate () - a simple watch next: for EnterpriseContext, there are public abstract void discard () throws RemoteException; MessageDriven ... for the public void discard () throws RemoteException {((MessageDrivenBean) instance) .ejbRemove ();} public void discard StatelessSession for the () throws RemoteException {((SessionBean) instance) .ejbRemove ();} for the StatefulSession ... public void discard () throws RemoteException {// Do nothing} Entity for .... public void discard () throws RemoteException {((EntityBean) instance) .unsetEntityContext ();} // discard is void discard in the AbstractInstancePool (EnterpriseContext ctx); call / ** * discard an anonymous instance after invocation. * This is called if the instance should not be reused, perhaps due to some * exception being thrown from it. * * @param ctx The context to discard. * / public void discard (EnterpriseContext ctx {ctx.discard ();} AbstractInstancePool also has a Free method: public void free (EnterpriseContext CTX) {ctx.clear (); // Remember that the CTX is just clearing ID, Transaction, etc., return Pool, ready to reply? // discard is an error when an error occurs, so Discard off, //, and // corresponding to get () FREE method is just returning EnterpriseContext to pool.} ------------- -------------------------------------------------- -------------------
For specialized Stateful .... Context EJB instance provided with a function / ** * During activation of stateful session beans we replace the instance * by the one read from the file. * / Public void setInstance (Object instance) {this.instance = instance; ((SessionBean) instance) .setSessionContext (ctx);} Note ... Context of the four, only Stateful ... Context signature public class StatefulSessionEnterpriseContext extends EnterpriseContext implements Serializable more than a implements Serializable, (the other is not ), This is to support the Activation / PassViation, and passviation to write the EJB Instance to the file. Two such methods private void writeObject (ObjectOutputStream out) in the StatefulSessionEnterpriseContext throws IOException, ClassNotFoundException {// do nothing} private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException {// do nothing} // description of the time sequence StatefulSessionEnterpriseContext It does not need to be written in itself, only the corresponding EJB Instance needs to be written.
Now let's see the source code of AbstractInstancePool, because there are too many content, it is not explained in detail.
First look at Abstract ... pool's create (Object Instance) function Hotmia ~ Abstract ... pool // protected ------------------------- ---------------------------- Protected Abstract EnterpriseContext Create (Object Instance) throws Exception; Entity ... pool protected enterpriseContext Create (Object Instance) throws Exception {Return New EntityEnterpriseContext (Instance, getContainer ());} Other three Pool is similar. Look back Abstract..Pool / ** The pool data structure * / protected EnterpriseContext [] pool; protected int currentIndex = -1; / ** The maximum number of instances allowed in the pool * / protected int maxSize = 30; / ** the minimum size of the pool * / protected int minSize = 0; / ** determine if we reuse EnterpriseContext objects ie if we actually do pooling * / protected reclaim = false boolean; // for MDB and StatelessSessionBean, this variable is set For True, // for MDB, WE * DO * POOL // for SLSB, WE * DO * POOLOK, now look at Pool's highlights, get () / free (EnterpriseContext CTX) function (in front of the Discard (EnterpriseContext CTX) , No longer repeat) these functions are also interfaces to implement in Interface Instancepool :) Gossip less, come and see code ~~ protected boilean minsizeinitialized = false;
/ ** * GET An Instance Without Identity. * Can be used by Finders, Create-methods, and activation * * @return context / w instance * @Exception RemoteException * /
public EnterpriseContext get () {// pool inside there Take out stuff synchronized (pool) {if (currentIndex> -1) {EnterpriseContext ctx = pool [currentIndex]; pool [currentIndex--] = null; return ctx;} }
// initialize a small fixed size of instance at startup if (minSizeInitialized!) {MinSizeInitialized = true;. Synchronized (pool) {for (int i = 0; i // Pool is empty, create an instance return create (container.createBeanClassInstance ());} / ** * Return an instance after invocation * * Called in 2 cases:. * A) Done with finder method * b) Just removed * * @Param CTX * / Public Void Free (EnterpriseContext CTX) {ctx.clear (); Synchronized (Pool) {IF (CurrentIndex 1 * DONE with Finder Method * Removed * PassiVated * * @Param CTX * / Public Void Free (EnterpriseContext CTX) {// i t ac a i () = null) {Return; = null Super.Free (CTX); -------------------------------------------------- --- and Stateful .... Pool's Free method Overwrite's Abstract ... Pool, public synchronized void free (EnterpriseContext CTX) {discard (CTX); // Simpi DISCARD is not available ~} The rest of the following, first preview 2 classes: 1.Abstractinstancecache, EntityInstanceCache and StatefulSessionInstanceCache subclasses. For Entity, use its PrimaryKey to make Cache's key, for Stateful, JBoss will also pay each instance a unique calibration value to do CacheKey. Abstract ... cache is combined with Abstract ... pool, get good Performance. 2.Public Abstract Class Container, there are 4 subclasses of EntityContainer, MessageDrivencontainer, Stateful / StatelessSessionContainer, used to provide services such as Transaction / Security / Pool for EJB Instance. // Look at its member variable, you can guess about / ** this is the transactionsManager * / protected transactionManager TM; / ** this is the securitymanager * / protected authenticationmanager sm; / ** this is the instancepool That is to be used * / protected instancepool instancepool; starting Container, I have said that Container has 4 seed classes, respectively corresponds to the four types of EJB. A Container is all Container Plugins (Note 1) and Metadata (Note 2) The THE CONTAINER PLUGINS can create the corresponding container.container when you get Metadata and other Container Plugins.ejb deployments, you will not do too much things, main DLEGITE gives Plugins. OK, let's take a look at the member variable of Container: / ** * this is the new metadata. it incdude information from Both EJB-JAR AND * JBOSS.XML The metadata for the application can be booksed Trough * metadata.getApplicationMetadata () * / protected beanmetadata metadata; / ** this is the EnterpriseBea Class * / Protected Class Beanclass / ** this is the home interface class * / protected class homeInterface / ** this is the remote interface transtend * / protected demoteinterface; / ** The local home interface class * / protected class localhomeinterface / ** The local interse class * / protected class localinterface; / ** this is the transactionsmanager * / protected transactionmanager TM; / ** this is the securitymanager * / protected authenticationmanager sm; / ** this is the realm mapping * / protected realmapping rm; / ** this is the bean lock manager this is to be used * / protected beanlockmanager lockmanager; / ** this is the application That THIS Container is a part of * / protected ejbmodule ejbmodule; // ejbmodule as a unit deployed Module, such as an ejb-jar is a module, / * This EJB-JAR may have multiple EntityBean, SESSIONBEAN, then for each EntityBean, SessionBean has a corresponding Container, and these stuff shares an ejBModule. * / / ** * Returns a new instance of the bean class or a subclass of the bean class. * this factory style method is speciffically used by a container to supply * an implementation of the abstract accessors in EJB2.0, but could be * usefull in other situations This method should ALWAYS be used instead * of getBeanClass () newInstance ();.. * * @return the new instance * * @see java.lang.Class # newInstance * / public Object createBeanClassInstance () throws Exception {return getBeanClass () newInstance ();.} public Class getBeanClass () {return beanClass;} Note EntityContainer overwrite This method: / ** * Returns a new instance of the bean class or a subclass of the bean class. * If this is 1.x CMP, SIMPLY RETURN A NEW Instance of the bean class. * If this is 2.x cmp, return a subclass that provides an implementation * of the abstract accessors. * * @see java.lang.Class # newInstance * * @return The new instance. * / public Object createBeanClassInstance () throws Exception {return persistenceManager .createBeanClassInstance ();} where persistenceManager declared: / ** This is the persistence manager for this container * / protected EntityPersistenceManager persistenceManager; // persitenceManager and PersistenceStore we will explain in part 3. Now give a minor impression: BMPPERSISTENCEMANAGER implements public object createBeanclassInstance () throws exception (). NewInstance (); CmppersistenceManager implements EntityPersistencestore Store; Public Object CreateBeanclassInstance () throws Exception {Return Store.createBeanclassInstance ();} -------------------------------------------------------------------------------------------------------------------- -------------------------------------- OK, then look at how Container handles Client INVOCATION. Everything is in the following functions public object invoke (Invocation MI); // invocation represents some member variables in the call // invocation of the Client side, indicating the Method, // Args, Transaction Information, Principle / Credential, which is to call. And other information. / ** Maps for MarshalledInvocation mapping * / protected mapp MarshalledInvocationMapping = new hashmap (); public Object invoke (Invocation mi) throws Exception {Thread currentThread = Thread.currentThread (); ClassLoader callerClassLoader = currentThread.getContextClassLoader (); // save the original classloader, finally recovered in Method M = NULL; Object Type = NULL; Try {currentthread.setContextClassLoader; (Note 3) // Check Against Home, Remote, Localhome, Local, GetHome, // GetRemote, getLocalHome, getLocal type = mi.gettype (); if (type == InvocationType.REMOTE || type == InvocationType.LOCAL) {if (mi instanceof MarshalledInvocation) {((MarshalledInvocation) mi) .setMethodMap (marshalledInvocationMapping);} return internalInvoke (mi);} else if (type = = InvocationType.HOME || type == InvocationType.LOCALHOME) {if (mi instanceof MarshalledInvocation) {((MarshalledInvocation) mi) .setMethodMap (marshalledInvocationMapping); return internalInvokeHome (mi);} else {throw new MBeanException (new IllegalArgumentException (/ // "Unknown Invocation Type: ///" Type));}} Finally {CURRENTTHREAD.SETCONTEXTCLASSLOADER (CALLERCLASSLOADER);}} -------------------------------------------------- -------------- MarshalledInvocation is the word invocation, representing the invocation public class invocation from Client to SERVER ... Public Class MarshaledInvocation Extends Invocation Implements Java.io.Externalizable, Invocation is delivered between the calling chain (Interceptor chain, Note 4) at the server side. ------------------------- -------------------------------- OK, slightly breath, then look at the two Invoke, They are abstract, to achieve public abstract Object internalInvokeHome (Invocation mi) throws Exception word class; public abstract Object internalInvoke (Invocation mi) throws Exception; As embodied Mody, TO BE CONITUE pull :) --------- ------------------------------------------ Note 1: ContainerPlugin can be put Stuff in the container. Interface interface ContainerPlugin: void setContainer (Container con); there InstancePool, InstanceCache, EJBProxyFactory / LocalProxyFactory, EntityPersistenceManager / EntityPersistenceStore Plugin etc. Note 2: metadata information describing the deployment, such as ejb-jar.xml, describes what is EntityBean stuff, what Dongdong is sessionbean, session is BMP / CMP, etc. Note 3: Member Variables of Container Protected ClassLoader ClassLoader; uses to Load this CONTAINER's classes and resources to set up a Container ClassLoader because it makes EJB RE-deployable. (JBoss schedule DEPLOY directory, if ejb change REDEPLOY, if the EJB is deleted, undeploy) Note 4: JBoss will create an interceptor chain, the Invocation passes the chain. For example, there is an EntityInterceptor, SecurityInterceptor, Transaction Interceptor, a set, one set, each interceptor handles some processing for the current Invocation, such as check permissions, things, etc., then pass to the next interceptor process (this is Filter and Pipe mode, it is also AOP pull ~, others say that JBoss This interceptor is implemented to the AOP dialect especially :). All interceptor is now Object Invokehome (Invocation MI) "and Object Invoke (Invocation MI) Throws Exception; in its own invoke, after all Interceptor, call the next one. See the default implementation of AbstractInterceptor: Public Abstract Class AbstractInterceptor IMPLEments Interceptor public Object invokeHome (final Invocation mi) throws Exception {// do sth return getNext () invokeHome (mi);..} public Object invoke (final Invocation mi) throws Exception {// do sth return getNext () invoke (.. MI); In fact, it is very simple: Public Object InternalInvokehome (Invocation Mi) throws Exception {Return GetInterceptor (). Invokehome (mi);} Public Object INTERINVOKE (Invocation MI) Throws Exception {// Invoke Through Interceptors Return GetInterceptor (). Invoke (mi); public Interceptor getInterceptor () {return interceptor;} protected Interceptor interceptor; // this is the first of a chain Interceptor Container established here invoking ~ look at void addInterceptor (Interceptor in); This function is finally hanging chain Interceptor a Interceptor public void addInterceptor (Interceptor in) {if (interceptor == null) {interceptor = in;} else {Interceptor current = interceptor; while (! current.getNext () = null) {current = current.getNext (); } Current.setnext (in);}} ----------------------------------------- ------------------------------ / protected instancecache instancecache; / ** This is the instancepool that is to be used * / protected InstancePool instancePool; / ** This is the instancepool that is to be used * / protected InstancePool instancePool; -------------- ---------------------------------------------- Public void setinstancecache (InstanceCache IC) {IF (IC == Null) throw new illegalargumentException (/// "null cache ///"); instancecache = IC; ic.setcontainer (this);} public InstanceCache getInstanceCache () {return instanceCache;} public void setInstancePool (InstancePool ip) {if (ip == null) throw new IllegalArgumentException (/// "Null pool ///"); this.instancePool = ip; ip.setContainer (this);} --------------------------------------------- -------------------------- OK, now let us see what Container has made what the method of exposing EJB Instance. How to call EJB Instance. This is important 2 map / ** * THESE ARE THE MAPPINGS BETWEEN THESE ARE THE MAPPINGS BETWEEN THE Home Interface Methods and the * Container Methods. * All Home Maps are available here * / protected map homemapping = new hashmap (); / ** * THESE ARE THE MAPPINGS BETWEEN The Remote / Local Interface Methods and The * Bean Methods. * All EJBOBJECT Method maps all here * / protected map beanmapping = new hashmap (); ---------- -------------------------------------------------- -------------- Class ContainerInterceptor Extendor // AbstractContainerInterceptor // AbstractContainerInterceptor basically does not do, don't see // ContainerInterceptor represents the last one of the interceptor call // chain of Container Setup, here you will will see him calling a method of your EJB Instance {public Object invokeHome (invocation mi) throws Exception {// invoke and handle exceptions method miMethod = mi.getMethod (); method m = (method) homeMapping.get (miMethod) ; if (M.GetDeclaringClass (). Equals (entitycontainer.class) {Try {return.this, new object [] {mi};} catch (e) {Rethrow (E);} } else // Home method {Try {returnom mi.getenterpriseContext ()). GetInstance (), mi.getarguments ();} catch (exception e) {Rethrow (e);}} // We will never get this far, but the compiler does not know that throw new org.jboss.util.unReachablestatementException (); Public Object Invoke (Invocation Mi) Throws Exception {// Get Method Method Mimethod = mi.getMethod (); Method M = (Method) BeanMapping.get (MIMETHOD); if (M == Null) {String MSG = /// "Invalid Invocation, Check Your Deployment Packaging ///" /// ", Method = ///" MIMETHOD; THROW New EJBEXCEPTION (} // select instance to invoke (container or bean) ing (m. getDeclaringClass (). Equals (entityContainer.class) {// invoke and handle exceptions try {return m.invoke (entityContainer.this, new object [] {mi});} Catch (Exception E) {Rethrow (e); }} else {// invoke and handle exceptions try {return m.invoke ((enterpriseContext) mi.getenterpriseContext ()). getInstance (), mi.getarguments ());} catCH (Exception E) {Rethrow (e) }} // We will never get this far, but the compiler does not know that thrti new org.jboss.util.unreachablestatementException ();} / / It can be seen that the two MAPs have made a map, and the MAP's key is the method of the EJB Instance method you want to call, the method implemented by Value is the method of EJB Instance itself, or the container is implemented. (,,,,,,,,, / EJBLOCALOBJECT and the word class of your EJB Instance (while JBoss generates a stuff in CMP2.0, nor is the subclass of EJB Instance). OK, basically understand the principle of Container, let's see some of the initialization operation of the bottom Container consider a service, JBoss calls several functions related to Service when deploy / undeploy / redeploy: protected void createService () throws Exception {} protected void startService () throws Exception {} protected void stopService () throws Exception {} protected void destroyService () throws Exception {} let's look from the EntityContainer: protected void createService () throws Exception {// Associate thread with classloader ClassLoader oldCl = Thread.currentThread () getContextClassLoader ();.. Thread.currentThread () setContextClassLoader (getClassLoader ()); try {// Acquire classes from CL // get metadata from Home / Remote the Class if homeInterface (metaData.getHome () = null!) = classLoader.loadClass (metaData.getHome ()); (! metaData.getRemote () = null) if remoteInterface = classLoader.loadClass ( Metadata.getRemote ()); // Call Default init // Call the CreateService in the Container, let's look back in super.createservice (); // Establish the two Method mappings that have just been mentioned (); setuPhomemApping (); // map the interfaces to long setupmarshalledinvocationmapping (); // Initialize pool instancePool.create (); // Try to register the instance pool as an MBean try {ObjectName containerName = super.getJmxName (); Hashtable props = containerName.getKeyPropertyList (); props.put (/// "plugin /////// "pool ///"); ObjectName poolname = new objectname (containername.getdomain (); server.register, poolname;} catch (throwable t) {log.debug (/// "failed to register cache as mbean ///", t);} // Init instance cache instanceCache.create (); // Try to register the instance cache as an MBean try {ObjectName containerName = super.getJmxName (); Hashtable props = containerName.getKeyPropertyList (); props.put (/// " Plugin /// ", ///" cache /// "); ObjectName Cachename = New ObjectName (ContainerName.GetDomain (); server.registermbean;} catch (throwable t) {log. Debug (// "failed to register cache as mbean ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////> for (Iterator it = proxyFactories.keySet () iterator ();. it.hasNext ();) {String invokerBinding = (String) it.next (); EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get (invokerBinding); ci. Create ();} // init persistence persistencemanager.create (); // initialize the interceptor by calling the chain interceptor in = interceptor; while (in! = Null); in.create (); in.getnext ();} readonly = ((EntityMetadata) Metadata);} finally {// reset dessloader thread.currentthread (). setContextClassLoader (OLDCL);}} protected void startService () throws Exception {// Associate thread with classloader ClassLoader oldCl = Thread.currentThread () getContextClassLoader ();.. Thread.currentThread () setContextClassLoader (getClassLoader ()); Try {// call default start super.startService (); // Start container invokers for (Iterator it = proxyFactories.keySet () iterator ();. It.hasNext ();) {String invokerBinding = (String) it.next (); EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get ( Invokerbinding; ci.start (); // start instance cache instancecache.start (); // start personistence persistencemanager.start (); // Start the instance pool instancepool.start (); // Start all interceptors in the chain Interceptor in = interceptor; while (in = null!) {In.start (); in = in.getNext ();}} finally {// Reset classloader Thread.currentThread () setContextClassLoader. (OLDCL);}} protected void stopService () throws Exception {// Associate thread with classloader ClassLoader oldCl = Thread.currentThread () getContextClassLoader ();.. Thread.currentThread () setContextClassLoader (getClassLoader ()); try {// Stop items in reverse order from start // This assures that CachedConnectionInterceptor will get removed // from in between this and the pm before the pm is stopped // Stop all interceptors in the chain Interceptor in = interceptor;. while ( IN! = null) {in.stop (); in = in.getnext ();} // stop the instance pool instancepool.stop (); // stop personistence persistencemanager.stop (); // stop instance cache instancecache.stop (); // Stop container invoker for (Iterator it = proxyFactories.keySet () iterator ();. It.hasNext ();) {String invokerBinding = (String) it.next (); EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get ( Invokerbinding; ci.stop (); // Call default stop super.stopservice ();} finally {// reset classloader thread.currentthread (). SetContextClassLoader (OLDCL);}} protected void destroyService () throws Exception {// Associate thread with classloader ClassLoader oldCl = Thread.currentThread () getContextClassLoader ();.. Thread.currentThread () setContextClassLoader (getClassLoader ()); try {// Destroy container invoker for (Iterator it = proxyFactories.keySet () iterator ();. it.hasNext ();) {String invokerBinding = (String) it.next (); EJBProxyFactory ci = (EJBProxyFactory) proxyFactories. Get (Invokerbinding); ci.destroy (); // Destroy instance cache instanceCache.destroy (); instanceCache.setContainer (null); try {ObjectName containerName = super.getJmxName (); Hashtable props = containerName.getKeyPropertyList (); props.put (/// "plugin /// ", ///" cache /// "); objectname cachename = new objectName (containername.getdomain (); server.unregistermbean (cachename);} catch (throwable ignore) {} // Destroy persistence persistenceManager.destroy (); persistenceManager.setContainer (null); // Destroy the pool instancePool.destroy (); instancePool.setContainer (null); try {ObjectName containerName = super.getJmxName (); Hashtable props = containerName .getKeyPropertyList (); Props.put (// "plugin ////////" pool //////////////////////////////////////////> (ContainerName.GetDomain (); server.unregistermbean (Poolname (} catch (throwable ignore) {} // destroy all the interceptors in the chain interceptor in = interceptor; while (in! = Null) {in.deStroy (); in.setcontainer (null); in. MarshalledInvocation.removehashes (HOMEINTERFACE); MarshalledInvocation.RemoveHashes (RemoteInterface); // Call default destroy super.destroyservice ();} finally {// resetLaceloadRead.currentthread (). SetContextClassLoader (OldCl);}} ------------------- ---------------------------------------- Protected void setupbeamapping () throws exception {TRY {if (RemoteInterface! = null) {method [] m = remoteInterface.getMethods (); setupbeamappingImpl (m, ///"javax.ejb.ebobject/// ");}} (localinterface! = null) {Method [ ] m = localinterface.getMethods (); setupbeanmappingImpl (m, ///"javax.ejb.ejblocalobject//////// Ditch The Half Built mappings homemapping.clear (); beanmapping .clear (); Throw e;}} Private void setupbeamappingImpl (Method [] M, String INTFNAME) THROWS Exception {for (INT i = 0; I Continue;} catch (nosuchmethodexception ignore) {} // Just Go ON WITHER TYPES OF Methods //MPLEMENTED by Container (MethodName.StartSwith)) {homemapping.put (M, this.getClass (). GetMethod (FinderName, New class [] {invocation .class}));} else if (MethodName.Equals (/// "crete ///////////////////////////////////////////////////////////////")))) {HomeMapping .put (m, this.getClass (). getMethod (/// "create ///////////////////////////////////////////////////> (); beanmapping.put (M, this.getClass (). getMethod (////////////////////////////////3});} else {homemapping.put (m, this.getClass (). getMethod (MethodName Append, New class [] {Invocation.class}));}} catch (NoSuchMethodException e) {throw new NoSuchMethodException (/// "Could not find matching method for ///" m);}}} protected void setupHomeMapping () throws Exception {try {IF (HomeInterface! = null) {method [] m = homeInterface.getMethods (); setuphomemappingImpl (m, /// "find ////////" home /// ");} if (localhomeinterface! = NULL) {Method [] m = localhomeinterface.getMethods (); SetUphomemappingImpl (m, /// "findlocal /////////" LocalHome /// "); // Special Methods // Get the one on handle (get the class class handleclass = class.forname (/// "javax.ejb.handle ///"); // Get the Methods (There IS Only One) Method [] HandleMethods = Handleclass.getMethods (); // just to make sure let /// 's iterate for (int J = 0; j {// Get online "called handle.getejbobject if (HandleMethods [J] .GetName (). Equals (///" getEbobject /// ")) {// Map it in the home stuff homeMapping.put (handleMethods [j], this.getClass (). getMethod (///" getEJBObject /// ", new Class [] {Invocation.class });}}} catch (Exception E) {// Ditch The Half Built mappings homemapping.clear (); beanmapping.clear (); throw e;}}