Currently MyFaces stops initializing when there is no (My)FacesServlet
configured in the (present) web.xml.

I am sure this is in 99.99% of all cases right. However there is a
chance that a "wrapping" framework will
instantiate the (My)FacesServlet, inside a wrapping Servlet.

An example of that is the WebSocket/Comet Framework Atmosphere.
As mentioned in [1] a typical configuration looks like:

 <servlet>
    <description>MeteorServlet</description>
    <servlet-name>MeteorServlet</servlet-name>
    <servlet-class>org.atmosphere.cpr.MeteorServlet</servlet-class>
    <init-param>
      <param-name>org.atmosphere.servlet</param-name>
      <param-value>javax.faces.webapp.FacesServlet</param-value>
    </init-param>
    <init-param>
      <param-name>org.atmosphere.useWebSocket</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>org.atmosphere.useNative</param-name>
      <param-value>true</param-value>
    </init-param>
  </servlet>


So in order to enable the AbstractFacesInitializer.java to see that it
can continue the initialization work, I thought about adding the
following to shared WebXml.java:

Index: src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java
===================================================================
--- src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java   
(revision
1028633)
+++ src/main/java/org/apache/myfaces/shared/webapp/webxml/WebXml.java   (working
copy)
@@ -107,6 +107,11 @@
     public abstract boolean isErrorPagePresent();

     /**
+     * Determines, if the web.xml contains the Atmosphere Meteor Servlet
+     */
+    public abstract boolean isAtmosphereMeteorServletPresent();
+
+    /**
      * Returns true if the given servlet class is a valid FacesServlet.
      * This is the FacesServlet itself or any DelegatedFacesServlet.
      *


The AbstractFacesInitializer would be changed to something like:



Index: 
impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
===================================================================
--- impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java  
(revision
1028633)
+++ impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java  
(working
copy)
@@ -79,6 +79,7 @@
      * application.
      */
     public void initFaces(ServletContext servletContext) {
+
         try {
             if (log.isLoggable(Level.FINEST)) {
                 log.finest("Initializing MyFaces");
@@ -102,7 +103,9 @@
                 }

                 return;
-            } else if (webXml.getFacesServletMappings().isEmpty()) {
+            } else if (webXml.getFacesServletMappings().isEmpty() &&
!webXml.isAtmosphereMeteorServletPresent()) {
+                // IF the
+
                 // check if the FacesServlet has been added dynamically
                 // in a Servlet 3.0 environment by MyFacesContainerInitializer
                 Boolean mappingAdded = (Boolean)
servletContext.getAttribute(FACES_SERVLET_ADDED_ATTRIBUTE);


What do you think?

Note....of course - today we have Atmoshpere, tomorrow we may have
different use cases to see if a different Servlet (and/or Filter) is
present.
Hence we could have something like instead:
<WebXml_API>
public abstract boolean containsServlet(String fullQualifiedClassName);
</WebXml_API>

(we want String here, since (with Atmosphere) we can't compile against
it (->(L)GPL))... but we can use the String-based name
as a constant in our code....)

Oh yes... a similar change would be needed for the
MyFacesContainerInitializer.java from our implee6 module.

-Matthias

[1] https://issues.apache.org/jira/browse/MYFACES-2952

-- 
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

Reply via email to