According to the official Java EE Javadoc (cf. https://docs.oracle.com/javaee/7/api/javax/servlet/AsyncListener.html#onStartAsync%28javax.servlet.AsyncEvent%29), AsyncListeners should be allowed to re-register themselves when the event "onStartAsync" is started : "This AsyncListener will not receive any events related to the new asynchronous cycle unless it registers itself (via a call to AsyncContext.addListener(javax.servlet.AsyncListener)) with the AsyncContext that is delivered as part of the given AsyncEvent.". In tomcat 7.0.x, the actual implementation prevents this behavior since the listeners list is cleared *after* firing the event (cf. AdyncContextImpl.java:366). If the list was cleared before firing the event, listeners would be able to re-register themselves if needed.
Thanks for the report. This has been fixed in trunk, 8.0.x (for 8.0.16 onwards) and 7.0.x (for 7.0.58 onwards).