Win a copy of TensorFlow 2.0 in Action this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Paul Clapham
  • Bear Bibeault
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Jj Roberts
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • salvin francis
  • Scott Selikoff
  • fred rosenberger

Why nextLine() results in a nosuchelementexception?

 
Ranch Hand
Posts: 203
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why nextLine() results in a nosuchelementexception when two pipes to System.in are opened and then if one is closed?

 
Saloon Keeper
Posts: 7395
66
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Scanners made from System.in are a very special case and should follow these guidelines or "bad" thing will happen:
  • Only ONE Scanner should ever be made for an entire program from System.in. If more than one place in a program requires access to such a Scanner then it must be shared.
  • Never, ever close the Scanner made from System.in.
  •  
    Marshal
    Posts: 70718
    288
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Varuna Seneviratna wrote:. . . two pipes to System.in is opened and then one closed? . . .

    As Carey said, closing System.in via one Scanner closes it completely and you can't reopen it.
     
    Varuna Seneviratna
    Ranch Hand
    Posts: 203
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Using documentation how can this be understood? By looking at the documentation at https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#close-, How could this be understood?
     
    Carey Brown
    Saloon Keeper
    Posts: 7395
    66
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The Scanner class contains several gotchas that are not documented, which is unfortunate considering how heavily the class is used. Often developers are left to create their own wrapper class to smooth over most of the bumps. I have a KeyboardUtility that does this. Cambell Ritchie has a similar one he created. These solve the problem of only having a single Scanner from System.in for an entire project, and deal with other issues like leftover pending new-lines in the input stream. They also provide a framework for prompting the user and input validation. Piped input streams can be handled with a few of the low level wrappers but the bulk of the methods are intended for user keyboard input. You're welcome to borrow this code.
     
    Marshal
    Posts: 25969
    70
    Eclipse IDE Firefox Browser MySQL Database
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Varuna Seneviratna wrote:Using documentation how can this be understood? By looking at the documentation at https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html#close-, How could this be understood?



    The documentation does say that the nextLine() method can throw NoSuchElementException. So that's what there is to understand -- it can happen according to the documentation, and it did happen.

    But as others have already said, you shouldn't expect the documentation to go into details of specific instances of a class. And really your code isn't specific to System.in, either. It shouldn't be hard to write similar code which uses two Scanners over the same String, for example.
     
    Rancher
    Posts: 220
    16
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    In order to understand it, you need to understand what System.in is. System.in is a static input stream variable. It does not get instantiated by the developer, and there's only one instance of it that ever exists. Therefore when you create two Scanners pointing at System.in, they are both pointing to the same input stream.

    So when you close that one input stream, both Scanners that use the input stream can no longer process data from it.

    It is not documented in Scanner - and it should not be, because it's not a behavior of Scanner. It's a behavior of System.in. If you use System.in in any other class that uses an Input Stream and you close it, it'll do the same thing.
     
    Ranch Hand
    Posts: 41
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    hasNextLine() returns boolean if you do not use a loop at least use an "if" test to determine whether to call nextLine()
     
    Campbell Ritchie
    Marshal
    Posts: 70718
    288
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    But System.in always implicitly might have a next line; as soon as you push any key that next line will exist and hasNextLine() will return true. So...is going to behave as an infinite loop.
     
    Samuel Marchant
    Ranch Hand
    Posts: 41
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:But System.in always implicitly might have a next line; as soon as you push any key that next line will exist and hasNextLine() will return true. So...is going to behave as an infinite loop.



    What interests me is the scanners are on seperate instances , are new and not static.
    The STDIN and STDOUD are in effect static as there is only  one OS and computer so in effect the two scanner references are of something that never closes anyhow.
     
    Campbell Ritchie
    Marshal
    Posts: 70718
    288
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Only say STDIN/STDOUT/STDERR (remember there are three “standard“ streams) if you are writing C.
    Yes, the three streams are declared as static fields in the System class; it is possible to close any one of them, which OP is doing in this case by calling close() on a Scanner object.
    Yes, you could use two Scanner objects, but what's the point? They are both pointing to the same input and there is a risk of them interfering with each other about which token comes next. Also Scanners aren't thread‑safe. If you use close one Scanner, then as Zachary Griggs said,

    . . . when you close that one input stream, both Scanners that use the input stream can no longer process data from it. . . .

     
    We don't have time for this. We've gotta save the moon! Or check this out:
    Thread Boost feature
    https://coderanch.com/t/674455/Thread-Boost-feature
    reply
      Bookmark Topic Watch Topic
    • New Topic