Created attachment 30604 [details] source code to reproduce the issue If using jsf 2 project and add Phase Listeners there, they are created and added to the list of Phase Listeners twice which means on page load same Phase Listeners are executed twice. This is happening only when com.sun.faces.config.ConfigureListener is defined in web.xml. Without such declaration in web.xml jsf is initialized one time. Such behaviour seems to happen on 7.0.42 version. I was using 7.0.41 and didn't see such behaviour. I didn't have a chance to check it again on 7.0.41 but checked on 7.0.6(because had it installed) and there everything was fine. Such behaviour can be very critical for applications using jsf and Phase Listeners. And Maybe not only Phase Listeners are duplicated(didn't look), because the problem here is that jsf is initialized twice and other things can get duplicated too. Attaching eclipse project where you can check the bug on 7.0.42 and compare to other tomcat version. In 7.0.42 there is duplicated message in console that Phase Listener is created.
A ServletContainerInitializer is defined which is processed by Tomcat as required by the Servlet 3.0 and later Servlet specifications. It appears that the SCI adds an instance of com.sun.faces.config.ConfigureListener so when it is defined a second time in web.xml everything gets processed twice. Either disable the SCI or removed the listener definition from web.xml.
Yes, changing the web.xml will fix the problem. But also if the servlet version 2.5 is defined in web.xml everything still get's initialized twice. I believe this is not what supposed to be. Not back compatibility for application that worked fine on older versions of tomcat.
The Servlet 3.0 EG made very clear that annotations must be processed regardless of any version declared in web.xml. Personally, I think that is the wrong decision but is pre-dates my involvement with the EG.
com.sun.faces.config.ConfigureListener is not marked with any annotations but is loaded twice if it is defined as <listener> in web.xml. Not really clear how servlet 3 spec defines this. Maybe post a link in spec to clarify this for me? From my opinion this issue means that any of the old applications that were created before tomcat 7 released will work incorrectly on 7.0.42 or just not work at all.
Sorry, I should have re-read this a little more carefully before commenting. However, the bug is still INVALID. A Servlet 3.0 container is required to scan for SCIs irrespective of any version declared in the web.xml. The docs for the library you are using should make clear that the web.xml definition is not required when running on a Servlet 3.0 or later container unless SCI scanning is disabled (e.g. via an absolute ordering) for the JAR that provides the SCI.
I have encountered the same problem when used a workoaround solution for a SEAM project (https://issues.jboss.org/browse/JBSEAM-4401). I need the ConfigureListener to be invoked before the SeamListener. During debugging I found that the com.sun.faces.config.ConfigureListener is added twice in org.apache.catalina.core.StandardContext. The first instance is added because it is described in the web.xml. The second instance is added by a JarScanner because the listener is described in jsf-impl.jar/META-INF/jsf_core.tld. My jsf-impl has an Implementation-Version: 2.1.7-SNAPSHOT. I have no idea how to avoid the situation yet.
For now I applied the following workaround. I have added the jsf-impl.jar to the property "tomcat.util.scan.DefaultJarScanner.jarsToSkip" of the TOMCAT\conf\catalina.properties. As a result my application started running properly. But I still have to check that it won't fail in some situations.
I have found the reason for adding com.sun.faces.config.ConfigureListener a second time: Tomcat 7.0.41 contained following method in class org.apache.catalina.core.StandardContext: public void addApplicationListener(String listener) This method checks that the same listener isn't added twice: ... for (int i = 0; i < applicationListeners.length; i++) { if (listener.equals(applicationListeners[i])) { log.info(sm.getString("standardContext.duplicateListener",listener)); return; } ... In Tomcat 7.0.42 the type of instance variable applicationListeners was changed from String[] to ApplicationListener[] and the method signature was changed to public void addApplicationListener(ApplicationListener listener) But the check "listener.equals(applicationListeners[i])" in the fow loop wasn't adjusted --> now it doesn't compares the fq class names of the listeners but calls Object.equals() because class ApplicationListener doesn't overwrite equals() method. The solution would be to overwrite equals() and hashCode() method in org.apache.catalina.deploy.ApplicationListener. I have checked current Tomcat version 8.0.8 and the issue is still present there. I would help much to fix it in Tomcat 7 and 8 releases. (In reply to Oleksii from comment #6) > I have encountered the same problem when used a workoaround solution for a > SEAM project (https://issues.jboss.org/browse/JBSEAM-4401). I need the > ConfigureListener to be invoked before the SeamListener. > > During debugging I found that the com.sun.faces.config.ConfigureListener is > added twice in org.apache.catalina.core.StandardContext. > > The first instance is added because it is described in the web.xml. > > The second instance is added by a JarScanner because the listener is > described in jsf-impl.jar/META-INF/jsf_core.tld. My jsf-impl has an > Implementation-Version: 2.1.7-SNAPSHOT. > > I have no idea how to avoid the situation yet.
Thanks for the investigation. This has been fixed in trunk for 8.0.9 and in 7.0.x for 7.0.55 onwards.
(In reply to Volker from comment #8) I also fixed the error message that was displayed (r1600616 7.0.55). The addApplicationListener(ApplicationListener) API was reviewed and reverted in Tomcat 8 - issue 56588.