Why is the catch statement being ignored here? - java

This is practice code from a book and i'm learning about try/catch statements.
The first method shown calls for the load method an retrieves two images. The error in this code is that the name of the first img in the resources file is called "welcome.png" but as you can see, it says "welcomee.png"(extra e at the end of welcome). When I run the code, it doesn't print out the code in the catch statement. It does show the stacktrace(because it does that regardless), but it doesn't print out " Error while reading: filename". Why is this?
public class Resources {
public static BufferedImage welcome, iconimage;
public static void load() {
welcome = loadImage("welcomee.png");
iconimage = loadImage("iconimage.png");
}
private static AudioClip loadSound(String filename) {
URL fileURL = Resources.class.getResource("/resources/" + filename);
return Applet.newAudioClip(fileURL);
}
private static BufferedImage loadImage(String filename) {
BufferedImage img = null;
try {
img = ImageIO.read(Resources.class.getResourceAsStream("/resources/" + filename));
} catch (IOException e) {
System.out.println("Error while reading: " + filename);
e.printStackTrace();
}
return img;
}
}

You're catching an IOException, but Class.getResourceAsStream doesn't throw an IOException if the resource is not found; it just returns null. And ImageIO.read doesn't throw an IOException if the argument is null; it throws an IllegalArgumentException.
I suggest you refactor the code this way:
private static BufferedImage loadImage(String filename) {
try (InputStream in = Resources.class.getResourceAsStream("/resources/" + filename)) {
if (in == null) throw new IOException("Resource not found");
return ImageIO.read(in);
} catch (IOException e) {
System.out.println("Error while reading: " + filename);
e.printStackTrace();
return null;
}
}
This will ensure you handle the error, and the use of the try-with-resources statement makes sure the stream is always closed after use (which ImageIO.read does not do). The direct return statement is perhaps a bit cleaner as it obviates the need for the img variable.
You should also consider, rather than returning null on error, to throw (or rethrow) some exception to the caller, such as an UncheckedIOException, since a null return value will only cause errors elsewhere once you try to make use of it, and an exception thrown directly from the point of the problem will be more meaningful than some NullPointerException thrown later.

You can only catch IOException. If you want to catch all type of exception, use catch(Exception e).

Try using catch(Exception e){...} instead. It is a way to check if it is just another exception or if it is not an exception, but a run-time error.
You can specify certain catch statements with certain exceptions later in the development process, if needed.

Related

Java Serialization: close streams in try or in a finally block?

