You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/02/05 23:33:47 UTC

svn commit: r1067544 - in /myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces: application/ config/annotation/ context/servlet/ webapp/

Author: lu4242
Date: Sat Feb  5 22:33:47 2011
New Revision: 1067544

URL: http://svn.apache.org/viewvc?rev=1067544&view=rev
Log:
MYFACES-3001 Memory Leak in MyFaces 1.2 related to RuntimeConfig ThreadLocal (backport of MYFACES-2942, adding startup facesContext and externalContext and removing the ThreadLocal variable)

Added:
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupServletExternalContextImpl.java
Modified:
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializer.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/MyFacesServlet.java
    myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Sat Feb  5 22:33:47 2011
@@ -91,9 +91,6 @@ public class ApplicationImpl extends App
 
     private final static PropertyResolver PROPERTYRESOLVER = new PropertyResolverImpl();
 
-    // recives the runtime config instance during initializing
-    private final static ThreadLocal<RuntimeConfig> initializingRuntimeConfig = new ThreadLocal<RuntimeConfig>();
-
     // ~ Instance fields
     // ----------------------------------------------------------------------------
 
@@ -130,35 +127,13 @@ public class ApplicationImpl extends App
 
     public ApplicationImpl()
     {
-        this(internalGetRuntimeConfig());
+        this(getRuntimeConfig());
     }
 
-    private static RuntimeConfig internalGetRuntimeConfig()
+    private static RuntimeConfig getRuntimeConfig()
     {
-        if (initializingRuntimeConfig.get() == null)
-        {
-            //It may happen that the current thread value
-            //for initializingRuntimeConfig is not set 
-            //(note that this value is final, so it just 
-            //allow set only once per thread).
-            //So the better for this case is try to get
-            //the value using RuntimeConfig.getCurrentInstance()
-            //instead throw an IllegalStateException (only fails if
-            //the constructor is called before setInitializingRuntimeConfig).
-            //From other point of view, AbstractFacesInitializer do 
-            //the same as below, so there is not problem if
-            //we do this here and this is the best place to do
-            //this.
-            //log.info("initializingRuntimeConfig.get() == null, so loading from ExternalContext");
-            ApplicationImpl.setInitializingRuntimeConfig(
-                    RuntimeConfig.getCurrentInstance(
-                            FacesContext.getCurrentInstance()
-                            .getExternalContext()));
-
-            //throw new IllegalStateException("The runtime config instance which is created while initialize myfaces "
-            //        + "must be set through ApplicationImpl.setInitializingRuntimeConfig");
-        }
-        return initializingRuntimeConfig.get();
+        return RuntimeConfig.getCurrentInstance(
+                FacesContext.getCurrentInstance().getExternalContext());
     }
 
     ApplicationImpl(final RuntimeConfig runtimeConfig)
@@ -181,11 +156,6 @@ public class ApplicationImpl extends App
             log.trace("New Application instance created");
     }
 
-    public static void setInitializingRuntimeConfig(RuntimeConfig config)
-    {
-        initializingRuntimeConfig.set(config);
-    }
-
     // ~ Methods
     // ------------------------------------------------------------------------------------
 

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/DefaultLifecycleProviderFactory.java Sat Feb  5 22:33:47 2011
@@ -39,8 +39,8 @@ import java.lang.reflect.Constructor;
  */
 public class DefaultLifecycleProviderFactory extends LifecycleProviderFactory {
     private static Log log = LogFactory.getLog(DefaultLifecycleProviderFactory.class);
-    private static LifecycleProvider LIFECYCLE_PROVIDER_INSTANCE;
-    
+    public static final String LIFECYCLE_PROVIDER_INSTANCE_KEY = LifecycleProvider.class.getName() + ".LIFECYCLE_PROVIDER_INSTANCE";
+
     @JSFWebConfigParam(name="org.apache.myfaces.config.annotation.LifecycleProvider", since="1.1")
     public static final String LIFECYCLE_PROVIDER = LifecycleProvider.class.getName();
 
@@ -49,32 +49,47 @@ public class DefaultLifecycleProviderFac
     {
     }
 
+    @Override
     public LifecycleProvider getLifecycleProvider(ExternalContext externalContext)
     {
-        if (LIFECYCLE_PROVIDER_INSTANCE == null)
+        LifecycleProvider lifecycleProvider = null;
+        if (externalContext == null)
+        {
+            log.info("No ExternalContext using fallback LifecycleProvider.");
+            lifecycleProvider = resolveFallbackLifecycleProvider();
+        }
+        else
         {
-            if (externalContext == null)
+            lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
+        }
+        if (lifecycleProvider == null)
+        {
+            if (!resolveLifecycleProviderFromExternalContext(externalContext))
             {
-                log.info("No ExternalContext using fallback LifecycleProvider.");
-                resolveFallbackLifecycleProvider();
+                if (!resolveLifecycleProviderFromService(externalContext))
+                {
+                    lifecycleProvider = resolveFallbackLifecycleProvider();
+                    externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, lifecycleProvider);
+                }
+                else
+                {
+                    //Retrieve it because it was resolved
+                    lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
+                }
             }
             else
             {
-                if (!resolveLifecycleProviderFromExternalContext(externalContext))
-                {
-                    if (!resolveLifecycleProviderFromService(externalContext))
-                    {
-                        resolveFallbackLifecycleProvider();
-                    }
-                }
+                //Retrieve it because it was resolved
+                lifecycleProvider = (LifecycleProvider) externalContext.getApplicationMap().get(LIFECYCLE_PROVIDER_INSTANCE_KEY);
             }
-            log.info("Using LifecycleProvider "+ LIFECYCLE_PROVIDER_INSTANCE.getClass().getName());
+            log.info("Using LifecycleProvider "+ lifecycleProvider.getClass().getName());
         }
-        return LIFECYCLE_PROVIDER_INSTANCE;
+        return lifecycleProvider;
     }
 
