System.exit(1) and return - java

import java.io.FileNotFoundException;
import java.util.Formatter;
import java.util.FormatterClosedException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class CreateTextFile
{
private Formatter formatter;
public void openFile()
{
try
{
formatter = new Formatter("clients.txt");
}
catch (SecurityException securityException)
{
System.err.println("You do not have permission to access this file");
System.exit(1);
}
catch (FileNotFoundException fileNotFoundException)
{
System.err.println("Error opening or creating the file");
System.exit(1);
}
}
public void addRecords()
{
AccountRecord accountRecord = new AccountRecord();
Scanner scanner = new Scanner(System.in);
System.out.printf("%s%n%s%n%s%n%s%n", "To terminate input, type the end-of-file indicator", "when you are prompted to enter input", "On Unix/Linux/Mac OS X type <control> d then press Enter", "On Windows type <ctrl> z then press Enter");
while (scanner.hasNext())
{
try
{
accountRecord.setAccountNumber(scanner.nextInt());
accountRecord.setFirstName(scanner.next());
accountRecord.setLastName(scanner.next());
accountRecord.setBalance(scanner.nextDouble());
if (accountRecord.getAccountNumber() > 0)
formatter.format("%d %s %s %,.2f%n", accountRecord.getAccountNumber(), accountRecord.getFirstName(), accountRecord.getLastName(), accountRecord.getBalance());
else
System.out.println("Account number must be greater than 0");
}
catch (FormatterClosedException formatterClosedException)
{
System.err.println("Error writing to file");
return;
}
catch (NoSuchElementException noSuchElementException)
{
System.err.println("Invalid input. Try again");
scanner.nextLine();
}
System.out.printf("%s %s%n%s", "Enter account number (>0),", "first name, last name and balance.", "?");
}
scanner.close();
}
public void closeFile()
{
if (formatter != null)
formatter.close();
}
}
I was just wondering why in openFile() the catch blocks are terminated with System.exit() and the catch blocks in addRecords() terminate with return. Is there a recommended way of when each should be used?

They do different things. return simply returns from the function to its caller and the program continues running. System.exit() terminates the program; control does not return to the caller.
You should use System.exit() when your program encounters an unrecoverable error and there is no point in the program continuing to run. Use return when your program can gracefully recover, or when the program should perform cleanup/closeout actions before exiting.
See also this more extended discussion of System.exit().

The return should have been a break, just leaving the while-loop, so that scanner.close() is done.
System.exit is bad style, but feasible for a command line program. Not catching the exception would be somewhat the same: termination with a message, but then with a stack trace too.
In this letting the function throw an exception would be the preferable way.

return statement is used inside a method to come out of it.System.exit(0) is used in any method to come out of program.
System.exit(0) terminates the program narmally.Whereas System.exit(1) terminates the program because of some error encountered in the program.

System.exit() terminates the program at the line of invocation.
System.exit(1) terminates the program if an error occurs.

Related

VM Terminated on static method