I was looking at Java Serialization articles and stumbled a number of times across examples where the streams are closed in the try block instead of in a finally block. Can someone explain to me why is that?
Example:
import java.io.*;
public class DeserializeDemo {
public static void main(String [] args) {
Employee e = null;
try {
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
in.close();
fileIn.close();
} catch(IOException i) {
i.printStackTrace();
return;
} catch(ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
Source: http://www.tutorialspoint.com/java/java_serialization.htm
The try-with-resources Statement
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, 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).
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
Source =>http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
From documentation:
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs.
The runtime system always executes the statements within the finally block regardless of what happens within the try block. So it's the perfect place to perform cleanup.
So it means if you have some connection, stream or some other resources opened you have to be sure that they will be closed after your code block will be executed.
To avoid such ugly blocks you can use utility methods:
public void close(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
// handle block
}
}
}
Since Java 8 (but it is not required) you can provide your own Exception handler with closing resource:
public void close(Closeable closeable, Consumer<? extends Throwable> handler) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
handler.accept(ex);
}
}
}
Also, just for knowledge, there are two cases when finally block is not called. It means that in most cases it will be called.
If you are Java 7 or aboveā€¦
Don't close in finally block
The close method can throw an IOException and FileInputStream/ObjectInputStream can be null. When you use .close in finally, you must check null and try/catch again.
Use "try-with-resources Statement" instead
Using try-with-resources your code looks like this:
try(
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)
) {
e = (Employee) in.readObject();
// in.close();
// fileIn.close();
}
The try-with-resources syntax guarantees the resources implementing AutoCloseable interface will be closed automatically. So you don't need to call a close method on your code.
You should close connection in finally. As finally always going to execute whether it goes in try or catch.
Also we need to close every connection once it created.
try{
// statements
}catch (){
// statements
}
finally {
in.close();
fileIn.close();
}
I was looking at Java Serialization articles and stumbled a number of times across examples where the streams are closed in the try block instead of in a finally block.
Examples that do it that way are poor examples. While closing a stream within a try block will work for simple one-shot examples, doing this in a case where the code might be executed multiple times is liable to lead to resource leaks.
The other Answers to this Question do a good job of explaining the right way(s) to close streams.
Can someone explain to me why is that?
It comes down to poor quality control on the tutorial sites; i.e. inadequate code reviewing.
The accepted answer certainly has a bug.
The close method can throw an IOException too. If this happens when
in.close is called, the exception prevents fileIn.close from getting
called, and the fileIn stream remains open.
It can implemented as below when multiple streams are involved:
} finally {
if ( in != null) {
try { in .close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
if (fileIn != null) {
try {
fileIn.close();
} catch (IOException ex) {
// Again, there is nothing we can do if close fails
}
}
}
Or, take advantage of Closeable Interface
} finally {
closeResource(in);
closeResource(fileIn);
}
Method:
private static void closeResource(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// There is nothing we can do if close fails
}
}
}
You should close in finally block.
It's a bad habit to close in try block.
try {
e = (Employee) in.readObject(); //Possibility of exception
} catch(IOException i) {
} catch(ClassNotFoundException c) {
} finally {
in.close();
fileIn.close();
}
When someone is writing a code by knowing it will throw an exception,he/she has to close the opened resources
You should always close in a finally block.
However, you can use try with resources.
Here's the link: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}

Java ObjectInputStream not being instantiated

I am creating a kind of messenger program, where clients communicate with the server etc.
The problem I have stumbled upon is when trying to create the ObjectInputStream and the ObjectOutputStream. Here is the method that instantiated the object streams:
private void initializeStreams() {
try {
input = new ObjectInputStream(socket.getInputStream());
if (input != null) {
System.out.println("ObjectInputStream successfully initiated");
} else {
System.out.println("ObjectInputStream is null but did not return an exception when being instantiated");
}
} catch (IOException ioe) {
System.out.println("Could not initialize ObjectInputStream: " + ioe.getMessage());
}
try {
output = new ObjectOutputStream(socket.getOutputStream());
if (output != null) {
System.out.println("ObjectOutputStream successfully initiated");
} else {
System.out.println("ObjectOutputStream is null but did not return an exception when being instantiated");
}
} catch (IOException ioe) {
System.out.println("Could not initialize ObjectOutputStream: " + ioe.getMessage());
}
}`
The problem within this method is that NONE of the System.out.println() methods are getting called, even though, at least to my knowledge, one for each of the streams should be getting called. For example, when instantiating the ObjectInputStream, it should either throw an Exception (which it apparently does not because the System.out.println() is not getting called), returning null (which also does not seem to be the case because the System.out.println() is not getting called) or successfully create the ObjectInputStream object, which it does not because the System.out.println() is not getting called. Why does it not run into any of these situations? Am I missing another situation that might occur?
P.S. Yes, the initializeStreams() method is being called from the program, I just checked it putting a System.out.println() at the very first line of the method.
Thank you
Try to write something on the console in the finally-cluster.
What possibly could be is that an exception is thrown, which doesn't get catched.
But you would see that...wouldn't you.
My first tip: Debug your program, that's what often helped me.
But you could also try this:
private void initializeStreams() {
input = null;
output = null;
try {
input = new ObjectInputStream(socket.getInputStream());
}
} catch (IOException ioe) {
System.out.println("Could not initialize ObjectInputStream: " + ioe.getMessage());
}
//just copied the if outside of the try-catch-cluster
if (input != null) {
System.out.println("ObjectInputStream successfully initiated");
} else {
System.out.println("ObjectInputStream is null but did not return an exception when being instantiated");
try {
output = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException ioe) {
System.out.println("Could not initialize ObjectOutputStream: " + ioe.getMessage());
}
if (output != null) {
System.out.println("ObjectOutputStream successfully initiated");
} else {
System.out.println("ObjectOutputStream is null but did not return an exception when being instantiated");
}
}`
Thats one thing I would try in order to find out what or where the problem is.
Even if it doesn't make that much sense ;)
Well, you catch only IOException. There might be RuntimeException for instance in your code. You won't get to your catch block in this case.
Change IOException to Exception and you will see the reason.
new ObjectInputStream() can throw exceptions other than IOException, but your try-catch only captures IOException. What happens if the exception thrown is one of the other types?
Replace IOException with the Exception class which is the parent of all exception classes.Whatever may be the exception,it will surely get caught using Exception class in catch block.
So replace catch (IOException ioe) this with catch (Exception ioe) everywhere in your code.Then u may find where is the exception coming from.

