This issue is REALLY weird. I spent a lot of time investigating this Exception and now (I think), I finally found it.
The problem comes from the following method of Application.java
public void subscribeToEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener)
Application application = getMyfacesApplicationInstance();
if (application != null)
subscribeToEvent(systemEventClass, null, listener);
It tries to get the actual MyFacesApplicationInstance (ApplicationImpl) from the ApplicationMap. This method returns null, if either FacesContext is null, ExternalContext is null or ApplicationFactoryImpl did not put it in the ApplicationMap yet.
If the call to getMyfacesApplicationInstance() returns NULL (!!!), everything functions properly and we can never get an infinite loop. Otherwise it calls subscribeToEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListener listener) on ApplicationImpl, which is not overrided and thus it calls itself again and again.
Normally this functions properly, because at startup FacesContext and ExternalContext are null. I don't really know how, but if you (or the Tomcat) managed to initialise the FacesContext and the ExternalContext before subscribeToEvent is invoked, we ran into the infinte loop.
The solution is, of course, really easy, but it was a long way to get there....