Handling FileNotFoundException in a different file - java

It's been a while since I've used Java so I feel silly that this is confusing me, but I have a class 'FileProcessor' in a 'FileProcessor.java' file. I'm trying to use it in my 'Driver.java' file but I keep getting this error:
error: unreported exception FileNotFoundException; must be caught or declared to be thrown
I'm a little confused by the whole exceptions thing in Java and I thought I handled it in my FileProcessor.java file but I don't know.
FileProcessor.java
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.FileNotFoundException;
public class FileProcessor{
/**
* Reads one line from file
* #param arg A file
* #return The line that is read
*/
public String readLineFromFile(File f) throws FileNotFoundException,
IOException{
BufferedReader br = null;
String line;
try{
br = new BufferedReader(new FileReader(f));
line = br.readLine();
return line;
}
catch(IOException e){
e.printStackTrace();
System.err.println("Read method failed");
throw new IOException();
}
catch(FileNotFoundException e1){
e1.getMessage();
System.err.println("File is not found");
throw new FileNotFoundException();
}
}
}
Driver.java
import java.io.File;
import java.io.FileNotFoundException;
public class Driver{
public static void main(String args[]){
File inFile = null;
if (0 < args.length){
inFile = new File(args[0]);
}
else{
System.err.println("No input file found");
System.exit(0);
}
FileProcessor fileProcessor = new FileProcessor();
String lineRead;
try{
lineRead = fileProcessor.readLineFromFile(inFile);
}
catch(FileNotFoundException e){
throw new FileNotFoundException();
}
}
}

Your main throws a new FileNotFoundException in the catch block which can't be catched outside of main. Change:
import java.io.File;
import java.io.FileNotFoundException;
public class Driver{
public static void main(String args[]){
File inFile = null;
if (0 < args.length){
inFile = new File(args[0]);
}
else{
System.err.println("No input file found");
System.exit(0);
}
FileProcessor fileProcessor = new FileProcessor();
String lineRead;
try{
lineRead = fileProcessor.readLineFromFile(inFile);
}
catch(FileNotFoundException e){
System.out.print(e.getMessage());
}
}
}

Throwing a new IO- or FileNotFoundException when you catch them is not a good handling of this exceptions.
catch(IOException e){
e.printStackTrace();
System.err.println("Read method failed");
throw new IOException();
}
First, you loose the Exception information (which file can not be found, what exactly happened, ...). Second, it does not really catch them if you throw it again, so you have to catch them again one frame above.
So, the simplest possible solution is to delete the throw statement.
public class FileProcessor{
public String readLineFromFile(File f)
// this can be deleted if you catch the exceptions
// in here (and do not rethrow them)
// throws FileNotFoundException, IOException
{
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
return br.readLine();
} catch(IOException e) {
e.printStackTrace();
// throw new IOException();
}
// this can be deleted because FileNotFoundException is a
// subclass of IOException and is caught above
// catch(FileNotFoundException e1){
// e1.getMessage();
// System.err.println("File is not found");
// throw new FileNotFoundException();
// }
// and after all, you should close the BufferedReader
// or use the "try-with-resources"
finally {
if(br != null) { br.close(); }
}
}
}

There are few things to do with Exceptions.
You catch the Exception and you write your appropriate code needed to handle the Exception, Example logging, setting error message or triggering fail mail, retry with new file name etc. For this you write the catch block along with try.
2.You catch the Exception and you write your appropriate code needed to handle the Exception, Example logging etc but you want future code which calls your method to catch and process the exception again. In this case you will re throw the exception using throw new and add it in throws. you can even throw new Exception type like
catch(NullPointerException e) {
throw new RecipeNotFoundException("No recipe found");
}
Delay the handling to future code which calls this method. This is done by writing throws clause. Throws tell method(s) calling a method that there are possibilities an exception can occur here and it is not caught and you need to catch and you wont write catch.
In your code you have caught the code in FileProcessor.readLineFromFile(File) method but you have also added throws clause to the method. So the system thinks there are chances an exception can be re thrown and not caught possible another FileNotFoundException from the catch block.
One more thing after catching the Exception you have re thrown same exception throw new IOException(); and throw new FileNotFoundException(); remove that too.
If you go through Java documentation on FileNotFoundException and IOException here. docs.oracle.com/javase/7/docs/api/java/io/… and docs.oracle.com/javase/7/docs/api/java/io/IOException.html you will notice FileNotFoundException actually extends IOException so you do not have to actually catch FileNotFoundException.

Related

In try with resources in java, what happens when there is an exception in close() when there is a catch block? [duplicate]