how to get the filename of a thrown IOException in java?

I have a try block which handles quite a few file opening/closing/reading/writing (more than one file).
It looks like:
try {
// commands
}
catch (IOException e) {
System.err.println("Error: " + e);
}
The main problem is that e.toString() does not contain information about the filename for which the exception was thrown, if there is an error.
I could check each read/write/open/close operation separately, and then know which file the error happens with, but that seems to defeat the purpose of having the elegant try-catch structure.
Is there any other way out? I just want to be able to print the file name for which e had the error in the try block.
EDIT: Maybe I should make it clear in which scenario this issue arises. This happens when I parse command-line arguments, input/output files, etc. I pass the file names to various functions and methods that can return with an IO error. It seems reasonable to require that I would have a generic way of handling any file problem by printing the error and the filename that had that error. I understand that IOException is more broad than handling IO with files, but surely it makes sense, given that IOException is a specialized exception class, to have a method that returns the IO source for which the error occurred.
You don't - as you know, IOException doesn't have information about the File that generated the exception. It's purpose it too general. If you roll your own, you can capture relevant information and catch your own exception instead.
In the various methods that handle your input, wrap the relevant section in try/catch blocks, catch the IOException, and throw your own with the additional data.
Here is a complete program that demonstrates the basic idea.
class FooException extends Exception {
private static final long serialVersionUID = 2816777468035627105L;
private final String filename;
private final Throwable cause;
public FooException(String filename) {
this(filename, null);
}
public FooException(String filename, Throwable cause) {
this.filename = filename;
this.cause = cause;
}
#Override
public String getMessage() {
return "Error reading file";
}
#Override
public Throwable getCause() {
return cause;
}
public String getFilename() {
return filename;
}
}
public class Soj25375647 {
public static void main(String[] args) {
try {
throwsAnException();
// Do other things that might throw my exception
} catch (FooException e) {
System.err.printf("File: %s, error: %s, caused by %s%n", e.getFilename(), e, e.getCause());
}
}
public static void throwsAnException() throws FooException {
try {
int x = 2 / 0;
} catch (ArithmeticException e) {
throw new FooException("bob.file", e);
}
}
}
Output
File: bob.file, error: soj25375647.FooException: Error reading file, caused by java.lang.ArithmeticException: / by zero
See Also Exception-Handling Antipatterns.
I think I see what's happening here. You probably have something like this:
try {
for (int i = 0; i < something; i++) {
File f = getSomeFile(i);
// Operations that might throw an IOException
}
}
catch (IOException e) {
// handle
}
This is not a good idea; as you say you don't know the file that caused the error. Instead try something like this:
for (int i = 0; i < something; i++) {
File f = getSomeFile(i);
try {
// Operations that might throw an IOException
}
catch (IOException e) {
// handle
break;
}
}
This way, you still have f around when the error is thrown, but it also breaks out of the loop on an error just like the original code. Hope this helps!

Is attached code safe from open file leak

