servlet
servlet copied to clipboard
Clarify how async ReadListener changes the contract of ServletInputStream methods
The use of an async ReadListener allows the normal read methods to be used in async mode. However nowhere in the javadoc do we document how that behaviour is changed and I think they may be a few corner cases that are ambiguous:
- can the
ServletInputStream.readLinemethod be used? Currently it has a default implementation that will fail in async mode asisReady()is not called. Should implementations override this with a method that works asynchronously and returns 0 if a complete line is not available? Or should the default implementation be updated to throw ISE if there is a ReadListener? - Ditto for
readAllBytes()andreadNBytes(...),skip(long),skipNBytes(long),transferTo(OutputStream): should they ISE, block or return null if insufficient data is available? - The javadoc of
isReady()is very light on and really needs to make clear the scheduling implications of a false return - ie that one of theReadListenercallbacks will eventually be called if false is return. - If
read(byte[],int,int)is called without previously callingisReady():- Should ISE always be thrown?
- Should ISE be thrown only if there is no data available?
- Should 0 be returned if there is no data available? If so, is this equivalent to a call to
isReady()returning false? ie will a callback be scheduled when data is available?
- If
read(byte[],int,int)is called afterisReady()returns false andonDataAvailable, should 0 be returned or ISE thrown? - If
read()is called, then returning 0 is not an option as it is a valid byte. So how shouldread()handle all of the situations above?
@markt-asf @stuartwdouglas any thoughts on this? Do you want me to propose some javadoc changes to clarify the way I think it should be? which are:
- ISE should be thrown from
readLine,readAllBytes,readNBytes,transferTo,skipNBytesand any other blocking methods added toInputStream skipworks normally- ISE will be thrown by any read without a prior
isReadycall. You may need to talk me down from this one... but at the very leastread()has to throw ISE if no data is available. If we allow 0 to be returned from a read, then it should not be the same as returning false fromisReady- ie no scheduling is done.
I don't think we can't do anything about readAllBytes, readNBytes, transferTo or skipNBytes as none of them are Java 8 methods.
Happy with skip working normally.
I think ISE is the only realistic option for readLine
I'm fine with an ISE for a read() without a prior isReady. Tomcat already does this.
I am happy with the above, Undertow will already throw an ISE for read() without a prior isReady.
Perhaps these decisions should be reflected in new TCK tests?
Perhaps these decisions should be reflected in new TCK tests?
Yes, please!
I don't think we can't do anything about
readAllBytes,readNBytes,transferToorskipNBytesas none of them are Java 8 methods.
Now with the recent release of the Servlet Spec on post Java 8 bytecodes, I would like to revive this discussion and make these methods also throw ISE.