Why does the inReady method of StreamDecoder swallow IOException?

Jeff Evans jeffrey.wayne.evans at gmail.com
Tue Nov 21 16:07:40 UTC 2017

(replying again on-list)

Hi Sherman,

We actually only support JDK 1.8.x in our product, so I can't answer
as to whether previous JDK versions exhibit the same behavior.  Given
the behavior of the library that ultimately throws this IOException
(Jersey) - namely that it maintains an AtomicReference to the
exception (presumably because it can actually be thrown by a different
thread) - I'm inclined to think it would work the same.  In this
particular case, the IOException happens when the HTTP connection is
terminated by the peer (RST packet), so the close does happen outside
the control flow of StreamDecoder and its reference to the
InputStream.  Given that implRead is already declared to throw
IOException, I don't see why it shouldn't simply allow one thrown from
its inReady invocation to be thrown out from itself.  But as you said,
this code has been unchanged for a long time, and there could be other
factors I'm not aware of.  Perhaps I will reach out to the Jersey
maintainers and ask if they have any suggestions.  Thanks!

On Wed, Nov 15, 2017 at 6:00 PM, Xueming Shen <xueming.shen at oracle.com> wrote:
> Jeff,
> It appears StreamDecoder.inReady()/implReady() works this way, silently
> swallow
> the IOE, from the very beginning/jdk1.4.0. This design/implementation
> probably was
> based on the assumption that the InputStream.available() only throws the IOE
> when
> the input stream has been closed by calling its close() method, as the
> InputStream.available()
> spec suggests. Since the StreamDecoder.isReady()/implReady() is guaranteed
> to be
> invoked under synchronized/ensureOpen() protection, the IOE should never
> occur. But
> it appears this assumption might be incorrect as/if the underlying
> InputStream.available()
> might throw an IOE when the stream is still open/has not been closed via a
> reader's
> close() method, which does not appear to be against the spec.
> @exception  IOException if an I/O error occurs.
> Is this issue only reproducible on the latest jdk1.8.x and works fine with
> previous version?
> If that is the case, it's possible that we might have a different
> "bug/issue" somewhere
> else that the input stream is getting closed without by its reader's close()
> method.
> regard,
> Sherman
> On 11/15/2017 03:11 PM, Jeff Evans wrote:
>> Hello,
>> We are dealing with an issue where an underlying exception appears to
>> be getting swallowed by the StreamDecoder class.  In particular, the
>> Jersey client library we are using (which happens to be version
>> 2.25.1) is throwing an IOException out of its implementation of
>> InputStream#available
>> https://github.com/jersey/jersey/blob/master/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/ByteBufferInputStream.java#L143
>> by way of calling checkThrowable
>> https://github.com/jersey/jersey/blob/master/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/ByteBufferInputStream.java#L127
>> The caller of that is ultimately StreamDecoder#inReady.  We are seeing
>> the problem under Oracle JDK 1.8.0_121, but it seems the StreamDecoder
>> code hasn't changed in a while:
>> http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/nio/cs/StreamDecoder.java#l366
>> Is there some issue with the way the Jersey library code
>> implementation, or potentially some issue with our code that is
>> resulting in this exception not being propagated out from
>> StreamDecoder?  Any insight is appreciated.
>> Full stack trace image here: https://i.imgur.com/AuyYFAp.png

More information about the jdk-dev mailing list