• Post Reply Bookmark Topic Watch Topic
  • New Topic

java.util.NoSuchElementException being received at input.nextByte();  RSS feed

 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have created a project which takes inputs and calculates percentages, etc. I have modularized my project so that once the user is done with an operation, the user is presented with a choice whether to exit the program or to return back to the main selection screen. However, I don't even get a prompt to enter anything. The program does what it's supposed to, except it throws an exception right after that, without giving me a chance to enter any Scanner input. Why is this happening?

Here is my clean-up/end-of-calculation class:



My console output is as follows:



Just to be clear, the program runs perfectly fine otherwise, and the issue isn't in any of the other classes to the best of my knowledge.
 
Henry Wong
author
Sheriff
Posts: 23280
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Richardson wrote:
Just to be clear, the program runs perfectly fine otherwise, and the issue isn't in any of the other classes to the best of my knowledge.


Are you sure about this? ... because one of the causes of the no such element exception is due to the stream being closed.

So... it could be, in your other class, you either directly closed the standard input, or closed a scanner that wrapped the standard input.  Never close a stream that you did not open, and that includes never closing a scanner that is wrapping a stream that you did not open.

Henry
 
Campbell Ritchie
Sheriff
Posts: 55351
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:. . . one of the causes of the no such element exception is due to the stream being closed. . . .
You might have closed the input stream programmatically with something like myScanner.close() or by passing something like ctrl‑Z/ctrl‑D to close the standard input stream. As Bear told you, and I told you yesterday, you mustn't do either. You can get such an exception if reading a file if you go beyond the end of the file, but you don't get that exception if the type entered (file or keyboard) is different from what the Scanner expected. You get a different exception.

Why are you requesting a byte? Bytes are not for general use, but for transmitting data across networks. Make that variable an int.
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Henry Wong wrote:. . . one of the causes of the no such element exception is due to the stream being closed. . . .
You might have closed the input stream programmatically with something like myScanner.close() or by passing something like ctrl‑Z/ctrl‑D to close the standard input stream. As Bear told you, and I told you yesterday, you mustn't do either. You can get such an exception if reading a file if you go beyond the end of the file, but you don't get that exception if the type entered (file or keyboard) is different from what the Scanner expected. You get a different exception.

Why are you requesting a byte? Bytes are not for general use, but for transmitting data across networks. Make that variable an int.


I do close my stream in other classes, but I can't help but think that since in this particular class (EndOfCalculation.java) I am opening an instance of Scanner, doing no other operations and subsequently using nextByte, I should at least get an input prompt in my console and that the closing of the input stream couldn't possibly come into play.


Here is an example of me closing the input stream in my other classes: http://imgur.com/a/ALhVK

For clarification, in my operations package are all of my various operations dealing with percentage calculation.

As for why I use a byte, well, I know a byte only goes up to 127 positive integers, and since for these particular switch statements, I am only going to be using a few different cases, byte works, no?


 
Dave Tolls
Ranch Hand
Posts: 2835
30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And as soon as you call close on that Scanner in that image (it would have been easier to show it as code here, but never mind) it will close the System.in stream...meaning anything else using, or later trying to use, that stream will fail, as it has been closed.
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
Mark Richardson wrote:
Just to be clear, the program runs perfectly fine otherwise, and the issue isn't in any of the other classes to the best of my knowledge.


Are you sure about this? ... because one of the causes of the no such element exception is due to the stream being closed.

So... it could be, in your other class, you either directly closed the standard input, or closed a scanner that wrapped the standard input.  Never close a stream that you did not open, and that includes never closing a scanner that is wrapping a stream that you did not open.

Henry



This is the code for the little percentage program I wrote as a zip file:

https://www.dropbox.com/s/pe313gcxgkjzfoe/percentage.zip?dl=0

