Skip to content

Conversation

@senivam
Copy link
Contributor

@senivam senivam commented Apr 24, 2025

No description provided.

Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
@senivam senivam force-pushed the 2x_servletWrapper branch from 61e31e9 to 497adbb Compare April 24, 2025 13:44
@senivam senivam merged commit 48c43f2 into eclipse-ee4j:2.x May 6, 2025
7 checks passed
@senivam senivam deleted the 2x_servletWrapper branch May 6, 2025 10:03
@senivam senivam added this to the 2.47 milestone May 6, 2025
@asharayev
Copy link

asharayev commented Jul 3, 2025

Is it possible to migrate the part of fix to 3.1.* versions branch?

Specifically the following changes, caching wrappedStream to avoid multiple calls to request.getInputStream from InputStreamWrapper:

        try {
            requestContext.setEntityStream(new InputStreamWrapper() {

                private ServletInputStream wrappedStream;
                @Override
                protected InputStream getWrapped() {
                    if (wrappedStream == null) {
                        try {
                            wrappedStream = servletRequest.getInputStream();
                        } catch (IOException e) {
                            throw new UncheckedIOException(e);
                        }
                    }
                    return wrappedStream;
                }
            });
        } catch (UncheckedIOException e) {

?

Let me clarify:
We have a servlet request wrapper that allows multiple consumptions of source input stream through caching of source request's stream bytes. However, current 3.1.* branch calls InputStreamWrapper.getWrapped() consistently while iterating bytes of the stream, not calling it once, and then iterating over the received stream object.

We get the following errors starting from 3.1.8 jersey version:

at java.util.Arrays.copyOf(java.base@21.0.2/Arrays.java:3539)
at java.io.ByteArrayOutputStream.toByteArray(java.base@21.0.2/ByteArrayOutputStream.java:187)
at security.util.MultiReadHttpServletRequest$CachedServletInputStream.<init>(MultiReadHttpServletRequest.java:53)
at security.util.MultiReadHttpServletRequest.getInputStream(MultiReadHttpServletRequest.java:34)
at org.glassfish.jersey.servlet.WebComponent$5.getWrapped(WebComponent.java:431)
at org.glassfish.jersey.innate.io.InputStreamWrapper.getWrappedIOE(InputStreamWrapper.java:40)
at org.glassfish.jersey.innate.io.InputStreamWrapper.available(InputStreamWrapper.java:81)
at sun.nio.cs.StreamDecoder.inReady(java.base@21.0.2/StreamDecoder.java:409)
at sun.nio.cs.StreamDecoder.implRead(java.base@21.0.2/StreamDecoder.java:370)
at sun.nio.cs.StreamDecoder.lockedRead(java.base@21.0.2/StreamDecoder.java:215)
at sun.nio.cs.StreamDecoder.read(java.base@21.0.2/StreamDecoder.java:169)
at java.io.InputStreamReader.read(java.base@21.0.2/InputStreamReader.java:188)
at java.io.Reader.read(java.base@21.0.2/Reader.java:265)

The cause is that org.glassfish.jersey.servlet.WebComponent$5.getWrapped(WebComponent.java:431) calls actually getInputStream for every single byte, thus doesn't iterate over a single stream, rather retrieves a stream every time from request.

If we want to make a stream wrapper that allow multiple reads of the source stream, then we need to return a new stream every time getInputStream() is called, otherwise we don't have any hint on whether this is just an iteration or a start of a new iteration of a stream.

Thanks in advance.

@jansupol
Copy link
Contributor

jansupol commented Jul 4, 2025

@asharayev Sure, it already is in 3.1

@asharayev
Copy link

@asharayev Sure, it already is in 3.1

Indeed! Thanks for the info!

@senivam senivam mentioned this pull request Sep 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Jersey not compatible with HttpServletRequests not always returning the same input stream from version 2.44

4 participants