Assuming Java6, is this code safe from file descriptor leak:
{
InputStream in = fileObject.getReadStream();
// fileObject cleans it's internal state in case it throws exception
try {
// do whatever, possibly throwing exception
} finally {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem
}
}
}
Edit: To make question seem less obvious, to state it other way, is above code equal to this longer code:
{
InputStream in = null;
try {
in = fileObject.getReadStream();
// fileObject cleans it's internal state in case it throws exception
// do whatever, possibly throwing exception
} finally {
if (in != null) {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem
}
}
}
}
That is, does it matter whether a call to a method which returns opened stream or throws exception is immediately before try, or inside the try block?
Yes, fine. Does not even merit an answer. A variant (I less use) is:
InputStream in = null;
try {
in = fileObject.getReadStream();
// do whatever, possibly throwing exception
} finally {
if (in != null) {
try {
in.close();
} catch (Exception ex) {
// failure to close input stream is no problem if everything else was ok
}
}
}
I'm a student not very familiar with Java, but I wish I can help you a litltle.
I think that the piece of code can't keep you from the problem of file descriptor leak. Though you have let a try clouse wurround the in.close methord, but that won't help if
the in.close method throws some exceptions.

File I/O without clutering of exceptions

What is the best way to use e.g. FileOutputStream without cluttering my code.
Example the following code:
What I need to do is:
FileOutputStream fOut = new FileOutputStream(file);
while(!Thread.currentThread().isInterrupted()){
fOut.write(data);
//other code
}
But if I add the exception handling is all messy. I thought for example something like the following:
private FileOutputStream openStream(String file){
try{
return new FileOutputStream(file);
}
catch(FileNotFoundException e){
return null;
}
}
But then it makes the logic weird. I mean when I close the stream, e.g. in another method etc.
What is the way to get clearer code
What about a wrapper like this:
public class StreamWrapper {
private FileOutputStream fileOutputStream;
public FileOutputStream open(String file) {
try {
fileOutputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// Define action
}
return fileOutputStream;
}
public void close() {
try {
fileOutputStream.close();
} catch (IOException e) {
// Define action
}
}
}
And use it like:
StreamWrapper wrapper = new StreamWrapper();
FileOutputStream fOut = wrapper.open("file");
// something
wrapper.close();
There is no direct way of avoiding checked exceptions in Java, unfortunately. Few work-arounds:
Use different language
Both groovy and scala treat checked exceptions as unchecked.
try-with-resources idiom in Java 7
It doesn't really help with catch, but substantially reduces the amount of finally blocks surrounding close().
Throwables.propagate(Throwable) in Guava
Avoid returning null and swallowing exceptions:
private FileOutputStream openStream(String file){
try{
return new FileOutputStream(file);
}
catch(FileNotFoundException e){
return Throwables.propagate(e);
}
}
See also: Long try statements.
Applicative exceptions are there for a reason (and nobody likes RT exceptions...)
You could use a factory to hide the exception handling, but the "catch" clause would have to be in your code somewhere.
One idea is to implement your own wrapper to FileOutputStream that will swallow the exception during instantiation, but since the exception is thrown at the constructor you'll end up in an unstable state if the file indeed doesn't exists.
public class MyFileOutputStream {
private FileOutputStream fis;
public MyFileOutputStream(File file){
try{
fis = new FileOutputStream(file);
} catch (FileNotFoundException e){
fis = null;
}
}
public boolean isOpened(){
return fis!=null;
}
public void write(Byte b) throws IOException {
fis.write(b);
}
}
There are couple options that you can do:
First of all you sample code is good only thing is "in case of a exception you are returning a null object". So rather than returning a FileOutputStream object you can actually send a boolean and store the FileOutputStream object as a class variable.
So if other program want to access that can make this call and the caller will get True/False depending on whether it could create a object successfully or not, and if that is True then can use the class variable for the FileOutputStream object. I am attaching some sample code with that:
FileOutputStream fOutSt;
private boolean isOpenStream(String file){
try{
fOutSt = new FileOutputStream(file);
return true;
}
catch(FileNotFoundException e){
return false;
}
}
Then the caller can make call like:
if(isOpenStream) {
obj.GetfOutSt;
}

Categories

Resources