try-with-resources or close() dilemma - java

I have a function that can throw IOException, so I don't catch the exception internally. however I've some resources to close. Is it correct to do in that way, using try-with-resource (without any catch block):
public void workOnFiles() throws IOException {
try(FileInputStream fis = new FileInputStream("bau.txt");) {
// Do some stuff
}
}
Or I should do something like that:
public void workOnFiles() throws IOException {
FileInputStream fis = new FileInputStream("bau.txt");
// Do some stuff
fis.close();
}

In 2nd one, if the exception is thrown, your fis won't be closed. An option is to enclose the statement that can throw th exception in a try block, and close the fis in a finally block.
But, since you are already on Java 7, you should use try-with-resource.

If you are keen on using the second method , then close the resource in finally block.
public void workOnFiles() throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream("bau.txt");
// Do some stuff
}
finally {
try {
fis.close();
}
catch(Exception e) {
//logger.error(e);
// e.printStackTrace();
}
}

try-with-resources always closes(Closeable resources) the resource whether exception raises or not(Work only java7 onwards).
Where as your second code do not close resource if exception raises.
So you can use try-with-resources if you are using java7 or else edit your code with try and finally block.
finally block guarantees execution irrespective of exception raises or not

Related

When should I use Throwable.getSuppressed() and addSuppressed() in my code?

I'm practicing with try-with-resources for my methods to understand that.
This is my example method.
public void a(File f) throws FileNotFoundException, IOException {
try (FileInputStream fis = new FileInputStream(f)) { // suppose FileNotFoundException occurs here
byte[] buffer = new byte[7];
fis.read(buffer); // suppose IOException occurs here
}
}
Now suppose that an exception occurs as FileNotFoundException for the new FileInputStream() and a IOException on the fis.read().
this is the use of my method in another class.
try {
a(new File(""));
} catch (IOException ex) {
ex.printStackTrace();
Throwable[] suppressedExceptions = ex.getSuppressed();
if (suppressedExceptions.length > 0)
for (Throwable exception : suppressedExceptions)
System.err.println(exception.toString());
}
As in the previous code. Should I use the getSuppressed() method always when I use try-with-resources?
And when, where and how should I use addSuppressed() method?

Try-Catch-Finally Block

i already know that the traditional Try block in java must have at least catch block or finally block (both or either), and i already know that checked exceptions must be handled or declared.
but i am wondering why it won't compile although i have used correct try block syntax
i have this piece of code here , in the main method i used Try with finally block but i am wondering why it won't compile
Here is my code:
import java.io.IOException;
import java.net.Socket;
public class ExHandling {
public void connect() throws IOException
{
Socket s = new Socket();
try
{
s.getInputStream();
}
catch(IOException e )
{
e.printStackTrace();
}
finally
{
s.close();
}
}
public static void main(String []args)
{
ExHandling ex = new ExHandling();
try
{
ex.connect();
}
finally
{
System.out.println("Finally");
}
}
}
Any Help Please
Remove the throws clause from your connect() method. It already catches the IOException. If you declare your method as throwing a checked exception it must be caught upon calling.
Update: since Socket#close() can itself throw an exception, you need to decide what do you want to do about it. Exception handling is hard because people tend to only think about the happiest path a program can take.
If you don't want to catch the exception explicitly in the main() method, you have only one choice: wrap the call to s.close() (and every other method that can throw a checked exception) into its' own try-catch block and remove the throws clause:
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
But you should probably think—"what should I do when it fails?"—each time you're dealing with code that might throw.
Either catch the thrown IOException or throw it and let JVM handle the same.
IOException checked exception so you need catch or add an exception to a signature method. final just guarantee whatever happens final block will be executed.
Declare your main method to catch the IOException. If you do so, when the exception is thrown in your connect() method, it will be propagated to the main method and your finally block will be executed. If that is what you wanted.
finally itself cannot handle any exception. So when using try{} finally then the code inside try should either not be raising any exception or your method must be throwing the exception.
It won't compile because just as you indicated, the s.close() in your finally block can throw an IOException and you chose to handle that checked exception by specifying the "throws IOException" clause. Because of that choice, the calling method must handle that checked exception by either catching it or also specifying it will throw the exception.
It is unclear what results you desire other than it must compile, so here are three options:
1) Wrap s.close with it's own try/catch and remove the throws clause.
2) Move "ExHandling ex" definition inside the caller's try/catch.
3) Add a throws clause to the caller (and remove the try/finally if desired). RECOMMENDED
CAUTION: You really don't want to catch an exception and do "e.printStackTrace();". All this does is mask issues in your logic. You should only catch an exception if you plan to handle it in some manner; otherwise, you should allow the exception to propagate up the chain of callers. Thus, only use options 1 & 2 if you really wish to do something in all the catch clauses.
Option 1: Wrap s.close with it's own try/catch and remove the throws clause.
public void connect() {
Socket s = new Socket();
try {
s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExHandling ex = new ExHandling();
try {
ex.connect();
}
finally {
System.out.println("Finally");
}
}
Option 2: Move "ExHandling ex" definition inside the caller's try/catch. In this case I would recommend using try with resources for the socket.
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) {
try {
ExHandling ex = new ExHandling();
ex.connect();
} catch (IOException e) {
e.printStackTrace();
}
finally {
System.out.println("Finally");
}
}
Option 3: Add a throws clause to the caller (and remove the try/finally if desired). RECOMMENDED
public void connect() throws IOException {
Socket s = new Socket();
s.getInputStream();
s.close();
}
public static void main(String[] args) throws IOException {
ExHandling ex = new ExHandling();
ex.connect();
System.out.println("Finally");
}

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();
}
}