public static void main() {
String fileName = "cardNumbers.txt";
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
CreditCard card = new CreditCard(line);
if (card.creditCardType().equalsIgnoreCase("Unknown"))
{
System.out.println("Card number " + card.getCardNumber() + "is an unknown credit card type.");
}
else if (card.isValid())
{
System.out.println(card.creditCardType() + " number" + card.getCardNumber() + " is valid.");
}
else if (!card.isValid())
{
System.out.println(card.creditCardType() + " number " + card.getCardNumber() + " is not valid.");
}
}
}
catch (FileNotFoundException ex)
{
System.out.println("file not found exception thrown");
}
catch (IOException ex)
{
System.out.println("error while reading the file");
}
finally
{
System.exit(0);
}
}
When I run this method it just says ProcessCardNumbers.main(); VM Terminated. Instead of actually printing out the content.
If I add a print at the very start of the function or in the finally block, they are printed.
Im not sure why this is happening or how I can fix it.
As you told us that:
Adding a println at the start is printed
and
Adding a println in the finally works too
we can deduce that your code is working. It's just that when you reach while((line = bufferedReader.readLine()) != null), line stays null, so you never enter your while.
Why is that? Well, your file may be empty to begin with. If it is not, double-check the encoding of your file: it may not be using the proper returns symbols, hence not having a "completed line".
This seems that in your text file cardNumbers.txt has no data. When this program will execute within while loop bufferedReader.readLine()). will return null. So loop will terminate. After termination you have written System.exit(0); function in finally block which terminate JVM on the spot. So JVM is terminated now that's why you are not able to see anything after working of this code.
If you want to check working, write one SOP statement in finally block. Probably that will execute without termination of JVM.
The problem here is not the bug in your code but the design problem that does not let you see the bug.
You are probably getting an undeclared exception (RuntimeException) and the VM can't print it because you kill it before in the finally.
You have several options:
Remove the System.exit(0); and let it die normally. This may fail if there is another non-daemon thread running. You may try to stop it. You can, for example, cancel a Timer.
Add a catch (RuntimeException e) { section before the finally and print the captured error. e.printStackTrace(); should do the trick.
With any of those you should see the exception on console so you can fix it.
Your main method signature must look like this:
public static void main(String[] args)
instead of
public static void main()

How to display a detailed error message using try{ }catch(){ } blocks

Suppose in your program you might get an IndexOutOfBoundsException. i am handling it in the following way:
try{
//throws an IndexOutOfBoundsException during runtime
}catch(IndexOutOfBoundsException ex){
System.err.println(ex);
}
This will only display java.lang.IndexOutOfBoundsException. But I would like to display a detailed error message (which won't terminate the program), like the one that java gives us (lineNumber, fileName, etc) when we do not handle the error and thus terminates the program.
In Java you can use printStackTrace on any exception object to get the stack trace printed by Java. In your case a minimal:
try {
// Throw an IndexOutOfBoundsException
} catch (IndexOutOfBoundsException ex) {
ex.printStackTrace();
}
This prints the stack trace to System.err. You can also pass it a print stream or even System.out to print to that particular stream.
Additionally, if you use java logger, you can use:
logger.log(<LOG_LEVEL>, <LOG_MESSAGE>, ex);
to log the exception. For more details see: https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html
Use ex.printStackTrace() method to print the exception:
try {
int[] x = new int[1];
x[2] = 5;
} catch (IndexOutOfBoundsException ex) {
ex.printStackTrace();
}
System.err.println("Program completed successfully");
Demo.
If you are running in an environment where console output is not desirable, call ex.getStackTrace(), and display elements in a way that is consistent with the user interface of your program.
You can use
ex.GetMessage()
Thanks
Got this from one of my teachers. Might be helpful for other beginners like me.
(This is not a part of any h.w./assignment/etc. Curiosity.)
public class ExceptionDemo{
public static void main(String[] args){
int[] array = new int[2];
try {
System.out.println(array[100]);//non-existent
} catch (IndexOutOfBoundsException ex){
StackTraceElement[] e = ex.getStackTrace();
System.err.println("Got error= " + ex + "\n"+
"in file "+e[0].getFileName() +"\n"+
"in class "+e[0].getClassName() +"\n"+
"in method "+e[0].getMethodName() +"\n"+
"in line "+e[0].getLineNumber());
System.err.println("Full trace= ");
ex.printStackTrace(System.err);
}
System.out.println("As Salamu Alaikum");
}
}

Java exceptions without the code to carry on

I am trying to make a program which allows the user to enter 2 integers (marks).
In case the user doesn't enter an integer, I am creating a try and catch code.
The problem is that after I try to enter letters instead of numbers, there is an error coming out but the program carries on, saying that I didn't pass. How do I let the program stop after saying to the user that he entered a wrong mark?
Here is my code:
public void actionPerformed(ActionEvent e)
try{
myCalculator.setCWK(Integer.parseInt(courseEnter));
myCalculator.setExam(Integer.parseInt(examEnter));
}
catch (Exception a){
System.out.print("System error");
}
displayArea.setText("" + myCalculator.calculateModuleMark());
if(myCalculator.hasPasssed()==true)
{
displayArea.setText(myCalculator.getModuleCode() + "Congratulations! You have PASSED! With a score of " + myCalculator.calculateModuleMark() + "%");
getContentPane().setBackground(Color.green);
}
else
{
displayArea.setText("I am sorry");
getContentPane().setBackground(Color.red);
}
}
If you want the program to "stop" after a certain statement, System.exit(0) is your friend. So, in your catch statement, you could have
catch (Exception a){
System.out.print("System error");
System.exit(0);
}
Note that this is different than return, as System.exit(0) will completely stop your program flow, not just this specific method.
After printing out an error simply type return.
The try...catch blocks means
if an error occurs in the try instruction block, execute the catch instruction block
In your case, you're not exiting the function in your catch block, so it will carry on.
Exception handling is essentially done to prevent the code from exiting abruptly without any error message.
You can just call System.exit(1) after System.out.print("System error").
Note: System.exit(0) means program terminated as expected while any other error code within bracket means there was an error.
So, now your code will be:
public void actionPerformed(ActionEvent e){
try{
myCalculator.setCWK(Integer.parseInt(courseEnter));
myCalculator.setExam(Integer.parseInt(examEnter));
}
catch (Exception a){
System.out.print("System error");
System.exit(1);
}
displayArea.setText("" + myCalculator.calculateModuleMark());
if(myCalculator.hasPasssed()==true)
{
displayArea.setText(myCalculator.getModuleCode() + "Congratulations! You have PASSED! With a score of " + myCalculator.calculateModuleMark() + "%");
getContentPane().setBackground(Color.green);
}
else
{
displayArea.setText("I am sorry");
getContentPane().setBackground(Color.red);
}
}

How to reprompt for invalid Boolean input (java)

When I run the program if I type something other than "true" or "false" it throws a InputMismatchException.
do {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
bus.setIndividualVideo(hasVideo);
} while (!(hasVideo == true) && !(hasVideo == false));
Catch the error and treat it as a invalid response...
try {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
} catch (InputMismatchException exp) {
System.err.println("Please, enter only true or false");
}
Take a look at The try Block for more details
Aha, time to learn about Exception handling! Any of the Exception types that you see when java crashes can in fact be caught inside the program with a try-catch block.
try {
// code that might throw exceptions 1
// code that might throw exceptions 2
} catch (Exception e) {
// do something to fix the error
}
If any code in the try{ } part does throw an Exception then it will immediately skip to the catch( ) { } part, skipping any other statements in the try{ }.
Your code with a try-catch would look like:
boolean loopAgain = false;
do {
try {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
bus.setIndividualVideo(hasVideo);
loopAgain = false;
} catch (InputMismatchException e) {
System.err.println("Please, enter only true or false");
loopAgain = true;
}
} while (loopAgain);
Edit: I borrowed the println("Please, enter only true or false"); from #MadProgrammer's answer.
You have to prompt the user to enter a Boolean value. Because nextBoolean() can throw an exception, the best thing to do is to put that code inside a try/catch. The catch block code is only executed if anything other than true or false is entered. You can add a while() or do/while() loop to keep telling the user to try again. However, the most important thing to do in the catch block is to flush the input stream. Remember, even though there was an exception, the stream still contains stuff in it. It has to be properly consumed before using again. The code below should do exactly what you are looking for:
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
Boolean answer = null;
do
{
System.out.println("Enter either true or false");
try
{
answer = input.nextBoolean();
}
catch(InputMismatchException e)
{
System.out.println("ERROR: The input provided is not a valid boolean value. Try again...");
input.next(); // flush the stream
}
} while(answer == null);
input.close();
}