+    @Override
     public void release() {
-        LIFECYCLE_PROVIDER_INSTANCE = null;
+
     }
 
 
@@ -90,7 +105,7 @@ public class DefaultLifecycleProviderFac
                 Object obj = createClass(lifecycleProvider, externalContext);
 
                 if (obj instanceof LifecycleProvider) {
-                    LIFECYCLE_PROVIDER_INSTANCE = (LifecycleProvider) obj;
+                    externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, (LifecycleProvider) obj);
                     return true;
                 }
             }
@@ -131,7 +146,7 @@ public class DefaultLifecycleProviderFac
                     DiscoverableLifecycleProvider discoverableLifecycleProvider =
                             (DiscoverableLifecycleProvider) obj;
                     if (discoverableLifecycleProvider.isAvailable()) {
-                        LIFECYCLE_PROVIDER_INSTANCE = discoverableLifecycleProvider;
+                        externalContext.getApplicationMap().put(LIFECYCLE_PROVIDER_INSTANCE_KEY, discoverableLifecycleProvider);
                         return true;
                     }
                 }
@@ -179,7 +194,7 @@ public class DefaultLifecycleProviderFac
     }
 
 
-    private void resolveFallbackLifecycleProvider()
+    private LifecycleProvider resolveFallbackLifecycleProvider()
     {
         try
         {
@@ -188,8 +203,7 @@ public class DefaultLifecycleProviderFac
         catch (ClassNotFoundException e)
         {
             // no annotation available don't process annotations
-            LIFECYCLE_PROVIDER_INSTANCE = new NoAnnotationLifecyleProvider();
-            return;
+            return new NoAnnotationLifecyleProvider(); 
         }
         Context context;
         try
@@ -199,20 +213,19 @@ public class DefaultLifecycleProviderFac
             {
                 ClassUtils.classForName("javax.ejb.EJB");
                 // Asume full JEE 5 container
-                LIFECYCLE_PROVIDER_INSTANCE = new AllAnnotationLifecycleProvider(context);
+                return new AllAnnotationLifecycleProvider(context);
             }
             catch (ClassNotFoundException e)
             {
                 // something else
-                LIFECYCLE_PROVIDER_INSTANCE = new ResourceAnnotationLifecycleProvider(context);
+                return new ResourceAnnotationLifecycleProvider(context);
             }
         }
         catch (NamingException e)
         {
             // no initial context available no injection
-            LIFECYCLE_PROVIDER_INSTANCE = new NoInjectionAnnotationLifecycleProvider();
             log.error("No InitialContext found. Using NoInjectionAnnotationProcessor.", e);
-
+            return new NoInjectionAnnotationLifecycleProvider();
         }
     }
 }

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/config/annotation/LifecycleProviderFactory.java Sat Feb  5 22:33:47 2011
@@ -20,19 +20,27 @@ package org.apache.myfaces.config.annota
 
 import org.apache.commons.discovery.tools.DiscoverSingleton;
 