Exception coming out of close() in try-with-resource [duplicate]

This question already has answers here:
Close resource quietly using try-with-resources
(4 answers)
Closed 1 year ago.
I was reading about the try-with-resource in JDK7 and while I was thinking of upgrading my application to run with JDK7 I faced this problem..
When using a BufferedReader for example the write throws IOException and the close throws IOException.. in the catch block I am concerned in the IOException thrown by the write.. but I wouldn't care much about the one thrown by the close..
Same problem with database connections.. and any other resource..
As an example I've created an auto closeable resource:
public class AutoCloseableExample implements AutoCloseable {
public AutoCloseableExample() throws IOException{
throw new IOException();
}
#Override
public void close() throws IOException {
throw new IOException("An Exception During Close");
}
}
Now when using it:
public class AutoCloseTest {
public static void main(String[] args) throws Exception {
try (AutoCloseableExample example = new AutoCloseableExample()) {
System.out.println(example);
throw new IOException("An Exception During Read");
} catch (Exception x) {
System.out.println(x.getMessage());
}
}
}
how can I distinguish between such exceptions without having to create wrappers for classes such as BufferedReader?
Most of cases I put the resource close in a try/catch inside the finally block without caring much about handling it.
Lets consider the class:
public class Resource implements AutoCloseable {
public Resource() throws Exception {
throw new Exception("Exception from constructor");
}
public void doSomething() throws Exception {
throw new Exception("Exception from method");
}
#Override
public void close() throws Exception {
throw new Exception("Exception from closeable");
}
}
and the try-with-resource block:
try(Resource r = new Resource()) {
r.doSomething();
} catch (Exception ex) {
ex.printStackTrace();
}
1. All 3 throw statements enabled.
Message "Exception from constructor" will printed and the exception thrown by constructor will be suppressed, that means you can't catch it.
2. The throw in constructor is removed.
Now the stack trace will print "Exception from method" and "Suppressed: Exception from closeable" below. Here you also can't catch the suppressed exception thrown by close method, but you will be nofitied about the suppressed exception.
3. Throws from constructor and method are removed.
As you have probably already guessed the "Exception from closeable" will be printed.
Important tip: In all of above situations you are actually catching all exceptions, no matter where they were throwed. So if you use try-with-resource block you don't need to wrap the block with another try-catch, the extra block is simply useless.
Hope it helps :)
I would suggest using a flag as in the following example:
static String getData() throws IOException {
boolean isTryCompleted = false;
String theData = null;
try (MyResource br = new MyResource();) {
theData = br.getData();
isTryCompleted = true;
} catch(IOException e) {
if (!isTryCompleted )
throw e;
// else it's a close exception and it can be ignored
}
return theData;
}
source:Close resource quietly using try-with-resources

do I need to surround fileInputStream.close with a try/catch/finally block? How is it done?

I have the following Java Class that does one thing, fires out values from config.properties.
When it comes time to close the fileInputStream, I think I read on Wikipedia that it is good to have it in a finally block. Because it honestly works just fine in try/catch block.
Can you show me correction to get fileInputStream.close() in a finally section?
ConfigProperties.java
package base;
import java.io.FileInputStream;
import java.util.Properties;
public class ConfigProperties {
public FileInputStream fileInputStream;
public String property;
public String getConfigProperties(String strProperty) {
Properties configProperties = new Properties();
try {
fileInputStream = new FileInputStream("resources/config.properties");
configProperties.load(fileInputStream);
property = configProperties.getProperty(strProperty);
System.out.println("getConfigProperties(" + strProperty + ")");
// use a finally block to close your Stream.
// If an exception occurs, do you want the application to shut down?
} catch (Exception ex) {
// TODO
System.out.println("Exception: " + ex);
}
finally {
fileInputStream.close();
}
return property;
}
}
Is the solution only to do as Eclipse suggests and do this in the finally block?
finally {
try {
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Yes, that is the common pre-Java 7 solution. However, with the introduction of Java 7, there are now try-with-resource statements which will automatically close any declared resources when the try block exits:
try (FileInputStream fileIn = ...) {
// do something
} // fileIn is closed
catch (IOException e) {
//handle exception
}
The standard approach is:
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(...);
// do something with the inputstream
} catch (IOException e) {
// handle an exception
} finally { // finally blocks are guaranteed to be executed
// close() can throw an IOException too, so we got to wrap that too
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
// handle an exception, or often we just ignore it
}
}
Because FileInputStream.close() throws an IOException, and the finally{} block doesn't catch exceptions. So you need to either catch it or declare it in order to compile. Eclipse's suggestion is fine; catch the IOException inside the finally{} block.
It's a good habit to close streams because what it does in background it's called buffering, meaning that it does not free the internal buffer and does not free the file descriptor.

Categories

Resources