admin管理员组

文章数量:1122832

I'm currently writing a program that has to fetch files from one API and send them to another one. I thought it would be nice to just take the byte stream and stream it directly from the response into the request, as I avoid saving the whole file again in a byte[] in memory and also avoid costly file system writes / reads.

And this works. Sometimes...

Sometimes I get this beast of an Exception:

// Application Exception ... //
Caused by: java.io.UncheckedIOException: java.io.IOException: closed
    at de.trinext.lib.nf.api.util.MultiPartBodyPublisher$PartsIterator.hasNext(MultiPartBodyPublisher.java:121)
    at java.http/jdk.internal.http.RequestPublishers$IterablePublisher$ByteBufferIterator.hasNext(RequestPublishers.java:135)
    at java.http/jdk.internal.http.PullPublisher$Subscription$PullTask.run(PullPublisher.java:120)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
    at java.http/jdk.internal.http.PullPublisher$Subscription.request(PullPublisher.java:138)
    at java.http/jdk.internal.http.Stream$RequestSubscriber.trySend(Stream.java:1132)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$TryEndDeferredCompleterplete(SequentialScheduler.java:324)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:151)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
    at java.http/jdk.internal.http.Stream.signalWindowUpdate(Stream.java:967)
    at java.http/jdk.internal.http.WindowController.increaseStreamWindow(WindowController.java:275)
    at java.http/jdk.internal.http.Stream.incoming_windowUpdate(Stream.java:714)
    at java.http/jdk.internal.http.Stream.otherFrame(Stream.java:508)
    at java.http/jdk.internal.http.Stream.incoming(Stream.java:502)
    at java.http/jdk.internal.http.Http2Connection.processFrame(Http2Connection.java:1051)
    at java.http/jdk.internal.http.frame.FramesDecoder.decode(FramesDecoder.java:155)
    at java.http/jdk.internal.http.Http2Connection$FramesController.processReceivedData(Http2Connection.java:310)
    at java.http/jdk.internal.http.Http2Connection.asyncReceive(Http2Connection.java:859)
    at java.http/jdk.internal.http.Http2Connection$Http2TubeSubscriber.processQueue(Http2Connection.java:1756)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
    at java.http/jdk.internal.http.Http2Connection$Http2TubeSubscriber.runOrSchedule(Http2Connection.java:1773)
    at java.http/jdk.internal.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1800)
    at java.http/jdk.internal.http.Http2Connection$Http2TubeSubscriber.onNext(Http2Connection.java:1734)
    at java.http/jdk.internal.httpmon.SSLTube$DelegateWrapper.onNext(SSLTube.java:210)
    at java.http/jdk.internal.httpmon.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:492)
    at java.http/jdk.internal.httpmon.SSLTube$SSLSubscriberWrapper.onNext(SSLTube.java:295)
    at java.http/jdk.internal.httpmon.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:316)
    at java.http/jdk.internal.httpmon.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:259)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
    at java.http/jdk.internal.httpmon.SubscriberWrapper.outgoing(SubscriberWrapper.java:232)
    at java.http/jdk.internal.httpmon.SubscriberWrapper.outgoing(SubscriberWrapper.java:198)
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:465)
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:283)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    ... 3 more
Caused by: java.io.IOException: closed
    at java.http/jdk.internal.http.ResponseSubscribers$HttpResponseInputStream.current(ResponseSubscribers.java:464)
    at java.http/jdk.internal.http.ResponseSubscribers$HttpResponseInputStream.read(ResponseSubscribers.java:508)
    at java.base/java.io.InputStream.read(InputStream.java:220)
    at de.trinext.lib.nf.api.util.MultiPartBodyPublisher$PartsIteratorputeNext(MultiPartBodyPublisher.java:175)
    at de.trinext.lib.nf.api.util.MultiPartBodyPublisher$PartsIterator.hasNext(MultiPartBodyPublisher.java:119)
    ... 53 more
Caused by: java.io.IOException: fixed content-length: 2861131, bytes received: 1539620
    at java.http/jdk.internal.httpmon.Utils.wrapWithExtraDetail(Utils.java:391)
    at java.http/jdk.internal.http.Http1Response$BodyReader.onReadError(Http1Response.java:676)
    at java.http/jdk.internal.http.Http1AsyncReceiver.checkForErrors(Http1AsyncReceiver.java:302)
    at java.http/jdk.internal.http.Http1AsyncReceiver.flush(Http1AsyncReceiver.java:268)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:177)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:282)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:251)
    at java.http/jdk.internal.http.Http1AsyncReceiver.onReadError(Http1AsyncReceiver.java:516)
    at java.http/jdk.internal.http.Http1AsyncReceiver$Http1TubeSubscriber.onError(Http1AsyncReceiver.java:595)
    at java.http/jdk.internal.httpmon.SSLTube$DelegateWrapper.onError(SSLTube.java:257)
    at java.http/jdk.internal.httpmon.SSLTube$SSLSubscriberWrapperplete(SSLTube.java:441)
    at java.http/jdk.internal.httpmon.SSLTube$SSLSubscriberWrapper.onErrorImpl(SSLTube.java:511)
    at java.http/jdk.internal.httpmon.SSLTube$SSLSubscriberWrapper.onError(SSLTube.java:525)
    at java.http/jdk.internal.httpmon.SubscriberWrapper$DownstreamPusher.run1(SubscriberWrapper.java:294)
    at java.http/jdk.internal.httpmon.SubscriberWrapper$DownstreamPusher.run(SubscriberWrapper.java:259)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:280)
    at java.http/jdk.internal.httpmon.SequentialScheduler.runOrSchedule(SequentialScheduler.java:233)
    at java.http/jdk.internal.httpmon.SubscriberWrapper.errorCommon(SubscriberWrapper.java:421)
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader.errorCommon(SSLFlowDelegate.java:384)
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:517)
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:283)
    at java.http/jdk.internal.httpmon.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
    at java.http/jdk.internal.httpmon.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
    at java.http/jdk.internal.httpmon.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
    at java.base/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)
    at java.base/java.lang.VirtualThread.run(VirtualThread.java:329)
Caused by: java.io.IOException: BUFFER_UNDERFLOW with EOF, 8570 bytes non decrypted.
    at java.http/jdk.internal.httpmon.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:487)
    ... 6 more

I don't really understand how this problem only occurs sparsely for identical requests. The program is something like:

  • Fetch file
  • Save InputStream from HttpResponse.BodyHandlers.ofInputStream() in a variable
  • Submit the InputStream as a Supplier to this MultiPartBodyPublisher implementation.
  • Send the request using java.http.HttpRequest.Builder.POST(BodyPublisher)

本文标签: javaIOException while streaming file from HTTP response into HTTP requestStack Overflow