Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - java.lang.IllegalStateException: source already consumed or closed

I have some code:

    Stream<String> previewImagesURLsList = uploadedVideoItemObj.getPreviewImagesURLsList().parallel();

    Stream<HashMap<String, Object>> imagesStream = previewImagesURLsList
            .map(new Function<String, HashMap<String, Object>>() {
                @Override
                public HashMap<String, Object> apply(String fileName) {
                    HashMap<String, Object> m = new HashMap<>();
                    m.put("preview_file", fileName);
                    m.put("parent_id", gotId);
                    return m;
                }
            });

    HashMap<String, Object>[] filesArr = imagesStream.toArray(HashMap[]::new);

I got on line

 HashMap<String, Object>[] filesArr = imagesStream.toArray(HashMap[]::new);

an exception

java.lang.IllegalStateException: source already consumed or closed
    at java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:455)
    at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:255)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438)
    at my.site.objects.videoitems.uploadedVideoItems.dao.impl.JdbcUploadedVideoItemDAO.insert(JdbcUploadedVideoItemDAO.java:79)
    at my.site.processors.files.threads.ServerUploadedFileProcessor.processFileServer(ServerUploadedFileProcessor.java:53)
    at my.site.processors.files.threads.ServerUploadedFileProcessor.call(ServerUploadedFileProcessor.java:28)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

I can't understand, where is bug. What means this exception and in what cases in can be throwed?

like image 386
Arthur Avatar asked Feb 24 '26 13:02

Arthur


1 Answers

Seems your getPreviewImagesURLsList() is returning a Stream despite its name. A Stream can be used only once so you must ensure that each invocation of getPreviewImagesURLsList() returns a new Stream.

Or better, let it return List as its name suggests and let the caller invoke stream() on it.

By the way, the usual way of using Streams is to chain the method invocations rather than storing the intermediate results in variables to avoid erroneous multiple uses of these variables:

HashMap<String, Object>[] filesArr =
  uploadedVideoItemObj.getPreviewImagesURLsList().parallel()
  // or better if getPreviewImagesURLsList() was returning a List:
  // uploadedVideoItemObj.getPreviewImagesURLsList().parallelStream()
  .map(fileName -> {
    HashMap<String, Object> m = new HashMap<>();
    m.put("preview_file", fileName);
    m.put("parent_id", gotId);
    return m;
  }).toArray(HashMap[]::new);
like image 68
Holger Avatar answered Feb 26 '26 03:02

Holger