Dear Servlet experts,
the behavior of *javax.servlet.ServletRequestListener* seems to be 
underspecified in Servlet 3.1 especially in case of asynchronous 
requests. I am seeking clarification for the case that follows.
There two properties of ServletRequestListener invocation that a Servlet 
implementation may want to have:
1) requestInitialized()/requestDestroyed() are only called once per request
This one simply says that the pair of 
requestInitialized()/requestDestroyed() methods of a given listener is 
not called more than once per a given request.
2) Symmetry with respect to the calling thread
This property says that if the 
ServletRequestListener.requestInitialized() is called by a given thread 
(T1) then the corresponding ServletRequestListener.requestDestroyed() 
invocation is performed by the same thread (T1). This second property is 
very important for integration with various other 
frameworks/technologies as it allows them to set a ThreadLocal in 
requestInitialized() and remove it in requestDestroyed()
Both these properties are achievable at the same time for synchronous 
Servlets. However, for asynchronous Servlets these properties are 
mutually exclusive. Most Servlet containers deal with this by 
sacrificing property (1) and only guarantee (2).
An example follows. Suppose we have a simple asynchronous servlet that:
A1) Does initial processing of the request
A2) Goes async (req.startAsync())
A3) Spawns a new thread T that calculates something
A4) The servlet exits
B1) The spawn thread T calculates the value
B2) Once the thread T finishes calculation, it dispatches back to 
Servlet container for rendering (e.g. 
ctx.dispatch("/asyncFinish?value=calculatedValue"))
C1) Servlet container creates response and completes the request
A1-A4 steps are performed by thread A that initially handles the 
request. B1 and B2 steps are performed by thread B spawned by a Servlet, 
C1 step is performed again by a Servlet container thread.
Now the question arises: When and how should ServletRequestListener 
callbacks be invoked?
Servlet containers that guarantee second of aforementioned properties, 
symmetry of the calling thread, do the following:
Thread A calls ServletRequestListener.requestInitialized()
A1, A2, A3 and A4 are performed
Thread A calls ServletRequestListener.requestDestroyed()
When the value is calculated by thread B and the request is dispatched 
to the Servlet container again:
Thread C calls ServletRequestListener.requestInitialized()
C1 is performed
Thread C calls ServletRequestListener.requestDestroyed()
Implementation such as this one:
sacrifices property (1) - the pair of ServletRequestListener methods is 
called more than once for a given request - each time request is being 
worked on by Servlet container
guarantees property (2) - symmetry of the calling thread - allows 
frameworks that depend on ThreadLocal to use ServletRequestListeners as 
reliable hooks
Undertow, JBoss Web, Jetty and Grizzly all do this.
Tomcat [1] uses an alternative implementation which simply does the 
following:
1) Thread A calls ServletRequestListener.requestInitialized()
2) the entire request is processed in threads A, B and C
3) Thread C calls ServletRequestListener.requestDestroyed()
This implementation:
guarantees property (1) - the pair of callbacks only called once
sacrifices property (2) - as a result, a ThreadLocal set by 
ServletRequestListener.requestInitialized() will probably not be cleaned 
up in the corresponding ServletRequestListener.requestDestroyed() call 
as it is invoked in a different thread - making frameworks that work on 
all the other implementations leak on Tomcat
I do not find the specification clear enough to tell which of the two 
options is the correct one. I found the following mentions in the 
specification:
Table 11-3
A servlet request has started being processed by Web components. - 
javax.servlet.ServletRequestListener
Javadoc:
A ServletRequest is defined as coming into scope of a web application 
when it is about to enter the first servlet or filter of the web 
application, and as going out of scope as it exits the last servlet or 
the first filter in the chain.
Which all leave room for interpretation.
The fact that two very different implementations of this behavior exist 
significantly reduces the usability of ServletRequestListener API by 
frameworks. I am therefore asking you for clarification of which one of 
these two implementations is correct and/or matches the best the 
original intention of specification authors and should be prefered.
Regards,
Jozef Hartinger
[1] 
https://issues.apache.org/bugzilla/show_bug.cgi?id=57314