hasNextInt() From Scanner behaving weirdly

I have a very simple loop that waits for a number (int) and as long as that number is not exitOption it does not leave the loop, however I get an unexpected error, and I don't know what's causing it.
Edit
Adding another snippet so you can compile
public static void main(String[] args) throws FileNotFoundException,
SecurityException,
IOException,
ClassNotFoundException {
while (controller.selectOptionMM());
/Edit
public boolean selectOptionMM() throws SecurityException,
FileNotFoundException,
IOException {
int cmd = ui.getExitOption();
ui.mainMenu();
cmd = utils.readInteger(">>> "); // this is my problem, right here
// code in next snippet
while (cmd <1 || cmd > ui.getExitOption()) {
System.out.println("Invalid command!");
cmd = utils.readInteger(">>> ");
}
switch (cmd) {
case 1:
case 2:
case 3:
case 4: this.repository.close();
return true;
case 5: return false;
}
return false;
}
Here is what fails:
public int readInteger(String cmdPrompt) {
int cmd = 0;
Scanner input = new Scanner(System.in);
System.out.printf(cmdPrompt);
try {
if (input.hasNextInt())
cmd = input.nextInt(); // first time it works
// Second time it does not allow me to input anything
// catches InputMissmatchException, does not print message
// for said catch
// infinitely prints "Invalid command" from previous snippet
} catch (InputMismatchException ime) {
System.out.println("InputMismatchException: " + ime);
} catch (NoSuchElementException nsee) {
System.out.println("NoSuchElementException: " + nsee);
} catch (IllegalStateException ise) {
} finally {
input.close(); // not sure if I should test with if (input != null) THEN close
}
return cmd;
}
First time I pass trough, it reads the number no problem. Now if the number is not 5 (in this case exitOption), it passes again trough readInteger(String cmdPrompt) except this time it jumps to catch (InputMismatchException ime) (debug) except it does not print that message and just jumps to Error, input must be number and Invalid command.
Is something stuck in my input buffer, can I flush it, why is it (input buffer) stuck (with random data)???
I'll try debugging again and see what's stuck in my input buffer, if I can figure out how to see that.
The problem is in the call to input.close() - this causes the underlying input stream to be closed. When the input stream being closed is System.in, bad things happen (namely, you can't read from stdin any more). You should be OK just eliminating this line.
input.hasNextInt()
This line throws the exception if there is no Integer, so instead of it going to else block it forward to catch block. It will never go to else block if exception get caught.

Categories