--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java	2004-11-24 17:55:09.000000000 +0100
+++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardContext.java	2009-06-10 11:58:15.000000000 +0200
@@ -4262,10 +4262,6 @@
                     ((Lifecycle) pipeline).start();
 		}
 
-                if(getProcessTlds()) {
-		    processTlds();
-		}
-
                 // Notify our interested LifecycleListeners
                 lifecycle.fireLifecycleEvent(START_EVENT, null);
 
@@ -4382,41 +4378,6 @@
         //cacheContext();
     }
 
-   /**
-    * Processes the TLDs.
-    *
-    * @throws LifecycleException If an error occurs
-    */
-    protected void processTlds() throws LifecycleException {
-      TldConfig tldConfig = new TldConfig();
-      tldConfig.setContext(this);
-
-      // (1)  check if the attribute has been defined
-      //      on the context element.
-      tldConfig.setTldValidation(tldValidation);
-      tldConfig.setTldNamespaceAware(tldNamespaceAware);
-
-      // (2) if the attribute wasn't defined on the context
-      //     try the host.
-      if (!tldValidation){
-        tldConfig.setTldValidation
-          (((StandardHost) getParent()).getXmlValidation());
-      }
-
-      if (!tldNamespaceAware){
-        tldConfig.setTldNamespaceAware
-          (((StandardHost) getParent()).getXmlNamespaceAware());
-      }
-                    
-      try {
-        tldConfig.execute();
-      } catch (Exception ex) {
-        log.error("Error reading tld listeners " 
-                  + ex.toString(), ex);
-      }
-    }
-
-    
     private void cacheContext() {
         try {
             File workDir=new File( getWorkPath() );
@@ -5460,6 +5421,10 @@
                 throw e;
             }
         }
+        if (processTlds)
+        {
+           this.addLifecycleListener(new TldConfig());
+        }
         super.init();
         
         // Send j2ee.state.starting notification 
--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java	2004-11-24 17:55:14.000000000 +0100
+++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/ContextConfig.java	2009-06-10 11:40:43.000000000 +0200
@@ -241,10 +241,6 @@
         
         long t1=System.currentTimeMillis();
 
-        if (webDigester == null){
-            webDigester = createWebDigester();
-        }
-        
         URL url=null;
         // Process the application web.xml file
         synchronized (webDigester) {
@@ -497,10 +493,6 @@
             return;
         }
 
-        if (webDigester == null){
-            webDigester = createWebDigester();
-        }
-        
         // Process the default web.xml file
         synchronized (webDigester) {
             try {
@@ -591,6 +583,11 @@
     private synchronized void start() {
         // Called from StandardContext.start()
 
+        if (webDigester == null){
+            webDigester = createWebDigester();
+            webDigester.getParser();
+        }
+       
         if (log.isDebugEnabled())
             log.debug(sm.getString("contextConfig.start"));
         context.setConfigured(false);
--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/LocalStrings.properties	2004-11-24 17:55:15.000000000 +0100
+++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/LocalStrings.properties	2009-06-10 11:21:11.000000000 +0200
@@ -55,6 +55,8 @@
 hostConfig.undeploy=Undeploying web application at context path {0}
 hostConfig.undeploy.error=Error undeploying web application at context path {0}
 hostConfig.undeploying=Undeploying deployed web applications
+tldConfig.cce=Lifecycle event data object {0} is not a Context
+tldConfig.execute=Error processing TDL files for context path {0}
 userConfig.database=Exception loading user database
 userConfig.deploy=Deploying web application for user {0}
 userConfig.deploying=Deploying user web applications
--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/TldConfig.java	2004-11-24 17:55:15.000000000 +0100
+++ jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/startup/TldConfig.java	2009-06-10 11:20:31.000000000 +0200
@@ -45,20 +45,25 @@
 
 import org.apache.catalina.Context;
 import org.apache.catalina.Globals;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
 import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
 import org.apache.catalina.util.StringManager;
 import org.apache.commons.digester.Digester;
 import org.xml.sax.InputSource;
 
 /**
- * Startup event listener for a <b>Context</b> that configures the properties
- * of that Context, and the associated defined servlets.
+ * Startup event listener for a <b>Context</b> that configures application
+ * listeners configured in any TLD files.
  *
  * @author Craig R. McClanahan
  * @author Jean-Francois Arcand
  * @author Costin Manolache
  */
-public final class TldConfig  {
+public final class TldConfig  implements LifecycleListener
+{
 
     // Names of JARs that are known not to contain any TLDs
     private static HashSet noTldJars;
@@ -399,20 +404,6 @@
     }
 
     /**
-     * Create (if necessary) and return a Digester configured to process a tag
-     * library descriptor, looking for additional listener classes to be
-     * registered.
-     */
-    private static Digester createTldDigester() {
-
-        return DigesterFactory.newDigester(tldValidation, 
-                                           tldNamespaceAware, 
-                                           new TldRuleSet());
-
-    }
-
-
-    /**
      * Scan the JAR file at the specified resource path for TLDs in the
      * <code>META-INF</code> subdirectory, and scan each TLD for application
      * event listeners that need to be registered.
@@ -504,10 +495,6 @@
     private void tldScanStream(InputSource resourceStream)
         throws Exception {
 
-        if (tldDigester == null){
-            tldDigester = createTldDigester();
-        }
-        
         synchronized (tldDigester) {
             try {
                 tldDigester.push(this);
@@ -715,4 +702,52 @@
 
         return jarPathMap;
     }
+                                  
+
+    public void lifecycleEvent(LifecycleEvent event) {
+        // Identify the context we are associated with
+        try {
+            context = (Context) event.getLifecycle();
+        } catch (ClassCastException e) {
+            log.error(sm.getString("tldConfig.cce", event.getLifecycle()), e);
+            return;
+        }
+        
+        if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {
+            init();
+        } else if (event.getType().equals(Lifecycle.START_EVENT)) {
+            try {
+                execute();
+            } catch (Exception e) {
+                log.error(sm.getString(
+                        "tldConfig.execute", context.getPath()), e);
+            }
+        } // Ignore the other event types - nothing to do 
+    }
+    
+    private void init() {
+        if (tldDigester == null){
+            // (1)  check if the attribute has been defined
+            //      on the context element.
+            setTldValidation(context.getTldValidation());
+            setTldNamespaceAware(context.getTldNamespaceAware());
+    
+            // (2) if the attribute wasn't defined on the context
+            //     try the host.
+            if (!tldValidation) {
+              setTldValidation(
+                      ((StandardHost) context.getParent()).getXmlValidation());
+            }
+    
+            if (!tldNamespaceAware) {
+              setTldNamespaceAware(
+                  ((StandardHost) context.getParent()).getXmlNamespaceAware());
+            }
+
+            tldDigester = DigesterFactory.newDigester(tldValidation, 
+                    tldNamespaceAware, 
+                    new TldRuleSet());
+            tldDigester.getParser();
+        }
+    }
 }
