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");
+ }
+
}