This question already has answers here:
Try-with-resources: Must I throw or catch the close() method's exceptions? [duplicate]
(4 answers)
Closed last year.
In this code, when there is an exception in br.close(), will catch block catch it or will the process be terminated?
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class TryWithBlock {
public static void main(String args[])
{
System.out.println("Enter a number");
try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in)))
{
int i = Integer.parseInt(br.readLine());
System.out.println(i);
}
catch(Exception e)
{
System.out.println("A wild exception has been caught");
System.out.println(e);
}
}
}
From the docs:
The resource declared in the try-with-resources statement is a
BufferedReader. The declaration statement appears within parentheses
immediately after the try keyword. The class BufferedReader, in Java
SE 7 and later, implements the interface java.lang.AutoCloseable.
Because the BufferedReader instance is declared in a try-with-resource
statement, it will be closed regardless of whether the try statement
completes normally or abruptly (as a result of the method
BufferedReader.readLine throwing an IOException).
Basically, it's equivalent to:
BufferedReader br = new BufferedReader(new FileReader(System.in));
try {
int i = Integer.parseInt(br.readLine());
System.out.println(i);
} finally {
br.close();
}
Let's try it out (from here a working example):
//class implementing java.lang.AutoCloseable
public class ClassThatAutoCloses implements java.lang.AutoCloseable {
public ClassThatAutoCloses() {}
public void doSomething() {
System.out.println("Pippo!");
}
#Override
public void close() throws Exception {
throw new Exception("I wasn't supposed to fail");
}
}
//the main class
public class Playground {
/**
* #param args
*/
public static void main(String[] args) {
//this catches exceptions eventually thrown by the close
try {
try(var v = new ClassThatAutoCloses() ){
v.doSomething();
}
} catch (Exception e) {
//if something isn't catched by try()
//close failed will be printed
System.err.println("close failed");
e.printStackTrace();
}
}
}
//the output
Pippo!
close failed
java.lang.Exception: I wasn't supposed to fail
at ClassThatAutoCloses.close(ClassThatAutoCloses.java:26)
at Playground.main(Playground.java:24)
Exceptions thrown inside the try-with-resources statement are supressed. Exceptions thrown inside the try block are propagated. So in your case the catch block will catch the parsing exception (if any).
For more details you can refer at the docs.

Exception is not thrown in coressponding try block