-
+import javax.faces.FacesException;
 import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
 
 
 public abstract class LifecycleProviderFactory {
     protected static final String FACTORY_DEFAULT = DefaultLifecycleProviderFactory.class.getName();
 
-    private static volatile LifecycleProviderFactory INSTANCE;
+    private static final String FACTORY_KEY = LifecycleProviderFactory.class.getName();
 
     public static LifecycleProviderFactory getLifecycleProviderFactory()
     {
-        LifecycleProviderFactory instance = INSTANCE;
-        if (instance != null) {
+        // Since we always provide a StartupFacesContext on initialization time, this is safe:
+        return getLifecycleProviderFactory(FacesContext.getCurrentInstance().getExternalContext());
+    }
+    
+    public static LifecycleProviderFactory getLifecycleProviderFactory(ExternalContext ctx)
+    {
+        LifecycleProviderFactory instance = (LifecycleProviderFactory) ctx.getApplicationMap().get(FACTORY_KEY);
+        if (instance != null)
+        {
             return instance;
         }
         return (LifecycleProviderFactory) DiscoverSingleton.find(LifecycleProviderFactory.class, FACTORY_DEFAULT);
@@ -40,7 +48,7 @@ public abstract class LifecycleProviderF
 
 
     public static void setLifecycleProviderFactory(LifecycleProviderFactory instance) {
-        INSTANCE = instance;
+        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(FACTORY_KEY, instance);
     }
 
     public abstract LifecycleProvider getLifecycleProvider(ExternalContext externalContext);

Added: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java?rev=1067544&view=auto
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java (added)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java Sat Feb  5 22:33:47 2011
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.context.servlet;
+
+import javax.el.ELContext;
+import javax.el.ELContextEvent;
+import javax.el.ELContextListener;
+import javax.faces.FactoryFinder;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.render.RenderKit;
+import javax.faces.render.RenderKitFactory;
+
+import org.apache.myfaces.context.ReleaseableExternalContext;
+import org.apache.myfaces.el.unified.FacesELContext;
+
+/**
+ * Provides a base implementation of the FacesContext for the use
+ * in FacesContextImpl and StartupFacesContextImpl.
+ * 
+ * @author Jakob Korherr (latest modification by $Author: jakobk $)
+ * @version $Revision: 963629 $ $Date: 2010-07-13 04:29:07 -0500 (Mar, 13 Jul 2010) $
+ */
+public abstract class FacesContextImplBase extends FacesContext
+{
+
+    private Application _application;
+    private ExternalContext _externalContext;
+    private ReleaseableExternalContext _defaultExternalContext;
+    private UIViewRoot _viewRoot;
+    private RenderKitFactory _renderKitFactory;
+    private ELContext _elContext;
+    
+    // Variables used to cache values
+    private RenderKit _cachedRenderKit = null;
+    private String _cachedRenderKitId = null;
+    
+    protected boolean _released = false;
+    
+    /**
+     * Base constructor.
+     * Calls FacesContext.setCurrentInstance(this);
+     */
+    public FacesContextImplBase(final ExternalContext externalContext,
+            final ReleaseableExternalContext defaultExternalContext)
+    {
+        _externalContext = externalContext;
+        _defaultExternalContext = defaultExternalContext;
+        
+        // this FacesContext impl is now the current instance
+        // note that because this method is protected, it has to be called from here
+        FacesContext.setCurrentInstance(this);
+    }
+    
+    /**
+     * Releases the instance fields on FacesContextImplBase.
+     * Must be called by sub-classes, when overriding it!
+     */
+    @Override
+    public void release()
+    {
+        if (_defaultExternalContext != null)
+        {
+            _defaultExternalContext.release();
+            _defaultExternalContext = null;
+        }
+        
+        _application = null;
+        _externalContext = null;
+        _viewRoot = null;
+        _renderKitFactory = null;
+        _elContext = null;
+        _cachedRenderKit = null;
+        _cachedRenderKitId = null;
+        
+        _released = true;
+        FacesContext.setCurrentInstance(null);
+    }
+    
+    @Override
+    public final ExternalContext getExternalContext()
+    {
+        assertNotReleased();
+
+        return _externalContext;
+    }
+    
+    @Override
+    public final Application getApplication()
+    {
+        assertNotReleased();
+        
+        if (_application == null)
+        {
+            _application = ((ApplicationFactory) FactoryFinder.getFactory(
+                    FactoryFinder.APPLICATION_FACTORY)).getApplication();
+        }
+        
+        return _application;
+    }
+    
+    @Override
+    public final ELContext getELContext()
+    {
+        assertNotReleased();
+
+        if (_elContext != null)
+        {
+            return _elContext;
+        }
+
+        _elContext = new FacesELContext(getApplication().getELResolver(), this);
+
+        ELContextEvent event = new ELContextEvent(_elContext);
+        for (ELContextListener listener : getApplication().getELContextListeners())
+        {
+            listener.contextCreated(event);
+        }
+
+        return _elContext;
+    }
+
+    @Override
+    public UIViewRoot getViewRoot()
+    {
+        assertNotReleased();
+
+        return _viewRoot;
+    }
+    
+    @Override
+    public final void setViewRoot(final UIViewRoot viewRoot)
+    {
+        assertNotReleased();
+
+        _viewRoot = viewRoot;
+    }
+    
+    @Override
+    public final RenderKit getRenderKit()
+    {
+        assertNotReleased();
+
+        if (getViewRoot() == null)
+        {
+            return null;
+        }
+
+        String renderKitId = getViewRoot().getRenderKitId();
+
+        if (renderKitId == null)
+        {
+            return null;
+        }
+        
+        if (_cachedRenderKitId == null || !renderKitId.equals(_cachedRenderKitId))
+        {
+            _cachedRenderKitId = renderKitId;
+            if (_renderKitFactory == null)
+            {
+                _renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+            }
+            _cachedRenderKit = _renderKitFactory.getRenderKit(this, renderKitId);
+        }
+        
+        return _cachedRenderKit;
+    }
+    
+    /**
+     * has to be thrown in many of the methods if the method is called after the instance has been released!
+     */
+    protected final void assertNotReleased()
+    {
+        if (_released)
+        {
+            throw new IllegalStateException("Error the FacesContext is already released!");
+        }
+    }
+    
+}

Added: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java?rev=1067544&view=auto
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java (added)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java Sat Feb  5 22:33:47 2011
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.context.servlet;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.context.ExternalContext;
+import javax.servlet.ServletContext;
+
+import org.apache.myfaces.context.ReleaseableExternalContext;
+
+/**
+ * Provides a base implementation of the ExternalContext for Servlet
+ * environments. This impl provides all methods which only rely on the
+ * ServletContext and thus are also provided at startup and shutdown.
+ * 
+ * @author Jakob Korherr (latest modification by $Author: jakobk $)
+ * @version $Revision: 956589 $ $Date: 2010-06-21 08:43:21 -0500 (Lun, 21 Jun 2010) $
+ */
+public abstract class ServletExternalContextImplBase extends ExternalContext
+        implements ReleaseableExternalContext
+{
+    
+    private static final String INIT_PARAMETER_MAP_ATTRIBUTE = InitParameterMap.class.getName();
+    
+    private ServletContext _servletContext;
+    private Map<String, Object> _applicationMap;
+    private Map<String, String> _initParameterMap;
+    
+    public ServletExternalContextImplBase(ServletContext servletContext)
+    {
+        _servletContext = servletContext;
+        _applicationMap = null;
+        _initParameterMap = null;
+    }
+    
+    public void release()
+    {
+        _servletContext = null;
+        _applicationMap = null;
+        _initParameterMap = null;
+    }
+    
+    // ~ Methods which only rely on the ServletContext-------------------------
+    
+    @Override
+    public Map<String, Object> getApplicationMap()
+    {
+        if (_applicationMap == null)
+        {
+            _applicationMap = new ApplicationMap(_servletContext);
+        }
+        return _applicationMap;
+    }
+    
+    @Override
+    public Object getContext()
+    {
+        return _servletContext;
+    }
+    
+    @Override
+    public String getInitParameter(final String s)
+    {
+        return _servletContext.getInitParameter(s);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<String, String> getInitParameterMap()
+    {
+        if (_initParameterMap == null)
+        {
+            // We cache it as an attribute in ServletContext itself (is this circular reference a problem?)
+            if ((_initParameterMap = (Map<String, String>) _servletContext.getAttribute(INIT_PARAMETER_MAP_ATTRIBUTE)) == null)
+            {
+                _initParameterMap = new InitParameterMap(_servletContext);
+                _servletContext.setAttribute(INIT_PARAMETER_MAP_ATTRIBUTE, _initParameterMap);
+            }
+        }
+        return _initParameterMap;
+    }
+    
+    @Override
+    public URL getResource(final String path) throws MalformedURLException
+    {
+        checkNull(path, "path");
+        return _servletContext.getResource(path);
+    }
+
+    @Override
+    public InputStream getResourceAsStream(final String path)
+    {
+        checkNull(path, "path");
+        return _servletContext.getResourceAsStream(path);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Set<String> getResourcePaths(final String path)
+    {
+        checkNull(path, "path");
+        return _servletContext.getResourcePaths(path);
+    }
+
+    @Override
+    public void log(final String message)
+    {
+        checkNull(message, "message");
+        _servletContext.log(message);
+    }
+
+    @Override
+    public void log(final String message, final Throwable exception)
+    {
+        checkNull(message, "message");
+        checkNull(exception, "exception");
+        _servletContext.log(message, exception);
+    }
+    
+    // ~ Methods which verify some required behavior---------------------------
+    
+    protected void checkNull(final Object o, final String param)
+    {
+        if (o == null)
+        {
+            throw new NullPointerException(param + " can not be null.");
+        }
+    }
+    
+}

Added: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java?rev=1067544&view=auto
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java (added)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupFacesContextImpl.java Sat Feb  5 22:33:47 2011
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.context.servlet;
+
+import java.util.Iterator;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.context.ReleaseableExternalContext;
+
+/**
+ * A FacesContext implementation which will be set as the current instance
+ * during container startup and shutdown and which provides a basic set of
+ * FacesContext functionality.
+ * 
+ * @author Jakob Korherr (latest modification by $Author: jakobk $)
+ * @version $Revision: 963629 $ $Date: 2010-07-13 04:29:07 -0500 (Mar, 13 Jul 2010) $
+ */
+public class StartupFacesContextImpl extends FacesContextImplBase
+{
+    
+    public static final String EXCEPTION_TEXT = "This method is not supported during ";
+
+    private boolean _startup;
+    
+    public StartupFacesContextImpl(
+            ExternalContext externalContext, 
+            ReleaseableExternalContext defaultExternalContext,
+            boolean startup)
+    {
+        // setCurrentInstance is called in constructor of super class
+        super(externalContext, defaultExternalContext);
+        
+        _startup = startup;
+    }
+
+    // ~ Methods which are valid by spec to be called during startup and shutdown------
+    
+    // public final UIViewRoot getViewRoot() implemented in super-class
+    // public void release() implemented in super-class
+    // public final ExternalContext getExternalContext() implemented in super-class
+    // public Application getApplication() implemented in super-class
+    // public boolean isProjectStage(ProjectStage stage) implemented in super-class
+    
+    // ~ Methods which can be called during startup and shutdown, but are not
+    //   officially supported by the spec--------------------------------------
+    
+    // all other methods on FacesContextImplBase
+    
+    // ~ Methods which are unsupported during startup and shutdown-------------
+
+    @Override
+    public final FacesMessage.Severity getMaximumSeverity()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+    
+    @Override
+    public final Iterator<FacesMessage> getMessages()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+    
+    
+    @Override
+    public final Iterator<String> getClientIdsWithMessages()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final Iterator<FacesMessage> getMessages(final String clientId)
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final void addMessage(final String clientId, final FacesMessage message)
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final void renderResponse()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final void responseComplete()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final boolean getRenderResponse()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final boolean getResponseComplete()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final void setResponseStream(final ResponseStream responseStream)
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final ResponseStream getResponseStream()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final void setResponseWriter(final ResponseWriter responseWriter)
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public final ResponseWriter getResponseWriter()
+    {
+        assertNotReleased();
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+    
+    // ~ private Methods ------------------------------------------------------
+    
+    /**
+     * Returns startup or shutdown as String according to the field _startup.
+     * @return
+     */
+    private String _getTime()
+    {
+        return _startup ? "startup" : "shutdown";
+    }
+    
+}

Added: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupServletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupServletExternalContextImpl.java?rev=1067544&view=auto
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupServletExternalContextImpl.java (added)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/context/servlet/StartupServletExternalContextImpl.java Sat Feb  5 22:33:47 2011
@@ -0,0 +1,278 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.context.servlet;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+/**
+ * An ExternalContext implementation for Servlet environments, which is used
+ * by StartupFacesContextImpl at container startup and shutdown and which
+ * provides ExternalContext functionality that does not require request and
+ * response objects.
+ * 
+ * @author Jakob Korherr (latest modification by $Author: lu4242 $)
+ * @version $Revision: 957581 $ $Date: 2010-06-24 10:22:24 -0500 (Jue, 24 Jun 2010) $
+ */
+public class StartupServletExternalContextImpl extends ServletExternalContextImplBase
+{
+    public static final String EXCEPTION_TEXT = "This method is not supported during ";
+    
+    private boolean _startup;
+    
+    public StartupServletExternalContextImpl(final ServletContext servletContext,
+            boolean startup)
+    {
+        super(servletContext);
+        _startup = startup;
+    }
+    
+    // ~ Methods which are valid to be called during startup and shutdown------
+    
+    // Note that all methods, which are valid to be called during startup and
+    // shutdown are implemented in ServletExternalContextImplBase, because they 
+    // are exactly the same as in the real ExternalContext implementation.
+    
+    // ~ Methods which are not valid to be called during startup and shutdown, but we implement anyway ------
+    
+    // ~ Methods which are unsupported during startup and shutdown-------------
+
+    @Override
+    public String encodeActionURL(String url)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String encodeNamespace(String name)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String encodeResourceURL(String url)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getAuthType()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRemoteUser()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Object getRequest()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRequestContextPath()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, Object> getRequestCookieMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, String> getRequestHeaderMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, String[]> getRequestHeaderValuesMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Locale getRequestLocale()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Iterator<Locale> getRequestLocales()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, Object> getRequestMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, String> getRequestParameterMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Iterator<String> getRequestParameterNames()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, String[]> getRequestParameterValuesMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRequestPathInfo()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRequestServletPath()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Object getResponse()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Object getSession(boolean create)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Map<String, Object> getSessionMap()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public Principal getUserPrincipal()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public boolean isUserInRole(String role)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRequestCharacterEncoding()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getRequestContentType()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getResponseCharacterEncoding()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public String getResponseContentType()
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public void setRequest(Object request)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public void setRequestCharacterEncoding(String encoding)
+            throws UnsupportedEncodingException
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public void setResponse(Object response)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    @Override
+    public void setResponseCharacterEncoding(String encoding)
+    {
+        throw new UnsupportedOperationException(EXCEPTION_TEXT + _getTime());
+    }
+
+    /**
+     * Cannot dispatch because this is not a page request
+     */
+    @Override
+    public void dispatch(String path) throws IOException
+    {
+        throw new IllegalStateException(EXCEPTION_TEXT + _getTime());
+    }
+    
+    /**
+     * Cannot redirect because this is not a page request
+     */
+    @Override
+    public void redirect(String url) throws IOException
+    {
+        throw new IllegalStateException(EXCEPTION_TEXT + _getTime());
+    }
+    
+    // ~ private Methods ------------------------------------------------------
+    
+    /**
+     * Returns startup or shutdown as String according to the field _startup.
+     * @return
+     */
+    private String _getTime()
+    {
+        return _startup ? "startup" : "shutdown";
+    }
+
+}

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java Sat Feb  5 22:33:47 2011
@@ -19,9 +19,12 @@
 package org.apache.myfaces.webapp;
 
 import java.util.List;
+import java.util.Locale;
 
 import javax.el.ExpressionFactory;
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
 import javax.servlet.ServletContext;
 
 import org.apache.commons.logging.Log;
@@ -31,7 +34,10 @@ import org.apache.myfaces.buildtools.mav
 import org.apache.myfaces.config.FacesConfigValidator;
 import org.apache.myfaces.config.FacesConfigurator;
 import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.context.ReleaseableExternalContext;
 import org.apache.myfaces.context.servlet.ServletExternalContextImpl;
+import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
+import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
 import org.apache.myfaces.shared_impl.util.StateUtils;
 import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
 
@@ -67,8 +73,8 @@ public abstract class AbstractFacesIniti
             // by using an ExternalContext. However, that's no problem as long as no 
             // one tries to call methods depending on either the ServletRequest or 
             // the ServletResponse.
-            ExternalContext externalContext = new ServletExternalContextImpl(
-                    servletContext, null, null);
+            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+                //new ServletExternalContextImpl(servletContext, null, null);
 
             // Parse and validate the web.xml configuration file
             WebXml webXml = WebXml.getWebXml(externalContext);
@@ -132,7 +138,7 @@ public abstract class AbstractFacesIniti
         RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
         runtimeConfig.setExpressionFactory(expressionFactory);
         
-        ApplicationImpl.setInitializingRuntimeConfig(runtimeConfig);
+        //ApplicationImpl.setInitializingRuntimeConfig(runtimeConfig);
         
         // And configure everything
         new FacesConfigurator(externalContext).configure();
@@ -204,7 +210,54 @@ public abstract class AbstractFacesIniti
        
        return null;
     }
-
+    
+    public FacesContext initStartupFacesContext(ServletContext servletContext)
+    {
+        // We cannot use FacesContextFactory, because it is necessary to initialize 
+        // before Application and RenderKit factories, so we should use different object. 
+        return _createFacesContext(servletContext, true);
+    }
+        
+    public void destroyStartupFacesContext(FacesContext facesContext)
+    {
+        _releaseFacesContext(facesContext);
+    }
+    
+    public FacesContext initShutdownFacesContext(ServletContext servletContext)
+    {
+        return _createFacesContext(servletContext, false);
+    }
+        
+    public void destroyShutdownFacesContext(FacesContext facesContext)
+    {
+        _releaseFacesContext(facesContext);
+    }
+    
+    private FacesContext _createFacesContext(ServletContext servletContext, boolean startup)
+    {
+        ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, startup);
+        FacesContext facesContext = new StartupFacesContextImpl(externalContext, 
+                (ReleaseableExternalContext) externalContext, startup);
+        
+        // If getViewRoot() is called during application startup or shutdown, 
+        // it should return a new UIViewRoot with its locale set to Locale.getDefault().
+        UIViewRoot startupViewRoot = new UIViewRoot();
+        startupViewRoot.setLocale(Locale.getDefault());
+        facesContext.setViewRoot(startupViewRoot);
+        
+        return facesContext;
+    }
+    
+    private void _releaseFacesContext(FacesContext facesContext)
+    {        
+        // make sure that the facesContext gets released.
+        // This is important in an OSGi environment 
+        if (facesContext != null)
+        {
+            facesContext.release();
+        }        
+    }
+    
     /**
      * Performs initialization tasks depending on the current environment.
      * 

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializer.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializer.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializer.java Sat Feb  5 22:33:47 2011
@@ -18,6 +18,7 @@
  */
 package org.apache.myfaces.webapp;
 
+import javax.faces.context.FacesContext;
 import javax.servlet.ServletContext;
 
 /**
@@ -29,4 +30,28 @@ public interface FacesInitializer
     void initFaces(ServletContext servletContext);
     
     void destroyFaces(ServletContext servletContext);
+
+    /**
+     * @since 1.2.10
+     * @param servletContext
+     */
+    FacesContext initStartupFacesContext(ServletContext servletContext);
+    
+    /**
+     * @since 1.2.10
+     * @param facesContext
+     */
+    void destroyStartupFacesContext(FacesContext facesContext);
+        
+    /**
+     * @since 1.2.10
+     * @param servletContext
+     */
+    FacesContext initShutdownFacesContext(ServletContext servletContext);    
+
+    /**
+     * @since 1.2.10
+     * @param facesContext
+     */
+    void destroyShutdownFacesContext(FacesContext facesContext);
 }

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/MyFacesServlet.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/MyFacesServlet.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/MyFacesServlet.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/MyFacesServlet.java Sat Feb  5 22:33:47 2011
@@ -18,15 +18,22 @@
  */
 package org.apache.myfaces.webapp;
 
+import java.io.IOException;
+
+import javax.faces.context.FacesContext;
+import javax.faces.webapp.FacesServlet;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.shared_impl.webapp.webxml.DelegatedFacesServlet;
 import org.apache.myfaces.util.ContainerUtils;
 
-import javax.faces.webapp.FacesServlet;
-import javax.servlet.*;
-import java.io.IOException;
-
 /**
  * Derived FacesServlet that can be used for debugging purpose
  * and to fix the Weblogic startup issue (FacesServlet is initialized before ServletContextListener).
@@ -84,17 +91,29 @@ public class MyFacesServlet implements S
     {
         //Check, if ServletContextListener already called
         ServletContext servletContext = servletConfig.getServletContext();
+        
+        FacesInitializer facesInitializer = getFacesInitializer();
+        
+        // Create startup FacesContext before initializing
+        FacesContext facesContext = facesInitializer.initStartupFacesContext(servletContext);
+
         Boolean b = (Boolean)servletContext.getAttribute(StartupServletContextListener.FACES_INIT_DONE);
         if (b == null || b.booleanValue() == false)
         {
             if(log.isWarnEnabled())
+            {
                 log.warn("ServletContextListener not yet called");
-            getFacesInitializer().initFaces(servletConfig.getServletContext());
+            }
+            facesInitializer.initFaces(servletConfig.getServletContext());
         }
+        
+        // Destroy startup FacesContext
+        facesInitializer.destroyStartupFacesContext(facesContext);
+        
         delegate.init(servletConfig);
         log.info("MyFacesServlet for context '" + servletConfig.getServletContext().getRealPath("/") + "' initialized.");
     }
-
+    
     public void service(ServletRequest request, ServletResponse response)
             throws IOException,
                    ServletException

Modified: myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java?rev=1067544&r1=1067543&r2=1067544&view=diff
==============================================================================
--- myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java (original)
+++ myfaces/core/branches/1.2.x/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java Sat Feb  5 22:33:47 2011
@@ -20,17 +20,19 @@ package org.apache.myfaces.webapp;
 
 import java.util.Enumeration;
 
+import javax.faces.FactoryFinder;
+import javax.faces.context.FacesContext;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
 import org.apache.commons.discovery.tools.DiscoverSingleton;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.config.ManagedBeanBuilder;
-import org.apache.myfaces.util.ContainerUtils;
+import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
 import org.apache.myfaces.shared_impl.util.ClassUtils;
-
-import javax.faces.FactoryFinder;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
+import org.apache.myfaces.util.ContainerUtils;
 
 /**
  * Initialise the MyFaces system.
@@ -66,69 +68,7 @@ public class StartupServletContextListen
 
     private FacesInitializer _facesInitializer;
     private ServletContext _servletContext;
-
-
-    /**
-     * the central initialisation event dispatcher which calls
-     * our listeners
-     * @param event
-     * @param operation
-     */
-    private void dispatchInitializationEvent(ServletContextEvent event, int operation) {
-        String [] pluginEntries = (String []) _servletContext.getAttribute(FACES_INIT_PLUGINS);
-
-        if(pluginEntries == null) {
-            String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
-            log.info("Checking for plugins:"+FACES_INIT_PLUGINS);
-            if(plugins == null) return;
-            log.info("Plugins found");
-            pluginEntries = plugins.split(",");
-            _servletContext.setAttribute(FACES_INIT_PLUGINS, pluginEntries);
-        }
-
-        //now we process the plugins
-        for(String plugin: pluginEntries) {
-            log.info("Processing plugin:"+plugin);
-            try {
-                //for now the initializers have to be stateless to
-                //so that we do not have to enforce that the initializer
-                //must be serializable
-                Class pluginClass = ClassUtils.getContextClassLoader().loadClass(plugin);
-                if (pluginClass == null)
-                {
-                    pluginClass = this.getClass().getClassLoader().loadClass(plugin);
-                }
-                StartupListener initializer = (StartupListener) pluginClass.newInstance();
-                
-                switch(operation) {
-                    case FACES_INIT_PHASE_PREINIT:
-                        initializer.preInit(event);
-                        break;
-                    case FACES_INIT_PHASE_POSTINIT:
-                        initializer.postInit(event);
-                        break;
-                    case FACES_INIT_PHASE_PREDESTROY:
-                        initializer.preDestroy(event);
-                        break;
-                    default:
-                        initializer.postDestroy(event);
-                        break;
-                }
-
-               
-            } catch (ClassNotFoundException e) {
-                log.error(e);
-            } catch (IllegalAccessException e) {
-                log.error(e);
-            } catch (InstantiationException e) {
-                log.error(e);
-            }
-
-        }
-        log.info("Processing plugins done");
-    }
-
-
+    
     public void contextInitialized(ServletContextEvent event)
     {
         if (_servletContext != null)
@@ -136,14 +76,22 @@ public class StartupServletContextListen
             throw new IllegalStateException("context is already initialized");
         }
         _servletContext = event.getServletContext();
+        
         Boolean b = (Boolean) _servletContext.getAttribute(FACES_INIT_DONE);
-
         if (b == null || b.booleanValue() == false)
         {
+            FacesInitializer facesInitializer = getFacesInitializer();
+
+            // Create startup FacesContext before initializing
+            FacesContext facesContext = facesInitializer.initStartupFacesContext(_servletContext);
+
             dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
-            getFacesInitializer().initFaces(_servletContext);
+            facesInitializer.initFaces(_servletContext);
             dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTINIT);
             _servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
+
+            //Destroy startup FacesContext
+            facesInitializer.destroyStartupFacesContext(facesContext);
         }
         else
         {
@@ -151,6 +99,36 @@ public class StartupServletContextListen
         }
     }
 
+
+    public void contextDestroyed(ServletContextEvent event)
+    {
+        if (_facesInitializer != null && _servletContext != null)
+        {
+            // Create startup FacesContext before start undeploy
+            FacesContext facesContext = _facesInitializer.initShutdownFacesContext(_servletContext);
+            
+            doPredestroy(event);
+            
+            _facesInitializer.destroyFaces(_servletContext);
+            
+            LifecycleProviderFactory.getLifecycleProviderFactory().release();
+
+            // Destroy startup FacesContext, but note we do before publish postdestroy event on
+            // plugins and before release factories.
+            if (facesContext != null)
+            {
+                _facesInitializer.destroyShutdownFacesContext(facesContext);
+            }
+            
+            FactoryFinder.releaseFactories();
+
+            DiscoverSingleton.release(); //clears EnvironmentCache and prevents leaking classloader references
+            dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
+        }
+        
+        _servletContext = null;
+    }
+
     protected FacesInitializer getFacesInitializer()
     {
         if (_facesInitializer == null)
@@ -185,21 +163,6 @@ public class StartupServletContextListen
             facesInitializer.initFaces(_servletContext);
         }
     }
