You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@locus.apache.org on 2000/12/30 01:39:09 UTC

cvs commit: jakarta-struts/src/share/org/apache/struts/action ActionFormBean.java ActionFormBeans.java ActionForward.java ActionForwards.java ActionMapping.java ActionMappingBase.java ActionMappings.java ActionServlet.java

craigmcc    00/12/29 16:39:08

  Modified:    src/share/org/apache/struts/action ActionFormBean.java
                        ActionFormBeans.java ActionForward.java
                        ActionForwards.java ActionMapping.java
                        ActionMappingBase.java ActionMappings.java
                        ActionServlet.java
  Log:
  Clean up several issues in the core controller servlet classes:
  
  * Switch to customized collection class implementations that do not
    require synchronization for normal use.
  
  * Make the classes that are stored as servlet context attributes
    (either directly or indirectly) Serializable, to help on containers
    where this is important.
  
  * Fix a race condition where two simultaneous requests for the same
    action might cause two Action instances to be created (even though
    only one would be used from then on).
  
  Revision  Changes    Path
  1.2       +8 -5      jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java
  
  Index: ActionFormBean.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ActionFormBean.java	2000/09/20 04:20:21	1.1
  +++ ActionFormBean.java	2000/12/30 00:39:04	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v 1.1 2000/09/20 04:20:21 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/09/20 04:20:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v 1.2 2000/12/30 00:39:04 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/12/30 00:39:04 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,9 @@
   package org.apache.struts.action;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * An <strong>ActionFormBean</strong> is the definition of a form bean that
    * is loaded from a <code>&lt;form-bean&gt;</code> element in the Struts
  @@ -70,10 +73,10 @@
    * properties.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/09/20 04:20:21 $
  + * @version $Revision: 1.2 $ $Date: 2000/12/30 00:39:04 $
    */
   
  -public class ActionFormBean {
  +public class ActionFormBean implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  
  
  
  1.2       +35 -16    jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java
  
  Index: ActionFormBeans.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ActionFormBeans.java	2000/09/20 04:20:21	1.1
  +++ ActionFormBeans.java	2000/12/30 00:39:04	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v 1.1 2000/09/20 04:20:21 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/09/20 04:20:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v 1.2 2000/12/30 00:39:04 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/12/30 00:39:04 $
    *
    * ====================================================================
    *
  @@ -63,9 +63,8 @@
   package org.apache.struts.action;
   
   
  -import java.util.Enumeration;
  -import java.util.Hashtable;
  -import java.util.Vector;
  +import java.io.Serializable;
  +import org.apache.struts.util.FastHashMap;
   
   
   /**
  @@ -73,10 +72,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/09/20 04:20:21 $
  + * @version $Revision: 1.2 $ $Date: 2000/12/30 00:39:04 $
    */
   
  -public class ActionFormBeans {
  +public class ActionFormBeans implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  @@ -85,9 +84,34 @@
       /**
        * The collection of ActionFormBean instances, keyed by name.
        */
  -    private Hashtable formBeans = new Hashtable();
  +    protected FastHashMap formBeans = new FastHashMap();
   
   
  +    // ------------------------------------------------------------- Properties
  +
  +
  +    /**
  +     * Return the "fast" mode flag.
  +     */
  +    public boolean getFast() {
  +
  +        return (formBeans.getFast());
  +
  +    }
  +
  +
  +    /**
  +     * Set the "fast" mode flag.
  +     *
  +     * @param fast The new fast mode flag
  +     */
  +    public void setFast(boolean fast) {
  +
  +        formBeans.setFast(fast);
  +
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
  @@ -122,13 +146,8 @@
        */
       public String[] findFormBeans() {
   
  -	Vector names = new Vector();
  -	Enumeration keys = formBeans.keys();
  -	while (keys.hasMoreElements())
  -	    names.addElement(keys.nextElement());
  -	String results[] = new String[names.size()];
  -	names.copyInto(results);
  -	return (results);
  +        return
  +         ((String[]) formBeans.keySet().toArray(new String[formBeans.size()]));
   
       }
   
  
  
  
  1.3       +8 -5      jakarta-struts/src/share/org/apache/struts/action/ActionForward.java
  
  Index: ActionForward.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ActionForward.java	2000/06/24 23:26:22	1.2
  +++ ActionForward.java	2000/12/30 00:39:04	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v 1.2 2000/06/24 23:26:22 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/06/24 23:26:22 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v 1.3 2000/12/30 00:39:04 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/12/30 00:39:04 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,9 @@
   package org.apache.struts.action;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * An <strong>ActionForward</strong> represents a destination to which the
    * controller servlet, <code>ActionServlet</code>, might be directed to
  @@ -87,10 +90,10 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2000/06/24 23:26:22 $
  + * @version $Revision: 1.3 $ $Date: 2000/12/30 00:39:04 $
    */
   
  -public class ActionForward {
  +public class ActionForward implements Serializable {
   
   
       // ----------------------------------------------------------- Constructors
  
  
  
  1.3       +35 -16    jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java
  
  Index: ActionForwards.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ActionForwards.java	2000/06/30 01:19:32	1.2
  +++ ActionForwards.java	2000/12/30 00:39:04	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v 1.2 2000/06/30 01:19:32 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/06/30 01:19:32 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v 1.3 2000/12/30 00:39:04 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/12/30 00:39:04 $
    *
    * ====================================================================
    *
  @@ -63,9 +63,8 @@
   package org.apache.struts.action;
   
   
  -import java.util.Enumeration;
  -import java.util.Hashtable;
  -import java.util.Vector;
  +import java.io.Serializable;
  +import org.apache.struts.util.FastHashMap;
   
   
   /**
  @@ -73,10 +72,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2000/06/30 01:19:32 $
  + * @version $Revision: 1.3 $ $Date: 2000/12/30 00:39:04 $
    */
   
  -public class ActionForwards {
  +public class ActionForwards implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  @@ -85,9 +84,34 @@
       /**
        * The collection of ActionForward instances, keyed by logical name.
        */
  -    private Hashtable forwards = new Hashtable();
  +    private FastHashMap forwards = new FastHashMap();
   
   
  +    // ------------------------------------------------------------- Properties
  +
  +
  +    /**
  +     * Return the "fast" mode flag.
  +     */
  +    public boolean getFast() {
  +
  +        return (forwards.getFast());
  +
  +    }
  +
  +
  +    /**
  +     * Set the "fast" mode flag.
  +     *
  +     * @param fast The new fast mode flag
  +     */
  +    public void setFast(boolean fast) {
  +
  +        forwards.setFast(fast);
  +
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
  @@ -122,13 +146,8 @@
        */
       public String[] findForwards() {
   
  -	Vector names = new Vector();
  -	Enumeration keys = forwards.keys();
  -	while (keys.hasMoreElements())
  -	    names.addElement(keys.nextElement());
  -	String results[] = new String[names.size()];
  -	names.copyInto(results);
  -	return (results);
  +        return
  +           ((String[]) forwards.keySet().toArray(new String[forwards.size()]));
   
       }
   
  
  
  
  1.12      +8 -5      jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java
  
  Index: ActionMapping.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ActionMapping.java	2000/11/30 20:12:50	1.11
  +++ ActionMapping.java	2000/12/30 00:39:04	1.12
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.11 2000/11/30 20:12:50 craigmcc Exp $
  - * $Revision: 1.11 $
  - * $Date: 2000/11/30 20:12:50 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.12 2000/12/30 00:39:04 craigmcc Exp $
  + * $Revision: 1.12 $
  + * $Date: 2000/12/30 00:39:04 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,9 @@
   package org.apache.struts.action;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * An <strong>ActionMapping</strong> represents the information that the
    * controller servlet, <code>ActionServlet</code>, knows about the mapping
  @@ -141,10 +144,10 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.11 $ $Date: 2000/11/30 20:12:50 $
  + * @version $Revision: 1.12 $ $Date: 2000/12/30 00:39:04 $
    */
   
  -public class ActionMapping {
  +public class ActionMapping implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  
  
  
  1.9       +4 -7      jakarta-struts/src/share/org/apache/struts/action/ActionMappingBase.java
  
  Index: ActionMappingBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappingBase.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ActionMappingBase.java	2000/09/20 04:20:21	1.8
  +++ ActionMappingBase.java	2000/12/30 00:39:05	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappingBase.java,v 1.8 2000/09/20 04:20:21 craigmcc Exp $
  - * $Revision: 1.8 $
  - * $Date: 2000/09/20 04:20:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappingBase.java,v 1.9 2000/12/30 00:39:05 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2000/12/30 00:39:05 $
    *
    * ====================================================================
    *
  @@ -63,9 +63,6 @@
   package org.apache.struts.action;
   
   
  -import java.util.Hashtable;
  -
  -
   /**
    * A minimal implementation of <strong>ActionMapping</strong> that contains
    * only the required properties.  Additional properties can be provided by
  @@ -74,7 +71,7 @@
    * @deprecated Now that ActionMapping is a class, you should use it intead
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.8 $ $Date: 2000/09/20 04:20:21 $
  + * @version $Revision: 1.9 $ $Date: 2000/12/30 00:39:05 $
    */
   
   public class ActionMappingBase extends ActionMapping {
  
  
  
  1.5       +35 -17    jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java
  
  Index: ActionMappings.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ActionMappings.java	2000/11/19 02:11:15	1.4
  +++ ActionMappings.java	2000/12/30 00:39:05	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v 1.4 2000/11/19 02:11:15 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/11/19 02:11:15 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v 1.5 2000/12/30 00:39:05 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/12/30 00:39:05 $
    *
    * ====================================================================
    *
  @@ -63,11 +63,12 @@
   package org.apache.struts.action;
   
   
  -import java.util.Enumeration;
  -import java.util.Hashtable;
  -import java.util.Vector;
  +import java.io.Serializable;
  +import java.util.ArrayList;
  +import java.util.Iterator;
   import javax.servlet.ServletRequest;
   import javax.servlet.http.HttpServletRequest;
  +import org.apache.struts.util.FastHashMap;
   
   
   /**
  @@ -75,10 +76,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2000/11/19 02:11:15 $
  + * @version $Revision: 1.5 $ $Date: 2000/12/30 00:39:05 $
    */
   
  -public class ActionMappings {
  +public class ActionMappings implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  @@ -87,13 +88,13 @@
       /**
        * The collection of ActionMapping instances, keyed by request path.
        */
  -    protected Hashtable mappings = new Hashtable();
  +    protected FastHashMap mappings = new FastHashMap();
   
   
       /**
        * The ActionServlet instance of our owning application.
        */
  -    protected ActionServlet servlet = null;
  +    transient protected ActionServlet servlet = null;
   
   
       /**
  @@ -106,6 +107,28 @@
   
   
       /**
  +     * Return the "fast" mode flag.
  +     */
  +    public boolean getFast() {
  +
  +        return (mappings.getFast());
  +
  +    }
  +
  +
  +    /**
  +     * Set the "fast" mode flag.
  +     *
  +     * @param fast The new fast mode flag
  +     */
  +    public void setFast(boolean fast) {
  +
  +        mappings.setFast(fast);
  +
  +    }
  +
  +
  +    /**
        * Return the Action that should handle unknown request paths, if any.
        * The default implementation casts the request to HttpServletRequest
        * and calls the corresponding version of this method.
  @@ -202,13 +225,8 @@
        */
       public String[] findMappings() {
   
  -	Vector paths = new Vector();
  -	Enumeration keys = mappings.keys();
  -	while (keys.hasMoreElements())
  -	    paths.addElement(keys.nextElement());
  -	String results[] = new String[paths.size()];
  -	paths.copyInto(results);
  -	return (results);
  +        return
  +           ((String[]) mappings.keySet().toArray(new String[mappings.size()]));
   
       }
   
  
  
  
  1.47      +65 -32    jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
  
  Index: ActionServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -r1.46 -r1.47
  --- ActionServlet.java	2000/12/29 20:06:22	1.46
  +++ ActionServlet.java	2000/12/30 00:39:05	1.47
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.46 2000/12/29 20:06:22 craigmcc Exp $
  - * $Revision: 1.46 $
  - * $Date: 2000/12/29 20:06:22 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.47 2000/12/30 00:39:05 craigmcc Exp $
  + * $Revision: 1.47 $
  + * $Date: 2000/12/30 00:39:05 $
    *
    * ====================================================================
    *
  @@ -67,13 +67,11 @@
   import java.io.IOException;
   import java.net.URL;
   import java.sql.SQLException;
  -import java.util.Hashtable;
  -import java.util.Enumeration;
  +import java.util.ArrayList;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.Locale;
   import java.util.MissingResourceException;
  -import java.util.Vector;
   import javax.servlet.RequestDispatcher;
   import javax.servlet.ServletException;
   import javax.servlet.UnavailableException;
  @@ -86,6 +84,7 @@
   import org.apache.struts.digester.Rule;
   import org.apache.struts.taglib.form.Constants;
   import org.apache.struts.util.BeanUtils;
  +import org.apache.struts.util.FastHashMap;
   import org.apache.struts.util.GenericDataSource;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.MessageResourcesFactory;
  @@ -212,7 +211,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.46 $ $Date: 2000/12/29 20:06:22 $
  + * @version $Revision: 1.47 $ $Date: 2000/12/30 00:39:05 $
    */
   
   public class ActionServlet
  @@ -226,7 +225,7 @@
        * The set of Action instances that have been created and initialized,
        * keyed by the fully qualified Java class name.
        */
  -    protected Hashtable actions = new Hashtable();
  +    protected FastHashMap actions = new FastHashMap();
   
   
       /**
  @@ -253,7 +252,7 @@
        * if any, keyed by the servlet context attribute under which they are
        * stored.
        */
  -    protected HashMap dataSources = new HashMap();
  +    protected FastHashMap dataSources = new FastHashMap();
   
   
       /**
  @@ -414,6 +413,7 @@
        */
       public void init() throws ServletException {
   
  +        initActions();
   	initInternal();
   	initDebug();
   	initApplication();
  @@ -480,9 +480,7 @@
   
           if (key == null)
               key = Action.DATA_SOURCE_KEY;
  -        synchronized (dataSources) {
  -            dataSources.put(key, dataSource);
  -        }
  +        dataSources.put(key, dataSource);
   
       }
   
  @@ -531,12 +529,10 @@
        */
       public DataSource findDataSource(String key) {
   
  -        synchronized (dataSources) {
  -            if (key == null)
  -                return ((DataSource) dataSources.get(Action.DATA_SOURCE_KEY));
  -            else
  -                return ((DataSource) dataSources.get(key));
  -        }
  +        if (key == null)
  +            return ((DataSource) dataSources.get(Action.DATA_SOURCE_KEY));
  +        else
  +            return ((DataSource) dataSources.get(key));
   
       }
   
  @@ -709,6 +705,7 @@
           destroyInternal();
   
           // Restart from our confirmation files
  +        initActions();
           initInternal();
           initDebug();
           initApplication();
  @@ -850,10 +847,9 @@
       protected void destroyActions() {
   
           synchronized (this.actions) {
  -            Vector actives = new Vector();
  -            Enumeration actions = this.actions.elements();
  -            while (actions.hasMoreElements()) {
  -                Action action = (Action) actions.nextElement();
  +            Iterator actions = this.actions.values().iterator();
  +            while (actions.hasNext()) {
  +                Action action = (Action) actions.next();
                   action.setServlet(null);
               }
               this.actions.clear();
  @@ -896,6 +892,7 @@
                       }
                   }
               }
  +            dataSources.setFast(false);
           }
   
       }
  @@ -912,6 +909,20 @@
   
   
       /**
  +     * Initialize the collection of previously instantiated Action instances.
  +     */
  +    protected void initActions() {
  +
  +        synchronized (actions) {
  +            actions.setFast(false);
  +            actions.clear();
  +            actions.setFast(true);
  +        }
  +
  +    }
  +
  +
  +    /**
        * Initialize the MessageResources bundle for this application, if any.
        *
        * @exception ServletException if we cannot initialize these resources
  @@ -976,6 +987,7 @@
                   }
                   getServletContext().setAttribute(key, dataSource);
               }
  +            dataSources.setFast(true);
           }
   
       }
  @@ -1204,8 +1216,14 @@
   
   	// Parse the input stream to configure our mappings
   	try {
  +            formBeans.setFast(false);
  +            forwards.setFast(false);
  +            mappings.setFast(false);
   	    digester.parse(input);
   	    input.close();
  +            mappings.setFast(true);
  +            forwards.setFast(true);
  +            formBeans.setFast(true);
   	} catch (SAXException e) {
   	    throw new ServletException
   		(internal.getMessage("configParse", config), e);
  @@ -1399,18 +1417,33 @@
   
           // Acquire the Action instance we will be using
           String actionClass = mapping.getType();
  +        if (debug >= 1)
  +            log(" Looking for Action instance for class " + actionClass);
           Action actionInstance = (Action) actions.get(actionClass);
           if (actionInstance == null) {
  -            try {
  -                Class clazz = Class.forName(actionClass);
  -                actionInstance = (Action) clazz.newInstance();
  -                actionInstance.setServlet(this);
  -                actions.put(actionClass, actionInstance);
  -            } catch (Throwable t) {
  -                log("Error creating Action instance for path '" +
  -                    mapping.getPath() + "', class name '" +
  -                    actionClass + "'", t);
  -                return (null);
  +            synchronized (actions) {
  +                if (debug >= 1)
  +                    log("  Double checking for Action instance already there");
  +                // Double check to avoid a race condition
  +                actionInstance = (Action) actions.get(actionClass);
  +                if (actionInstance != null)
  +                    return (actionInstance);
  +                // Go ahead and create the new Action instance
  +                // ASSERT:  This will never ever happen more than once
  +                //  for a particular action class name
  +                try {
  +                    if (debug >= 1)
  +                        log("  Creating new Action instance");
  +                    Class clazz = Class.forName(actionClass);
  +                    actionInstance = (Action) clazz.newInstance();
  +                    actionInstance.setServlet(this);
  +                    actions.put(actionClass, actionInstance);
  +                } catch (Throwable t) {
  +                    log("Error creating Action instance for path '" +
  +                        mapping.getPath() + "', class name '" +
  +                        actionClass + "'", t);
  +                    return (null);
  +                }
               }
           }
           return (actionInstance);