User: mnf999  
  Date: 01/06/26 22:37:43

  Modified:    src/main/org/jboss/ejb/plugins AbstractInstanceCache.java
  Log:
  mmmm FIXMES in the AbstractInstanceCache...
  
  we need to fix this poopoo
  
  Revision  Changes    Path
  1.12      +292 -276  jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java
  
  Index: AbstractInstanceCache.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- AbstractInstanceCache.java        2001/06/18 20:01:23     1.11
  +++ AbstractInstanceCache.java        2001/06/27 05:37:43     1.12
  @@ -1,9 +1,9 @@
   /*
  - * JBoss, the OpenSource EJB server
  - *
  - * Distributable under LGPL license.
  - * See terms of license at gnu.org.
  - */
  +* JBoss, the OpenSource EJB server
  +*
  +* Distributable under LGPL license.
  +* See terms of license at gnu.org.
  +*/
   
   package org.jboss.ejb.plugins;
   
  @@ -47,24 +47,32 @@
   import org.jboss.monitor.MetricsConstants;
   
   /**
  - * Base class for caches of entity and stateful beans. <p>
  - * It manages the cache entries through a {@link CachePolicy} object;
  - * the implementation of the cache policy object must respect the following
  - * requirements:
  - * <ul>
  - * <li> Have a public constructor that takes a single argument of type
  - * AbstractInstanceCache.class or a subclass
  - * </ul>
  - *
  - * @author <a href="mailto:[EMAIL PROTECTED]";>Simone Bordet</a>
  - * @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
  - * @version $Revision: 1.11 $
  - */
  +* Base class for caches of entity and stateful beans. <p>
  +* It manages the cache entries through a {@link CachePolicy} object;
  +* the implementation of the cache policy object must respect the following
  +* requirements:
  +* <ul>
  +* <li> Have a public constructor that takes a single argument of type
  +* AbstractInstanceCache.class or a subclass
  +* </ul>
  +*
  +*
  +* @author <a href="mailto:[EMAIL PROTECTED]";>Simone Bordet</a>
  +* @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
  +* @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  +*
  +* 
  +*   Revisions:
  +*
  +*   20010626 marc fleury: Cache should be working with the MethodInvocation  
  +* 
  +* @version $Revision: 1.12 $
  +*/
   public abstract class AbstractInstanceCache
  -     implements InstanceCache, XmlLoadable, Monitorable, MetricsConstants
  +implements InstanceCache, XmlLoadable, Monitorable, MetricsConstants
   {
        // Constants -----------------------------------------------------
  -
  +     
        // Attributes ----------------------------------------------------
        /* The object that is delegated to implement the desired caching policy */
        private CachePolicy m_cache;
  @@ -85,11 +93,11 @@
        private Topic m_jmsTopic;
        private TopicSession m_jmsSession;
        private TopicPublisher m_jmsPublisher;
  -
  +     
        // Static --------------------------------------------------------
  -
  +     
        // Constructors --------------------------------------------------
  -
  +     
        // Monitorable implementation ------------------------------------
        public void sample(Object s)
        {
  @@ -104,16 +112,16 @@
                        }
                }
        }
  -
  +     
        // Public --------------------------------------------------------
        public void setJMSMonitoringEnabled(boolean enable) {m_jmsMonitoring = enable;}
        public boolean isJMSMonitoringEnabled() {return m_jmsMonitoring;}
  -
  +     
        public void sendMessage(Message message)
        {
                try
                {
  -            message.setJMSType(BEANCACHE_METRICS);
  +                     message.setJMSType(BEANCACHE_METRICS);
                        message.setJMSExpiration(5000);
                        message.setLongProperty(TIME, System.currentTimeMillis());
                        m_jmsPublisher.publish(m_jmsTopic, message);
  @@ -142,22 +150,26 @@
                }
                return message;
        }
  -
  +     
        /* From InstanceCache interface */
        public EnterpriseContext get(Object id)
  -             throws RemoteException, NoSuchObjectException
  +     throws RemoteException, NoSuchObjectException
        {
                if (id == null) throw new IllegalArgumentException("Can't get an 
object with a null key");
  -
  +                     
                EnterpriseContext ctx = null;
  +             
                synchronized (getCacheLock())
                {
                        ctx = (EnterpriseContext)getCache().get(id);
                        if (ctx == null)
                        {
                                // Here I block if the bean is passivating now
  +                             
  +                             // FIXME marcf: I am REALLY against locking on 
passivation, we are locking the 
  +                             // whole cache for the passivation of one guy. it 
doesn't make sense!!!!!!!!
                                ctx = unschedulePassivation(id);
  -
  +                             
                                // Already passivated ?
                                if (ctx == null)
                                {
  @@ -165,6 +177,9 @@
                                        {
                                                ctx = acquireContext();
                                                setKey(id, ctx);
  +                                             //FIXME marcf: in the case of session 
we are saying that the WHOLE
  +                                             // cache will be locked (see 
synchronized statement) until this guy completes
  +                                             // DO YOU SEE IT? THE *WHOLE* APP 
LOCKED ON A ACTIVATION??? WTF?
                                                activate(ctx);
                                                logActivation(id);
                                                insert(ctx);
  @@ -182,13 +197,14 @@
                        }
                }
                if (ctx == null) throw new NoSuchObjectException("Can't find bean with 
id = " + id);
  +             
                return ctx;
        }
        /* From InstanceCache interface */
        public void insert(EnterpriseContext ctx)
        {
                if (ctx == null) throw new IllegalArgumentException("Can't insert a 
null object in the cache");
  -
  +                     
                CachePolicy cache = getCache();
                synchronized (getCacheLock())
                {
  @@ -196,7 +212,7 @@
                        // key, then the context is passivated and I will insert in 
cache a meaningless
                        // context.
                        Object key = getKey(ctx);
  -
  +                     
                        if (cache.peek(key) == null)
                        {
                                cache.insert(key, ctx);
  @@ -214,7 +230,7 @@
        public void release(EnterpriseContext ctx)
        {
                if (ctx == null) throw new IllegalArgumentException("Can't release a 
null object");
  -
  +                     
                // Here I remove the bean; call to remove(id) is wrong
                // cause will remove also the cache lock that is needed
                // by the passivation, that eventually will remove it.
  @@ -237,7 +253,7 @@
        public void remove(Object id)
        {
                if (id == null) throw new IllegalArgumentException("Can't remove an 
object using a null key");
  -
  +                     
                synchronized (getCacheLock())
                {
                        if (getCache().peek(id) != null)
  @@ -247,19 +263,19 @@
                }
                removeLock(id);
        }
  -
  +     
        public boolean isActive(Object id)
        {
                // Check whether an object with the given id is available in the cache
                return getCache().peek(id) != null;
        }
        /**
  -      * Creates (if necessary) and returns an object used as mutex to sync 
passivation
  -      * activity with other activities, in particular incoming invoking calls. <br>
  -      * The mutex is automatically removed when the corrispondent id is removed from
  -      * the cache, either by passivation or by removal.
  -      * This method must be synchronized with its dual, {@link #removeLock}.
  -      */
  +     * Creates (if necessary) and returns an object used as mutex to sync 
passivation
  +     * activity with other activities, in particular incoming invoking calls. <br>
  +     * The mutex is automatically removed when the corrispondent id is removed from
  +     * the cache, either by passivation or by removal.
  +     * This method must be synchronized with its dual, {@link #removeLock}.
  +     */
        public synchronized Sync getLock(Object id)
        {
                Sync mutex = (Sync)m_lockMap.get(id);
  @@ -271,22 +287,22 @@
                return mutex;
        }
        /**
  -      * Removes the mutex associated with the given id.
  -      * This method must be synchronized with its dual, {@link #getLock}.
  -      */
  +     * Removes the mutex associated with the given id.
  +     * This method must be synchronized with its dual, {@link #getLock}.
  +     */
        protected synchronized void removeLock(Object id)
        {
                Object mutex = m_lockMap.get(id);
                if (mutex != null)
                {
  -                 if (mutex instanceof BeanSemaphore)
  -                 {
  -                     ((BeanSemaphore)mutex).invalidate();
  -                 }
  -                 m_lockMap.remove(id);
  +                     if (mutex instanceof BeanSemaphore)
  +                     {
  +                             ((BeanSemaphore)mutex).invalidate();
  +                     }
  +                     m_lockMap.remove(id);
                }
        }
  -
  +     
        // XmlLoadable implementation ----------------------------------------------
        public void importXml(Element element) throws DeploymentException
        {
  @@ -302,7 +318,7 @@
                {
                        throw new DeploymentException("Can't create cache policy", x);
                }
  -
  +             
                Element policyConf = MetaData.getOptionalChild(element, 
"cache-policy-conf");
                if (policyConf != null)
                {
  @@ -319,7 +335,7 @@
                        }
                }
        }
  -
  +     
        /* From Service interface*/
        public void init() throws Exception
        {
  @@ -328,16 +344,16 @@
                String threadName = "Passivator Thread for " + 
getContainer().getBeanMetaData().getEjbName();
                ClassLoader cl = getContainer().getClassLoader();
                m_passivator = new PassivatorQueue(threadName, cl);
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        // Setup JMS for cache monitoring
                        Context namingContext = new InitialContext();
                        Object factoryRef = 
namingContext.lookup("TopicConnectionFactory");
                        TopicConnectionFactory factory = 
(TopicConnectionFactory)PortableRemoteObject.narrow(factoryRef, 
TopicConnectionFactory.class);
  -
  +                     
                        m_jmsConnection = factory.createTopicConnection();
  -
  +                     
                        Object topicRef = namingContext.lookup("topic/metrics");
                        m_jmsTopic = (Topic)PortableRemoteObject.narrow(topicRef, 
Topic.class);
                        m_jmsSession = m_jmsConnection.createTopicSession(false, 
Session.DUPS_OK_ACKNOWLEDGE);
  @@ -349,7 +365,7 @@
        {
                getCache().start();
                m_passivator.start();
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        m_jmsConnection.start();
  @@ -363,9 +379,9 @@
                {
                        getCache().stop();
                }
  -
  +             
                if (m_passivator != null) {m_passivator.stop();}
  -
  +                     
                if (isJMSMonitoringEnabled() && m_jmsConnection != null)
                {
                        try
  @@ -388,32 +404,32 @@
                        catch (JMSException ignored) {}
                }
        }
  -
  +     
        // Y overrides ---------------------------------------------------
  -
  +     
        // Package protected ---------------------------------------------
  -
  +     
        // Protected -----------------------------------------------------
        /**
  -      * Schedules the given EnterpriseContext for passivation
  -      * @see PassivationHelper#schedule
  -      */
  +     * Schedules the given EnterpriseContext for passivation
  +     * @see PassivationHelper#schedule
  +     */
        protected void schedulePassivation(EnterpriseContext ctx)
        {
                m_passivationHelper.schedule(ctx);
                logPassivationScheduled(getKey(ctx));
        }
        /**
  -      * Tries to unschedule the given EnterpriseContext for passivation; returns
  -      * the unscheduled context if it wasn't passivated yet, null if the
  -      * passivation already happened.
  -      * @see PassivationHelper#unschedule
  -      */
  +     * Tries to unschedule the given EnterpriseContext for passivation; returns
  +     * the unscheduled context if it wasn't passivated yet, null if the
  +     * passivation already happened.
  +     * @see PassivationHelper#unschedule
  +     */
        protected EnterpriseContext unschedulePassivation(Object id)
        {
                return m_passivationHelper.unschedule(id);
        }
  -
  +     
        protected void logActivation(Object id)
        {
                m_buffer.setLength(0);
  @@ -422,7 +438,7 @@
                m_buffer.append(" with id = ");
                m_buffer.append(id);
                Logger.debug(m_buffer.toString());
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        // Prepare JMS message
  @@ -435,12 +451,12 @@
                        {
                                Logger.exception(x);
                        }
  -
  +                     
                        // Send JMS Message
                        sendMessage(message);
                }
        }
  -
  +     
        protected void logPassivationScheduled(Object id)
        {
                m_buffer.setLength(0);
  @@ -449,7 +465,7 @@
                m_buffer.append(" with id = ");
                m_buffer.append(id);
                Logger.debug(m_buffer.toString());
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        // Prepare JMS message
  @@ -463,12 +479,12 @@
                        {
                                Logger.exception(x);
                        }
  -
  +                     
                        // Send JMS Message
                        sendMessage(message);
                }
        }
  -
  +     
        protected void logPassivation(Object id)
        {
                m_buffer.setLength(0);
  @@ -477,7 +493,7 @@
                m_buffer.append(" with id = ");
                m_buffer.append(id);
                Logger.debug(m_buffer.toString());
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        // Prepare JMS message
  @@ -491,12 +507,12 @@
                        {
                                Logger.exception(x);
                        }
  -
  +                     
                        // Send JMS Message
                        sendMessage(message);
                }
        }
  -
  +     
        protected void logPassivationPostponed(Object id)
        {
                m_buffer.setLength(0);
  @@ -505,7 +521,7 @@
                m_buffer.append(" with id = ");
                m_buffer.append(id);
                Logger.debug(m_buffer.toString());
  -
  +             
                if (isJMSMonitoringEnabled())
                {
                        // Prepare JMS message
  @@ -519,86 +535,86 @@
                        {
                                Logger.exception(x);
                        }
  -
  +                     
                        // Send JMS Message
                        sendMessage(message);
                }
        }
  -
  +     
        /**
  -      * Returns the container for this cache.
  -      */
  +     * Returns the container for this cache.
  +     */
        protected abstract Container getContainer();
        /**
  -      * Returns the cache policy used for this cache.
  -      */
  +     * Returns the cache policy used for this cache.
  +     */
        protected CachePolicy getCache() {return m_cache;}
        /**
  -      * Returns the mutex used to sync access to the cache policy object
  -      */
  +     * Returns the mutex used to sync access to the cache policy object
  +     */
        public Object getCacheLock()
        {
                return m_cacheLock;
        }
        /**
  -      * Passivates the given EnterpriseContext
  -      */
  +     * Passivates the given EnterpriseContext
  +     */
        protected abstract void passivate(EnterpriseContext ctx) throws 
RemoteException;
        /**
  -      * Activates the given EnterpriseContext
  -      */
  +     * Activates the given EnterpriseContext
  +     */
        protected abstract void activate(EnterpriseContext ctx) throws RemoteException;
        /**
  -      * Acquires an EnterpriseContext from the pool
  -      */
  +     * Acquires an EnterpriseContext from the pool
  +     */
        protected abstract EnterpriseContext acquireContext() throws Exception;
        /**
  -      * Frees the given EnterpriseContext to the pool
  -      */
  +     * Frees the given EnterpriseContext to the pool
  +     */
        protected abstract void freeContext(EnterpriseContext ctx);
        /**
  -      * Returns the key used by the cache to map the given context
  -      */
  +     * Returns the key used by the cache to map the given context
  +     */
        protected abstract Object getKey(EnterpriseContext ctx);
        /**
  -      * Sets the given id as key for the given context
  -      */
  +     * Sets the given id as key for the given context
  +     */
        protected abstract void setKey(Object id, EnterpriseContext ctx);
        /**
  -      * Returns whether the given context can be passivated or not
  -      *
  -      */
  +     * Returns whether the given context can be passivated or not
  +     *
  +     */
        protected abstract boolean canPassivate(EnterpriseContext ctx);
  -
  +     
        // Private -------------------------------------------------------
  -
  +     
        // Inner classes -------------------------------------------------
        /**
  -      * Helper class that schedules, unschedules, and executes the passivation jobs.
  -      */
  +     * Helper class that schedules, unschedules, and executes the passivation jobs.
  +     */
        protected class PassivationHelper
        {
                /* The map that holds the passivation jobs posted */
                private Map m_passivationJobs;
  -
  +             
                protected PassivationHelper()
                {
                        m_passivationJobs = Collections.synchronizedMap(new HashMap());
                }
  -
  +             
                /**
  -              * Creates and schedules a {@link PassivationJob} for passivation
  -              */
  +             * Creates and schedules a {@link PassivationJob} for passivation
  +             */
                protected void schedule(EnterpriseContext bean)
                {
                        // Register only once the job to be able to unschedule its 
passivation
                        Object key = getKey(bean);
                        if (m_passivationJobs.get(key) == null)
                        {
  -                             // (Bill Burke) We can't rely on the EnterpriseContext 
to provide PassivationJob
  -                             // with a valid key because it may get freed to the 
InstancePool, then
  -                             // reused before the PassivationJob executes.
  -                             //
  +                             // (Bill Burke) We can't rely on the EnterpriseContext 
to provide PassivationJob
  +                             // with a valid key because it may get freed to the 
InstancePool, then
  +                             // reused before the PassivationJob executes.
  +                             //
                                PassivationJob job = new PassivationJob(bean, key)
                                {
                                        public void execute() throws Exception
  @@ -606,101 +622,101 @@
                                                EnterpriseContext ctx = 
this.getEnterpriseContext();
                                                if (ctx.getId() == null)
                                                {
  -                                                 // If this happens, then a 
passivation request for this bean was issued
  -                                                 // but not yet executed, and in 
the meanwhile the bean has been removed.
  -                                                 return;
  +                                                     // If this happens, then a 
passivation request for this bean was issued
  +                                                     // but not yet executed, and 
in the meanwhile the bean has been removed.
  +                                                     return;
                                                }
  -
  +                                             
                                                Object id = this.getKey();
  -
  +                                             
                                                /**
  -                                              * Synchronization / Passivation 
explanations:
  -                                              * The instance interceptor (II) first 
acquires the Sync object associated
  -                                              * with the given id, then asks to the 
instance cache (IC) for an enterprise
  -                                              * context.
  -                                              * The IC, if the context is not 
present, activates it and returns it.
  -                                              * If the context is not in the IC 
then or it has already been
  -                                              * passivated, or it is scheduled for 
passivation. If the latter is true,
  -                                              * then the job is canceled and 
passivation does not occur, and the context
  -                                              * is reinserted in the IC.
  -                                              * This activity synchronizes in the 
following order the following objects:
  -                                              * 1) the Sync object associated to 
the context's id via getLock(id)
  -                                              * 2) the cache lock object via 
getCacheLock()
  -                                              * 3) the passivation job, since 
cancel() is synchronized.
  -                                              * To avoid deadlock, here we MUST 
acquire these resources in the same
  -                                              * exact order.
  -                                              */
  +                                             * Synchronization / Passivation 
explanations:
  +                                             * The instance interceptor (II) first 
acquires the Sync object associated
  +                                             * with the given id, then asks to the 
instance cache (IC) for an enterprise
  +                                             * context.
  +                                             * The IC, if the context is not 
present, activates it and returns it.
  +                                             * If the context is not in the IC then 
or it has already been
  +                                             * passivated, or it is scheduled for 
passivation. If the latter is true,
  +                                             * then the job is canceled and 
passivation does not occur, and the context
  +                                             * is reinserted in the IC.
  +                                             * This activity synchronizes in the 
following order the following objects:
  +                                             * 1) the Sync object associated to the 
context's id via getLock(id)
  +                                             * 2) the cache lock object via 
getCacheLock()
  +                                             * 3) the passivation job, since 
cancel() is synchronized.
  +                                             * To avoid deadlock, here we MUST 
acquire these resources in the same
  +                                             * exact order.
  +                                             */
                                                Sync mutex = (Sync)getLock(id);
  -
  +                                             
                                                try
                                                {
                                                        mutex.acquire();
  -
  +                                                     
                                                        synchronized (getCacheLock())
                                                        {
  -                                                         // This is absolutely 
fundamental: the job must be removed from
  -                                                         // the map in every case. 
If it remains there, the call to
  -                                                         // 
PassivationHelper.unschedule() will cause the corrispondent
  -                                                         // context to be 
reinserted in the cache, and if then is passivated
  -                                                         // we have a context 
without meaning in the cache
  -                                                         
m_passivationJobs.remove(id);
  -                                                         
  -                                                         synchronized (this)
  -                                                         {
  -                                                             if (ctx instanceof 
EntityEnterpriseContext)
  -                                                             {
  -                                                                 // Verify that 
this ctx hasn't already
  -                                                                 // been freed and 
re-used by another thread.
  -                                                                 if 
(!((EntityEnterpriseContext)ctx).getCacheKey().equals(id))
  -                                                                 {
  -                                                                     // ctx has 
been freed then re-used in another thread.
  -                                                                     return;
  -                                                                 }
  -                                                             }
  -                                                             if (!canPassivate(ctx))
  +                                                             // This is absolutely 
fundamental: the job must be removed from
  +                                                             // the map in every 
case. If it remains there, the call to
  +                                                             // 
PassivationHelper.unschedule() will cause the corrispondent
  +                                                             // context to be 
reinserted in the cache, and if then is passivated
  +                                                             // we have a context 
without meaning in the cache
  +                                                             
m_passivationJobs.remove(id);
  +                                                             
  +                                                             synchronized (this)
                                                                {
  -                                                                 // This check is 
done because there could have been
  -                                                                 // a request for 
passivation of this bean, but before
  -                                                                 // being 
passivated it got a request and has already
  -                                                                 // been inserted 
in the cache by the cache
  -                                                                 if 
(getCache().peek(id) == null)
  -                                                                 {
  -                                                                     
getCache().insert(id, ctx);
  -                                                                 }
  -                                                                 
  -                                                                 
logPassivationPostponed(id);
  -                                                                 
  -                                                                 return;
  -                                                             }
  -                                                             else
  -                                                             {
  -                                                                 if (!isCancelled())
  -                                                                 {
  -                                                                     try
  +                                                                     if (ctx 
instanceof EntityEnterpriseContext)
  +                                                                     {
  +                                                                             // 
Verify that this ctx hasn't already
  +                                                                             // 
been freed and re-used by another thread.
  +                                                                             if 
(!((EntityEnterpriseContext)ctx).getCacheKey().equals(id))
  +                                                                             {
  +                                                                                    
 // ctx has been freed then re-used in another thread.
  +                                                                                    
 return;
  +                                                                             }
  +                                                                     }
  +                                                                     if 
(!canPassivate(ctx))
                                                                        {
  -                                                                         // If the 
next call throws RemoteException we reinsert
  -                                                                         // the 
bean in the cache; every successive passivation
  -                                                                         // attempt 
will fail. The other policy would have been
  -                                                                         // to 
remove it, but then clients unexpectedly won't
  -                                                                         // find it 
anymore. On the other hand, on the server
  -                                                                         // log it 
is possible to see that passivation for the
  -                                                                         // bean 
failed, and fix it. See EJB 1.1, 6.4.1
  -                                                                         
passivate(ctx);
  -                                                                         executed();
  -                                                                         
removeLock(id);
  -                                                                         
freeContext(ctx);
  -                                                                         
  -                                                                         
logPassivation(id);
  +                                                                             // 
This check is done because there could have been
  +                                                                             // a 
request for passivation of this bean, but before
  +                                                                             // 
being passivated it got a request and has already
  +                                                                             // 
been inserted in the cache by the cache
  +                                                                             if 
(getCache().peek(id) == null)
  +                                                                             {
  +                                                                                    
 getCache().insert(id, ctx);
  +                                                                             }
  +                                                                             
  +                                                                             
logPassivationPostponed(id);
  +                                                                             
  +                                                                             return;
                                                                        }
  -                                                                     catch 
(RemoteException x)
  +                                                                     else
                                                                        {
  -                                                                         // Can't 
passivate this bean, reinsert it in the cache
  -                                                                         
getCache().insert(id, ctx);
  -                                                                         throw x;
  +                                                                             if 
(!isCancelled())
  +                                                                             {
  +                                                                                    
 try
  +                                                                                    
 {
  +                                                                                    
         // If the next call throws RemoteException we reinsert
  +                                                                                    
         // the bean in the cache; every successive passivation
  +                                                                                    
         // attempt will fail. The other policy would have been
  +                                                                                    
         // to remove it, but then clients unexpectedly won't
  +                                                                                    
         // find it anymore. On the other hand, on the server
  +                                                                                    
         // log it is possible to see that passivation for the
  +                                                                                    
         // bean failed, and fix it. See EJB 1.1, 6.4.1
  +                                                                                    
         passivate(ctx);
  +                                                                                    
         executed();
  +                                                                                    
         removeLock(id);
  +                                                                                    
         freeContext(ctx);
  +                                                                                    
         
  +                                                                                    
         logPassivation(id);
  +                                                                                    
 }
  +                                                                                    
 catch (RemoteException x)
  +                                                                                    
 {
  +                                                                                    
         // Can't passivate this bean, reinsert it in the cache
  +                                                                                    
         getCache().insert(id, ctx);
  +                                                                                    
         throw x;
  +                                                                                    
 }
  +                                                                             }
                                                                        }
  -                                                                 }
                                                                }
  -                                                         }
                                                        }
                                                }
                                                catch (InterruptedException ignored) {}
  @@ -710,7 +726,7 @@
                                                }
                                        }
                                };
  -
  +                             
                                // This method is entered only by one thread at a 
time, since the only caller
                                // call it only after having sync on the cache lock 
via getCacheLock().
                                // However, enforce this sync'ing on the passivation 
job's map
  @@ -720,7 +736,7 @@
                                        {
                                                // Register job
                                                m_passivationJobs.put(key, job);
  -
  +                                             
                                                // Schedule the job for passivation
                                                m_passivator.putJob(job);
                                        }
  @@ -735,15 +751,15 @@
                        }
                }
                /**
  -              * Tries to unschedule a job paired with the given context's id
  -              * @return null if the bean has been passivated, the context
  -              * paired with the given id otherwise
  -              */
  +             * Tries to unschedule a job paired with the given context's id
  +             * @return null if the bean has been passivated, the context
  +             * paired with the given id otherwise
  +             */
                protected EnterpriseContext unschedule(Object id)
                {
                        // I chose not to remove canceled job here becauses multiple
                        // unscheduling requests can arrive. This way all will be 
served
  -
  +                     
                        // Is the passivation job for id still to be executed ?
                        PassivationJob job = (PassivationJob)m_passivationJobs.get(id);
                        if (job != null)
  @@ -768,75 +784,75 @@
   }
   
   /**
  - * Abstract class for passivation jobs.
  - * Subclasses should implement {@link #execute} synchronizing it in some way because
  - * the execute method is normally called in the passivation thread,
  - * while the cancel method is normally called from another thread.
  - * To avoid that subclasses override methods of this class without
  - * make them synchronized (except execute of course), they're declared final.
  - */
  +* Abstract class for passivation jobs.
  +* Subclasses should implement {@link #execute} synchronizing it in some way because
  +* the execute method is normally called in the passivation thread,
  +* while the cancel method is normally called from another thread.
  +* To avoid that subclasses override methods of this class without
  +* make them synchronized (except execute of course), they're declared final.
  +*/
   abstract class PassivationJob implements Executable
   {
        private EnterpriseContext m_context;
        private Object m_key;
        private boolean m_cancelled;
        private boolean m_executed;
  -
  +     
        PassivationJob(EnterpriseContext ctx, Object key)
        {
                m_context = ctx;
                m_key = key;
        }
  -
  +     
        public abstract void execute() throws Exception;
  -
  -        /**
  -      * (Bill Burke) We can't rely on the EnterpriseContext to provide 
PassivationJob
  -      * with a valid key because it may get freed to the InstancePool, then
  -      * reused before the PassivationJob executes.
  -      */
  -        final Object getKey()
  -        {
  -         return m_key;
  +     
  +     /**
  +     * (Bill Burke) We can't rely on the EnterpriseContext to provide PassivationJob
  +     * with a valid key because it may get freed to the InstancePool, then
  +     * reused before the PassivationJob executes.
  +     */
  +     final Object getKey()
  +     {
  +             return m_key;
        }
        /**
  -      * Returns the EnterpriseContext associated with this passivation job,
  -      * so the bean that will be passivated.
  -      * No need to synchronize access to this method, since the returned
  -      * reference is immutable
  -      */
  +     * Returns the EnterpriseContext associated with this passivation job,
  +     * so the bean that will be passivated.
  +     * No need to synchronize access to this method, since the returned
  +     * reference is immutable
  +     */
        final EnterpriseContext getEnterpriseContext()
        {
                return m_context;
        }
        /**
  -      * Mark this job for cancellation.
  -      * @see #isCancelled
  -      */
  +     * Mark this job for cancellation.
  +     * @see #isCancelled
  +     */
        final synchronized void cancel()
        {
                m_cancelled = true;
        }
        /**
  -      * Returns whether this job has been marked for cancellation
  -      * @see #cancel
  -      */
  +     * Returns whether this job has been marked for cancellation
  +     * @see #cancel
  +     */
        final synchronized boolean isCancelled()
        {
                return m_cancelled;
        }
        /**
  -      * Mark this job as executed
  -      * @see #isExecuted
  -      */
  +     * Mark this job as executed
  +     * @see #isExecuted
  +     */
        final synchronized void executed()
        {
                m_executed = true;
        }
        /**
  -      * Returns whether this job has been executed
  -      * @see #executed
  -      */
  +     * Returns whether this job has been executed
  +     * @see #executed
  +     */
        final synchronized boolean isExecuted()
        {
                return m_executed;
  @@ -846,24 +862,24 @@
   class PassivatorQueue extends WorkerQueue
   {
        /**
  -      * Used for debug purposes, holds the scheduled passivation jobs
  -      */
  -//   private Map m_map = new HashMap();
  -
  +     * Used for debug purposes, holds the scheduled passivation jobs
  +     */
  +     //      private Map m_map = new HashMap();
  +     
        /**
  -      * Creates a new passivator queue with default thread name of
  -      * "Passivator Thread".
  -      */
  +     * Creates a new passivator queue with default thread name of
  +     * "Passivator Thread".
  +     */
        PassivatorQueue()
        {
                this("Passivator Thread", null);
        }
        /**
  -      * Creates a new passivator queue with the given thread name and given
  -      * context class loader. <br>
  -      * @param threadName the name of the passivator thread
  -      * @param cl the context class loader; if null the context class loader is not 
set.
  -      */
  +     * Creates a new passivator queue with the given thread name and given
  +     * context class loader. <br>
  +     * @param threadName the name of the passivator thread
  +     * @param cl the context class loader; if null the context class loader is not 
set.
  +     */
        PassivatorQueue(String threadName, ClassLoader cl)
        {
                super(threadName);
  @@ -873,43 +889,43 @@
                }
        }
        /**
  -      * Overridden for debug purposes
  -      *//*
  +     * Overridden for debug purposes
  +     *//*
        protected Executable getJobImpl() throws InterruptedException
        {
  -             PassivationJob j = (PassivationJob)super.getJobImpl();
  -             EnterpriseContext ctx = j.getEnterpriseContext();
  -             Object id = ctx.getId();
  -             m_map.remove(id);
  -             return j;
  +     PassivationJob j = (PassivationJob)super.getJobImpl();
  +     EnterpriseContext ctx = j.getEnterpriseContext();
  +     Object id = ctx.getId();
  +     m_map.remove(id);
  +     return j;
        }
        */
        /**
  -      * Overridden for debug purposes
  -      *//*
  +     * Overridden for debug purposes
  +     *//*
        protected void putJobImpl(Executable job)
        {
  -             PassivationJob j = (PassivationJob)job;
  -             EnterpriseContext ctx = j.getEnterpriseContext();
  -             Object id = ctx.getId();
  -             if (m_map.get(id) != null)
  -             {
  -                     // Here is a bug, job requests are scheduled only once per 
bean.
  -                     System.err.println("DUPLICATE PASSIVATION JOB INSERTION FOR ID 
= " + ctx.getId());
  -                     System.err.println("CTX isLocked: " + ctx.isLocked());
  -                     System.err.println("CTX transaction: " + ctx.getTransaction());
  -                     throw new IllegalStateException();
  -             }
  -             else
  -             {
  -                     m_map.put(id, job);
  -             }
  -             super.putJobImpl(job);
  +     PassivationJob j = (PassivationJob)job;
  +     EnterpriseContext ctx = j.getEnterpriseContext();
  +     Object id = ctx.getId();
  +     if (m_map.get(id) != null)
  +     {
  +     // Here is a bug, job requests are scheduled only once per bean.
  +     System.err.println("DUPLICATE PASSIVATION JOB INSERTION FOR ID = " + 
ctx.getId());
  +     System.err.println("CTX isLocked: " + ctx.isLocked());
  +     System.err.println("CTX transaction: " + ctx.getTransaction());
  +     throw new IllegalStateException();
  +     }
  +     else
  +     {
  +     m_map.put(id, job);
  +     }
  +     super.putJobImpl(job);
        }
        */
        /**
  -      * Logs exceptions thrown during job execution.
  -      */
  +     * Logs exceptions thrown during job execution.
  +     */
        protected void logJobException(Exception x)
        {
                // Log system exceptions
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to