-
-    public void contextDestroyed(ServletContextEvent event)
-    {
-        doPredestroy(event);
-        
-        if (_facesInitializer != null && _servletContext != null)
-        {
-            _facesInitializer.destroyFaces(_servletContext);
-        }
-        FactoryFinder.releaseFactories();
-        DiscoverSingleton.release(); //clears EnvironmentCache and prevents leaking classloader references
-        dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
-
-        _servletContext = null;
-    }
     
     private void doPredestroy(ServletContextEvent event) {
                 
@@ -215,4 +178,65 @@ public class StartupServletContextListen
                doPreDestroy(value, name, ManagedBeanBuilder.APPLICATION);
            }
     }
+
+    /**
+     * the central initialisation event dispatcher which calls
+     * our listeners
+     * @param event
+     * @param operation
+     */
+    private void dispatchInitializationEvent(ServletContextEvent event, int operation) {
+        String [] pluginEntries = (String []) _servletContext.getAttribute(FACES_INIT_PLUGINS);
+
+        if(pluginEntries == null) {
+            String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
+            log.info("Checking for plugins:"+FACES_INIT_PLUGINS);
+            if(plugins == null) return;
+            log.info("Plugins found");
+            pluginEntries = plugins.split(",");
+            _servletContext.setAttribute(FACES_INIT_PLUGINS, pluginEntries);
+        }
+
+        //now we process the plugins
+        for(String plugin: pluginEntries) {
+            log.info("Processing plugin:"+plugin);
+            try {
+                //for now the initializers have to be stateless to
+                //so that we do not have to enforce that the initializer
+                //must be serializable
+                Class pluginClass = ClassUtils.getContextClassLoader().loadClass(plugin);
+                if (pluginClass == null)
+                {
+                    pluginClass = this.getClass().getClassLoader().loadClass(plugin);
+                }
+                StartupListener initializer = (StartupListener) pluginClass.newInstance();
+                
+                switch(operation) {
+                    case FACES_INIT_PHASE_PREINIT:
+                        initializer.preInit(event);
+                        break;
+                    case FACES_INIT_PHASE_POSTINIT:
+                        initializer.postInit(event);
+                        break;
+                    case FACES_INIT_PHASE_PREDESTROY:
+                        initializer.preDestroy(event);
+                        break;
+                    default:
+                        initializer.postDestroy(event);
+                        break;
+                }
+
+               
+            } catch (ClassNotFoundException e) {
+                log.error(e);
+            } catch (IllegalAccessException e) {
+                log.error(e);
+            } catch (InstantiationException e) {
+                log.error(e);
+            }
+
+        }
+        log.info("Processing plugins done");
+    }
+
 }