I am trying execute below code. But I am getting compile time errors. I have written below code to display the contents of the file "myfile.txt".
But Actually there is no file "myfile.txt". Then an exception "FileNotFound" should be thrown at run time. But the below programme is not compiled.
Why am i getting compile time errors?
code:
import java.io.*;
class rethrow {
public static void main(String args[]) {
rethrow rt = new rethrow();
try {
rt.m1();
} catch (FileNotFoundException FNFE) {
FNFE.printStackTrace();
}
}
void m1() {
try {
FileInputStream fin = new FileInputStream("myfile.txt");
System.out.println("file contents");
int ch;
while ((ch = fin.read()) != -1)
System.out.println((char) ch);
fin.close();
} catch (FileNotFoundException FNFE) {
FNFE.printStackTrace();
throw FNFE;
} catch (IOException IOE) {
IOE.printStackTrace();
}
}
}
---------------------------`---------------------------
OUT PUT:
rethrow.java:11: exception java.io.FileNotFoundException is never thrown in bod
y of corresponding try statement
catch(FileNotFoundException FNFE)
^
rethrow.java:30: unreported exception java.io.FileNotFoundException; must be ca
ught or declared to be thrown
throw FNFE;
^
2 errors
you have to add the throws clause in method m1:
void m1() throws FileNotFoundException {
otherwise you have a Unreachable catch block for FileNotFoundException in your main method and Unhandled exception type FileNotFoundException in your method m1.
catching the exception in m1 is not necessary with that change.
Declare your method as following
void m1() throws FileNotFoundException
{
try
{
FileInputStream fin=new FileInputStream("myfile.txt");
System.out.println("file contents");
int ch;
while((ch=fin.read())!= -1)
{
System.out.println((char)ch);
}
fin.close();
}
catch(FileNotFoundException FNFE)
{
FNFE.printStackTrace();
throw FNFE;
}
catch(IOException IOE)
{
IOE.printStackTrace();
}
}
You should declare what type of exceptions your method throws to the calling method.

Using custom exception in Java

I am trying to throw my custom exception in java but currently I have had no luck. I have two classes a readWrite class which allows the user to enter the file name and a text to be wrote to the file (via the constructor). It has three methods, write, read and a writeToFile which validates if the file ends in .txt if it does now it should throw my custom exception class stating that "Sorry but this system only accepts .txt files" which I have created in a toString() method in my custom exception. I can not seem to make it work, below is the code, some might be able to help, I hope I have explained properly as I am new to Java, note I have commented out some code as I was trying a few different things to make it work
ReadWrite.java
import java.io.*;
public class ReadWrite
{
private final String file;
private final String text;
public ReadWrite(String file, String text)
{
// initialise instance variables
this.file=file;
this.text=text;
}
private void write() //throws InvalidFileException
{
try {
FileWriter writer = new FileWriter(file);
writer.write(text);
writer.write('\n');
writer.close();
}
catch(IOException e)
{
System.out.print(e);
}
}
public boolean writeToFile()
{
boolean ok;
try{
FileWriter writer = new FileWriter(file);
{
if(file.toLowerCase().endsWith(".txt"))
{
write();
ok = true;
} //if end
else{
ok=false;
//throw new InvalidFileException();
} //else end
}
} //try end
catch(IOException e) {
ok=false;
} // catch end
//catch (InvalidFileException e){
//System.out.println(e.toString());
//}
return ok;
}
public void read(String fileToRead)
{
try {
BufferedReader reader = new BufferedReader(new FileReader(fileToRead));
String line = reader.readLine();
while(line != null) {
System.out.println(line);
line = reader.readLine();
}// while end
reader.close();
}//try end
catch(FileNotFoundException e) {
System.out.println(fileToRead + " the system can not find the file specified");
} //catch end
catch(IOException e) {
e.printStackTrace();
} //catch end
}
}
InvalidFileException.java
import java.io.FileNotFoundException;
import java.io.*;
public class InvalidFileException extends Exception
{
/**
* Constructor for objects of class InvalidFileException
*/
public InvalidFileException(String message)
{
super(message);
}
public String toString()
{
return ("Sorry but this system only accepts .txt files");
}
}
try this:
private void write() throws InvalidFileException {
try {
if(!file.getName().endsWith(".txt") {
throw new InvalidFileException(".txt files only.");
}
FileWriter writer = new FileWriter(file);
writer.write(text);
writer.write('\n');
writer.close();
}
catch(IOException e)
{
// handle exception please.
}
Please note, that you have to override the "getMessage()" Method of Exception in order to print your custom message. Or set it in the super() call.
Overriding the toString() method makes your super() call and therefore your custom (detail) message passed to the exception (in my example ".txt files only.") obsolete, because this string won't be printed anymore.
Below is your requirement:
it does not it should throw my custom exception class stating that
"Sorry but this system only accepts .txt files"
I think you got confused because of toString. You really don't need that toString method. You correctly implemented a InvalidFileException which accepts a String argument.
So, now all you need is throw new InvalidFileException("Sorry but this system only accepts .txt files"); or use whatever String message you want while throwing InvalidFileException.
Please note, if you are throwing an exception from a method and catching it in same method looks illogical unless you are doing because APM (application performance monitoring) tools logging purpose.
As other note, if you are throwing exception like this then you need to add a throw statement in your method signature indicating that this method "may" throw so-and-so exception. So, that called of that method can either re-throw or catch it.
If you are catching the exception somewhere then use getMessage method on the exception object and you will get same message as you placed while throwing the exception, in this case - "Sorry but this system only accepts .txt files"
InvalidFileException extends Exception but you only ever try to catch IOException and FileNotFoundException. I think you meant to have InvalidFileException extend IOException.

Junit Test case of method that already has a try-catch clause

I'm trying to write a test case for the method setTrailer() within the class ErParser. setTrailer() has try-catch clauses, and in one of its catch clauses, it catches NullPointerException. I'm trying to write a Junit test for the case where setTrailer() throws and catches a NullPointerException, but the test case keeps failing. Is it because I already caught the exception in the method itself? Should I be catching the exception in the test case instead?
The test case:
public class TestERParser {
#Test(expected=NullPointerException.class)
public void nullSetTrailer() {
ERParser recCurrParse = new ERParser();
recCurrParse.setTrailer(null);
}
}
setTrailer() method within the ERParser Class:
public class ERParser {
private static final String TRAILER_E = "GRAND TOTAL";
private static final String TRAILER_R = "TRAILER";
public String trailerRecord;
/**
* Constructs an ERParser object.
*/
public ERParser() {
this.trailerRecord = null;
this.trailerVals = null;
}
/**
* Populates the trailerRecord field with the summary (trailer) record of the input file.
* #param file Input file
* #throws NullPointerException, FileNotFoundException, IOException
*/
public void setTrailer(File file) {
try {
FileReader fReader = new FileReader(file);
BufferedReader bReader = new BufferedReader (fReader);
String currLine = new String();
readLoop:
while (bReader.ready()) {
currLine = bReader.readLine();
if (currLine.contains(TRAILER_E) || currLine.contains(TRAILER_R)) {
break readLoop;
}
}
this.trailerRecord = currLine.trim();
System.out.println("From setTrailer(): " + this.trailerRecord);
fReader.close();
bReader.close();
} catch (NullPointerException exception) {
exception.printStackTrace();
} catch (FileNotFoundException exception) {
exception.printStackTrace();
} catch (IOException exception) {
exception.printStackTrace();
}
}
}
As you suspected you are catching the NPE inside of your code and it is not being propagated. If you expected your users to catch this exception you should remove this code and adorn your method with throws, to the appropiate classes.
public void setTrailer(File file) throws Exception {
FileReader fReader = new FileReader(file);
BufferedReader bReader = new BufferedReader (fReader);
String currLine = new String();
readLoop:
while (bReader.ready()) {
currLine = bReader.readLine();
if (currLine.contains(TRAILER_E) || currLine.contains(TRAILER_R)) {
break readLoop;
}
}
this.trailerRecord = currLine.trim();
System.out.println("From setTrailer(): " + this.trailerRecord);
fReader.close();
bReader.close();
}
As your code now throws a checked Exception, you will need to update your Junit method slightly, to catch the checked exceptions
#Test(expected=NullPointerException.class)
public void nullSetTrailer() throws Exception {
ERParser recCurrParse = new ERParser();
recCurrParse.setTrailer(null);
}
We can argue about whether or not this catch block means the exception is handled. I would argue that merely printing the stack trace is not handling anything. It might be better to add a throws clause to the method signature and let clients decide what to do with exceptions.
If the method is written that way, it's up to you to test it as-written. You wouldn't have a choice if this was a 3rd party library.
Write the test that throws the exception; succes means trailerRecord is set to null.
Your code has another flaw: close the streams in a finally block. You risk not closing the input stream properly as written.
In your test case are expecting a NullPointerException class. If you catch it, the caller class will not get it. Hence, either you can remove the try/catch blocks or you can rethrow the exception after printing stacktrace :
catch (NullPointerException exception) {
exception.printStackTrace();
throw new NullPointerException();
}

Return in a 'finally' statement

I'm trying to read ObjectOutputStream from a file and convert it to an arraylist.
This whole thing is happening inside a method which should read the file and return the array list:
public static List<Building> readFromDatabase(){
String fileName="database.txt";
FileInputStream fileIStream=null;
ObjectInputStream in=null;
List<Building> buildingsArr=null;
try
{
fileIStream = new FileInputStream(fileName);
in = new ObjectInputStream(fileIStream);
buildingsArr=(ArrayList<Building>)in.readObject();
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
Console.printPrompt("ArrayList<Building> class not found.");
e.printStackTrace();
}
finally{
Console.printPrompt("Closing file...");
close(in);
close(fileIStream);
return buildingsArr;
}
}
Java tells me that this is dangerous.
What are the alternatives?
I can't put the return in the "try" block because it won't do it / it won't close files in the "finally" block.
I need to both make sure files will be closed, and return the array list I created as well.
Any ideas?
I can't put the return in the "try" block because it won't do it / it
won't close files in the "finally" block.
Wrong, finally block would still execute if you put return in try block. Thus you can return in your try block.
try
{
//your code
return buildingsArr;
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
Console.printPrompt("ArrayList<Building> class not found.");
e.printStackTrace();
}
finally{
Console.printPrompt("Closing file...");
close(in);
close(fileIStream);
}
I would suggest starting to use Java 7, and the try with resources clause. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ex:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
You must either throw an Exception or return a value:
All you need to prove this is comment out the return "File Not Found" after the finally block and see that it won't compile.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ReturnFinallyExample
{
public static void main(final String[] args)
{
returnFinally();
}
private static String returnFinally()
{
try
{
final File f = new File("that_does_not_exist!");
final FileInputStream fis = new FileInputStream(f);
return "File Found!";
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
System.out.println("finally!");
}
return "File Not Found!";
}
}
You must have the return after the finally or you have to either:
declare the method to throws FileNotFoundExceptoin and re-throw the FileNotException out.
or
wrap the FileNotFoundException with throw new RuntimeException(e)

Categories

Resources