0

Below code is to iterate through the list of files in a folder so as to create data in the db, but throws IllegalStateException: Iterator already obtained exception.

Flux.fromIterable(Files.newDirectoryStream(Paths.get(VIDEO_FILE_LOCATION)))
          .map(file -> new VideoFile(file.getFileName()
                                         .toString()))
          .subscribe(f -> videoRepository.save(f));

Full stack

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
    at com.kalarikkal.KalarikkalApplication.main(Kalarikkalpplication.java:30) ~[main/:na]
Caused by: reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IllegalStateException: Iterator already obtained
Caused by: java.lang.IllegalStateException: Iterator already obtained

Not able to correct this. Please help.

Krishnakumar R
  • 362
  • 2
  • 18
  • post with full stack trace please – Shoshi Apr 18 '20 at 15:15
  • can you make sure that you are using `Files.newDirectoryStream(Paths.get(VIDEO_FILE_LOCATION)` only in this pasted code? like this stream can be iterate just once. if you need again to iterate it, then you have to write `Files.newDirectoryStream(Paths.get(VIDEO_FILE_LOCATION)` this again. – Shoshi Apr 18 '20 at 15:43
  • Yes, I am using it in CommandLineRunner to populate the names of files in the db, nowhere else. On search, I too came across the answer about the DirectoryStream iterated only once. But here, there is only one iteration right? – Krishnakumar R Apr 18 '20 at 15:47
  • sorry brother, I am unable to recreate the problem from my end. even I have tried to implement it in commanlinerunner. but everything goes smoothly from my end. – Shoshi Apr 18 '20 at 16:10
  • You mean similar code works at you end?! . May be I will find out the reason for this some day!!. Thanks for the help. – Krishnakumar R Apr 18 '20 at 16:24
  • yes, it runs without error in my end. hope you will find out the issue :D – Shoshi Apr 18 '20 at 16:29

1 Answers1

1

Based on the suggestion by 123, I have changed the code as below. It works..

    @Bean
      CommandLineRunner init(MongoOperations mongoOperations)
      {
        return args ->
        {
          mongoOperations.dropCollection(VideoFile.class);
    Path myDir = Paths.get(VIDEO_FILE_LOCATION);
          Stream<Path> directorStream = Files.list(myDir);
          Flux.fromStream(directorStream)
              .doOnNext(path -> mongoOperations.insert(new VideoFile(path.getFileName()
                                                                         .toString())))
              .subscribe();
        };
    }
Krishnakumar R
  • 362
  • 2
  • 18
  • `subscribe()` is blocking och reading the file system is blocking, so if this code is in a webflux application, it is bad practice and can crash the application. – Toerktumlare Apr 18 '20 at 21:05
  • I am using this block in a CommandLineRunner to get the file names and insert into Mongo reactively. I have changed the above code and am using MongoOperations now. mongoOperations.insert(new VideoFile(path.getFileName() .toString())); – Krishnakumar R Apr 19 '20 at 05:51
  • I had the same error like you in your first code. After a while searching not found any solution. I changed my code like you, it works. – Ramazan Cinardere Sep 09 '20 at 17:26