You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by pa...@apache.org on 2022/08/30 13:23:44 UTC
[myfaces] branch main updated: MYFACES-4442: avoid UnsupportedOperationException
This is an automated email from the ASF dual-hosted git repository.
paulnicolucci pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/main by this push:
new e0a2812bd MYFACES-4442: avoid UnsupportedOperationException
new fcaf6d46a Merge pull request #292 from pnicolucci/MYFACES-4442
e0a2812bd is described below
commit e0a2812bde32c8994b136f067236cb6d0c9ae608
Author: Paul Nicolucci <pn...@gmail.com>
AuthorDate: Mon Aug 29 10:47:47 2022 -0400
MYFACES-4442: avoid UnsupportedOperationException
---
.../myfaces/webapp/FacesInitializerImpl.java | 77 ++++++++----------
.../webapp/MyFacesContainerInitializer.java | 92 ++++++++++++++--------
2 files changed, 91 insertions(+), 78 deletions(-)
diff --git a/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializerImpl.java b/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializerImpl.java
index 3752d2b34..db5a91f94 100644
--- a/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializerImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/webapp/FacesInitializerImpl.java
@@ -85,19 +85,19 @@ public class FacesInitializerImpl implements FacesInitializer
private static final Logger log = Logger.getLogger(FacesInitializerImpl.class.getName());
public static final String CDI_BEAN_MANAGER_INSTANCE = "oam.cdi.BEAN_MANAGER_INSTANCE";
-
+
private static final String CDI_SERVLET_CONTEXT_BEAN_MANAGER_ATTRIBUTE =
"jakarta.enterprise.inject.spi.BeanManager";
public static final String INJECTED_BEAN_STORAGE_KEY = "org.apache.myfaces.spi.BEAN_ENTRY_STORAGE";
public static final String INITIALIZED = "org.apache.myfaces.INITIALIZED";
-
+
private static final byte FACES_INIT_PHASE_PREINIT = 0;
private static final byte FACES_INIT_PHASE_POSTINIT = 1;
private static final byte FACES_INIT_PHASE_PREDESTROY = 2;
private static final byte FACES_INIT_PHASE_POSTDESTROY = 3;
-
+
/**
* Performs all necessary initialization tasks like configuring this Faces
* application.
@@ -115,14 +115,14 @@ public class FacesInitializerImpl implements FacesInitializer
}
return;
}
-
+
try
{
if (log.isLoggable(Level.FINEST))
{
log.finest("Initializing MyFaces");
}
-
+
long start = System.currentTimeMillis();
// Some parts of the following configuration tasks have been implemented
@@ -144,43 +144,34 @@ public class FacesInitializerImpl implements FacesInitializer
{
spf.initKnownServiceProviderMapInfo(externalContext, spfConfig);
}
-
- // Parse and validate the web.xml configuration file
-
+
if (!WebConfigParamUtils.getBooleanInitParameter(externalContext,
MyfacesConfig.INITIALIZE_ALWAYS_STANDALONE, false))
{
- FacesServletMappingUtils.ServletRegistrationInfo facesServletRegistration =
- FacesServletMappingUtils.getFacesServletRegistration(facesContext, servletContext);
- if (facesServletRegistration == null
- || facesServletRegistration.getMappings() == null
- || facesServletRegistration.getMappings().length == 0)
+ // check to see if the FacesServlet was found by MyFacesContainerInitializer
+ Boolean mappingAdded = (Boolean) servletContext.getAttribute(
+ MyFacesContainerInitializer.FACES_SERVLET_FOUND);
+
+ if (mappingAdded == null || !mappingAdded)
{
- // check to see if the FacesServlet was found by MyFacesContainerInitializer
- Boolean mappingAdded = (Boolean) servletContext.getAttribute(
- MyFacesContainerInitializer.FACES_SERVLET_FOUND);
+ // check if the FacesServlet has been added dynamically
+ // in a Servlet 3.0 environment by MyFacesContainerInitializer
+ mappingAdded = (Boolean) servletContext.getAttribute(
+ MyFacesContainerInitializer.FACES_SERVLET_ADDED_ATTRIBUTE);
if (mappingAdded == null || !mappingAdded)
{
- // check if the FacesServlet has been added dynamically
- // in a Servlet 3.0 environment by MyFacesContainerInitializer
- mappingAdded = (Boolean) servletContext.getAttribute(
- MyFacesContainerInitializer.FACES_SERVLET_ADDED_ATTRIBUTE);
-
- if (mappingAdded == null || !mappingAdded)
+ if (log.isLoggable(Level.WARNING))
{
- if (log.isLoggable(Level.WARNING))
- {
- log.warning("No mappings of FacesServlet found. Abort initializing MyFaces.");
- }
- return;
+ log.warning("No mappings of FacesServlet found. Abort initializing MyFaces.");
}
+ return;
}
}
}
-
+
initCDIIntegration(servletContext, externalContext);
-
+
initContainerIntegration(servletContext, externalContext);
// log environment integrations
@@ -205,10 +196,10 @@ public class FacesInitializerImpl implements FacesInitializer
initWebsocketIntegration(servletContext, externalContext);
WebConfigParamsLogger.logWebContextParams(facesContext);
-
+
//Start ViewPoolProcessor if necessary
ViewPoolProcessor.initialize(facesContext);
-
+
MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
if (config.isAutomaticExtensionlessMapping())
{
@@ -222,7 +213,7 @@ public class FacesInitializerImpl implements FacesInitializer
facesContext.getExternalContext().getApplicationMap().put(
MyfacesConfig.RESOURCE_BUNDLE_CONTROL, resourceBundleControl);
}
-
+
// print out a very prominent log message if the project stage is != Production
if (!facesContext.isProjectStage(ProjectStage.Production)
&& !facesContext.isProjectStage(ProjectStage.UnitTest))
@@ -476,33 +467,33 @@ public class FacesInitializerImpl implements FacesInitializer
// before Application and RenderKit factories, so we should use different object.
return _createFacesContext(servletContext, true);
}
-
+
@Override
public void destroyStartupFacesContext(FacesContext facesContext)
{
_releaseFacesContext(facesContext);
}
-
+
@Override
public FacesContext initShutdownFacesContext(ServletContext servletContext)
{
return _createFacesContext(servletContext, false);
}
-
- @Override
+
+ @Override
public void destroyShutdownFacesContext(FacesContext facesContext)
{
_releaseFacesContext(facesContext);
}
-
+
private FacesContext _createFacesContext(ServletContext servletContext, boolean startup)
{
ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, startup);
ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
- FacesContext facesContext = new StartupFacesContextImpl(externalContext,
+ FacesContext facesContext = new StartupFacesContextImpl(externalContext,
externalContext, exceptionHandler, startup);
-
- // If getViewRoot() is called during application startup or shutdown,
+
+ // 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());
@@ -510,7 +501,7 @@ public class FacesInitializerImpl implements FacesInitializer
return facesContext;
}
-
+
private void _releaseFacesContext(FacesContext facesContext)
{
// make sure that the facesContext gets released.
@@ -518,7 +509,7 @@ public class FacesInitializerImpl implements FacesInitializer
if (facesContext != null)
{
facesContext.release();
- }
+ }
}
/**
@@ -819,7 +810,7 @@ public class FacesInitializerImpl implements FacesInitializer
* @return false if there are not plugins defined via ServiceLoader.
*/
private boolean loadFacesInitPluginsViaServiceLoader(ServletContext servletContext)
- {
+ {
ServiceLoader<StartupListener> loader = ServiceLoader.load(StartupListener.class,
ClassUtils.getContextClassLoader());
diff --git a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesContainerInitializer.java b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesContainerInitializer.java
index 5bbc8978a..6c919d215 100644
--- a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesContainerInitializer.java
+++ b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesContainerInitializer.java
@@ -60,7 +60,7 @@ import org.apache.myfaces.util.lang.ClassUtils;
/**
* This class is called by any Java EE 6 complaint container at startup.
- * It checks if the current webapp is a Faces-webapp by checking if some of
+ * It checks if the current webapp is a Faces-webapp by checking if some of
* the Faces related annotations are specified in the webapp classpath or if
* the faces-config.xml file is present. If so, the listener checks if
* the FacesServlet has already been defined in web.xml and if not, it adds
@@ -132,6 +132,9 @@ public class MyFacesContainerInitializer implements ServletContainerInitializer
return;
}
+ // Check for a FacesServlet and store the result so it can be used by the FacesInitializer.
+ boolean isFacesServletPresent = checkForFacesServlet(servletContext);
+
// Check for one or more of this conditions:
// 1. A faces-config.xml file is found in WEB-INF
// 2. A faces-config.xml file is found in the META-INF directory of a jar in the application's classpath.
@@ -142,45 +145,42 @@ public class MyFacesContainerInitializer implements ServletContainerInitializer
// implementation is not empty.
if ((clazzes != null && !clazzes.isEmpty()) || isFacesConfigPresent(servletContext))
{
- // look for the FacesServlet
- Map<String, ? extends ServletRegistration> servlets = servletContext.getServletRegistrations();
- for (Map.Entry<String, ? extends ServletRegistration> servletEntry : servlets.entrySet())
+ /*
+ * If we get into this code block the application contains some Faces artifacts, either a faces-config.xml
+ * or one ore more classes from @HandlesTypes. However if classes from @HandlesTypes or a faces-config.xml
+ * is available a FacesServlet definition might not be defined.
+ *
+ * If a FacesServet definition was not found then add it dynamically.
+ */
+ if(!isFacesServletPresent)
{
- String className = servletEntry.getValue().getClassName();
- if (FACES_SERVLET_CLASS.getName().equals(className) || isDelegatedFacesServlet(className))
+ // the FacesServlet is not installed yet - install it
+ ServletRegistration.Dynamic servlet =
+ servletContext.addServlet(FACES_SERVLET_NAME, FACES_SERVLET_CLASS);
+
+ //try to add typical Faces mappings
+ String[] mappings = isAutomaticXhtmlMappingDisabled(servletContext) ?
+ FACES_SERVLET_MAPPINGS : FACES_SERVLET_FULL_MAPPINGS;
+ Set<String> conflictMappings = servlet.addMapping(mappings);
+ if (conflictMappings != null && !conflictMappings.isEmpty())
{
- // we found a FacesServlet; set an attribute for use during initialization
- servletContext.setAttribute(FACES_SERVLET_FOUND, Boolean.TRUE);
- return;
+ //at least one of the attempted mappings is in use, remove and try again
+ Set<String> newMappings = new HashSet<>(Arrays.asList(mappings));
+ newMappings.removeAll(conflictMappings);
+ mappings = newMappings.toArray(new String[newMappings.size()]);
+ servlet.addMapping(mappings);
}
- }
-
- // the FacesServlet is not installed yet - install it
- ServletRegistration.Dynamic servlet = servletContext.addServlet(FACES_SERVLET_NAME, FACES_SERVLET_CLASS);
-
- //try to add typical Faces mappings
- String[] mappings = isAutomaticXhtmlMappingDisabled(servletContext) ?
- FACES_SERVLET_MAPPINGS : FACES_SERVLET_FULL_MAPPINGS;
- Set<String> conflictMappings = servlet.addMapping(mappings);
- if (conflictMappings != null && !conflictMappings.isEmpty())
- {
- //at least one of the attempted mappings is in use, remove and try again
- Set<String> newMappings = new HashSet<>(Arrays.asList(mappings));
- newMappings.removeAll(conflictMappings);
- mappings = newMappings.toArray(new String[newMappings.size()]);
- servlet.addMapping(mappings);
- }
- if (mappings != null && mappings.length > 0)
- {
- // at least one mapping was added
- // now we have to set a field in the ServletContext to indicate that we have
- // added the mapping dynamically, because MyFaces just parsed the web.xml to
- // find mappings and thus it would abort initializing
- servletContext.setAttribute(FACES_SERVLET_ADDED_ATTRIBUTE, Boolean.TRUE);
+ if (mappings != null && mappings.length > 0)
+ {
+ // at least one mapping was added
+ // now we have to set a field in the ServletContext to indicate that we have
+ // added the mapping dynamically.
+ servletContext.setAttribute(FACES_SERVLET_ADDED_ATTRIBUTE, Boolean.TRUE);
- // add a log message
- log.log(Level.INFO, "Added FacesServlet with mappings=" + Arrays.toString(mappings));
+ // add a log message
+ log.log(Level.INFO, "Added FacesServlet with mappings=" + Arrays.toString(mappings));
+ }
}
}
}
@@ -304,6 +304,28 @@ public class MyFacesContainerInitializer implements ServletContainerInitializer
}
}
+ /*
+ * Checks if a FacesServlet has been mapped.
+ */
+ private boolean checkForFacesServlet(ServletContext servletContext)
+ {
+ // look for the FacesServlet
+ Map<String, ? extends ServletRegistration> servlets = servletContext.getServletRegistrations();
+ boolean isFacesServletPresent = false;
+
+ for (Map.Entry<String, ? extends ServletRegistration> servletEntry : servlets.entrySet())
+ {
+ String className = servletEntry.getValue().getClassName();
+ if (FACES_SERVLET_CLASS.getName().equals(className) || isDelegatedFacesServlet(className))
+ {
+ // we found a FacesServlet; set an attribute for use during initialization
+ servletContext.setAttribute(FACES_SERVLET_FOUND, Boolean.TRUE);
+ isFacesServletPresent = true;
+ }
+ }
+ return isFacesServletPresent;
+ }
+
/**
* Checks if the class represented by className implements DelegatedFacesServlet.
* @param className