Bug 57284 - When in async mode and calling it from another thread, chain.doFilter() throws NPE
Summary: When in async mode and calling it from another thread, chain.doFilter() throw...
Status: RESOLVED INVALID
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.56
Hardware: PC All
: P2 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL: https://github.com/circlespainter/ser...
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-29 17:30 UTC by Fabio Tudone
Modified: 2014-12-19 10:38 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Fabio Tudone 2014-11-29 17:30:15 UTC
Also happens in 7.0.57 and 8.0.15.

Exception in thread "Thread-1" java.lang.NullPointerException
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:258)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at servlet.thread.ThreadFilter$1.run(ThreadFilter.java:60)
        at java.lang.Thread.run(Thread.java:745)

Complete (Gradle-based) test here: https://github.com/circlespainter/servlet3-filter-async-test
Comment 1 Mark Thomas 2014-12-04 20:09:12 UTC
My favourite kind of bug fix. One where all I have to do is delete stuff. This will be committed to trunk and back-ported to 8.0.x and 7.0.x when svn returns to read-write:
https://github.com/markt-asf/tomcat/commit/fe5fd7ba6b44dbc7ffad65dc6e906278109e58eb
Comment 2 Mark Thomas 2014-12-05 18:35:49 UTC
This has been fixed in trunk and in 8.0.x (for 8.0.16 onwards).
Comment 3 Konstantin Kolinko 2014-12-05 22:35:42 UTC
The stacktrace: you are trying to call  FilterChain.doFilter() from within a runnable ($1)?

It is wrong and contradicts with chapter 6 (Filters) of the Servlet Specification.

<quote>A Filter and the target servlet or resource at the end
of the filter chain must execute in the same invocation thread.</quote>

FilterChain.doFilter() cannot be called from a different thread.
Comment 4 Mark Thomas 2014-12-06 00:05:44 UTC
The fix has been reverted. Given the text in section 6.2.3, I am resolving this as invalid until such time the Servlet EG clarifies that 6.2.3 does not apply to asycn requests.
Comment 5 Fabio Tudone 2014-12-07 16:26:02 UTC
Yes, indeed Im trying to call from a different thread.

My apologies for not having checked the spec and for having instead just assumed it should work; my reasoning is that it can be very useful to start async mode in filters (so, early in the request processing chain) rather than in the servlet.

For example I'm working on several web framework integrations with Quasar (https://github.com/puniverse/quasar), a technology that enables dispatching execution to "fibers" (which can be much cheaper than threads). Being able to dispatch potentially expensive filter processing to fiber-based execution contexts would be a good thing (plus it would make async processing more transparent for the framework being integrated).

I think supporting more than the servlet spec mandates is not a bad thing per se, but in case in this circumstance this is not sensible in your opinion, would it be possible at least to throw some exception pointing at the wrong usage?

TIA
Comment 6 Eugene Chung (TmaxSoft) 2014-12-19 09:00:04 UTC
FYI : I hope it might help you that AsyncContext.dispatch() mechanism supports FilterChain.
Comment 7 Fabio Tudone 2014-12-19 09:25:25 UTC
Thanks, yes it dispatches to a whole new processing chain including filters but it will do so in the context of another servlet container thread, so it's not very useful for this specific case of avoiding using threads.
Comment 8 Remy Maucherat 2014-12-19 09:46:06 UTC
Since the discussion is going on in the Servlet EG, and this is used as a reference, I have to mention this makes no sense to me.

- Detaching a filter chain prevents any reuse, its state has to be frozen and thus every invocation would need a new instance
- This breaks EE (naming, etc, should be available when invoking the Servlet, here obviously it is not going to happen)
- Async invocations likes this should, well, use async instead (the Servlet API async is under the control of the container, and it can provide its EE environment)

I think it would be better if Tomcat kept deviations from specifications and established behaviors down to a minimum.
Comment 9 Fabio Tudone 2014-12-19 09:56:35 UTC
I understand your point that there would be several implications. Still the API shape itself doesn't forbid attempting to do such things, so I think it would be better, if reasonably feasible, that such conditions were reported to the developer with at least some indication about them not being allowed.
Comment 10 Remy Maucherat 2014-12-19 10:36:30 UTC
There is nothing to "understand", this has always been 100% clear for everyone and all implementations, and the specification will be clarified. I have no idea how a reasonable developer could actually infer that this behavior was actually allowed.
Comment 11 Fabio Tudone 2014-12-19 10:38:46 UTC
Ok, thanks for discussing this anyway.