I have commented out all of the places in which I am closing the input stream, but I don't feel good about it because all I now know is that the program works... but I'm not sure why a closing of the stream would have impacted me in my "clean-up" EndofCalculation Class in which I simply opened a NEW stream and tried to get input from it...
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:And as soon as you call close on that Scanner in that image (it would have been easier to show it as code here, but never mind) it will close the System.in stream...meaning anything else using, or later trying to use, that stream will fail, as it has been closed.


I see what you are saying, but in the imagine, that operation happens and then we are taken to the //clean-up part... and the "EndOfCalculation" part where a *new* instance of Scanner is opened up, fresh for the using... What I can't wrap my head around is how a previous closing of the input stream impacts my completely new opening of the input stream.  *scratching head*

Here is my actual code: https://www.dropbox.com/s/pe313gcxgkjzfoe/percentage.zip?dl=0
 
Dave Tolls
Ranch Hand
Posts: 2835
30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It may be a new instance of Scanner, but it's not a new instance of System.in.
When you closed the Scanner, you closed System.in as well...tat's how closing of streams etc works.  Close the outer one, and it closes the one it is wrapping, and on down the chain.

So when you create a new Scanner, using System.in, that InputStream is closed...so Scanner throws an exception when you try to use it.
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:It may be a new instance of Scanner, but it's not a new instance of System.in.
When you closed the Scanner, you closed System.in as well...tat's how closing of streams etc works.  Close the outer one, and it closes the one it is wrapping, and on down the chain.

So when you create a new Scanner, using System.in, that InputStream is closed...so Scanner throws an exception when you try to use it.


But, in my lines 14-15 of EndOfCalculation.java:



I am definitely doing a "new Scanner(System.in)" suggesting to me that i'm opening a brand new instance of it.... no?
 
Tony Docherty
Bartender
Posts: 3264
81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Dave has said yes you are creating a new Scanner object but the underlying stream that your Scanner object uses ie System.in is closed so it can't work.
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Docherty wrote:As Dave has said yes you are creating a new Scanner object but the underlying stream that your Scanner object uses ie System.in is closed so it can't work.


interesting.... doesn't make that much sense to me yet... but I will take it on face value for now.   Thank you guys
 
Mark Richardson
Ranch Hand
Posts: 102
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:It may be a new instance of Scanner, but it's not a new instance of System.in.
When you closed the Scanner, you closed System.in as well...tat's how closing of streams etc works.  Close the outer one, and it closes the one it is wrapping, and on down the chain.

So when you create a new Scanner, using System.in, that InputStream is closed...so Scanner throws an exception when you try to use it.


Next logical question: How could I open it up again?
 
Tony Docherty
Bartender
Posts: 3264
81
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Richardson wrote:interesting.... doesn't make that much sense to me yet... but I will take it on face value for now.   Thank you guys

I'm struggling to think of a good analogy. This is the best I can come up with:

Think of System.in as a book with empty pages and your Scanner(System.in) as a camera looking at that book. Now every time you write something in the book and press the enter key the Scanner reads the page and then the book turns over the page. If you create a new Scanner(System.in), it is looking at the same book. Everything works well until you call close() on one of your Scanner objects because when you call close() the Scanner object also tells the book to close. So now the other Scanner object and any new Scanner(System.in) objects you create are looking at a closed book so there is no way for them to read any input.

Mark Richardson wrote:Next logical question: How could I open it up again?

Restart your application. I'm not aware of any other way of opening System.in.
 
Dave Tolls
Ranch Hand
Posts: 2835
30
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Richardson wrote:
I am definitely doing a "new Scanner(System.in)" suggesting to me that i'm opening a brand new instance of it.... no?


Scanner is a wrapper around the stream you give it.
It doesn't open that stream or, with this constructor, create a stream.
All it does is use it to read stuff.
 
Campbell Ritchie
Sheriff
Posts: 55351
157
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mark Richardson wrote: . . . Next logical question: How could I open it up again?
Tony is right: you can't. Not at all. Starting a new JVM will create an unrelated new standard input stream . . . which you will close again.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!