Java AutoClosable behaviour in function - java

I have a sample code here. Will the FileInputStream created by the function, get automatically closed when the code exists the try/catch block of parentFunction ?
Or does it need to be explicitly closed in the someOtherFunction() itself ?
private void parentFunction() {
try {
someOtherFunction();
} catch (Exception ex) {
// do something here
}
}
private void someOtherFunction() {
FileInputStream stream = new FileInputStream(currentFile.toFile());
// do something with the stream.
// return, without closing the stream here
return ;
}

You have to use the resource with try-with-resource block.
Please read docs for AutoCloseable interface: https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html
method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header.

It needs to either be explicitly closed in the someOtherFunction() method, or used in a try-with-resources block:
private void someOtherFunction() {
try (FileInputStream stream = new FileInputStream(currentFile.toFile())) {
// do something with the stream.
} // the stream is auto-closed
}

Related

automatically closing a resource passed as an argument

If I want to automatically close a resource passed as an argument, is there a more elegant solution than this?
void doSomething(OutputStream out) {
try (OutputStream closeable = out) {
// do something with the OutputStream
}
}
Ideally, I'd like to have this resource closed automatically, without declaring another variable closeable that refers to the same object as out.
Aside
I realise that closing out within doSomething is considered a bad practice
With Java 9 and higher, you can do
void doSomething(OutputStream out) {
try (out) {
// do something with the OutputStream
}
}
This is only allowed if out is final or effectively final. See also the Java Language Specification version 10 14.20.3. try-with-resources.
I use Java 8 and it does not support Resource Reference. What about create universal method that accepts Closable and payload:
public static <T extends Closeable> void doAndClose(T out, Consumer<T> payload) throws Exception {
try {
payload.accept(out);
} finally {
out.close();
}
}
Client code could look like this:
OutputStream out = null;
doAndClose(out, os -> {
// do something with the OutputStream
});
InputStream in = null;
doAndClose(in, is -> {
// do something with the InputStream
});
void doSomething(OutputStream out) {
try {
// do something with the OutputStream
}
finally {
org.apache.commons.io.IOUtils.closeQuietly(out);
}
}

use try-with-resources to close a Closeable

I have a Map<Key, Closeable> and if a key is removed from the map I want to close the Closeable. Normally I have something like:
Closeable c = map.remove(key);
c.close();
My Eclipse warns me "Resource 'c' should be managed by try-with-resource", so is it better just to write the following?
try (Closeable c = map.remove(key)) {}
In my special implementation I have a subclass of Closeable, where close() does not throw an IOException, so no exception handling is needed.
The point of try-with-resources is that:
The opening of the Closeable resource is done in the try statement
The use of the resource is inside the try statement's block
close() is called for you automatically.
So your suggested code:
try(Closeable c = map.remove(key)) {}
... doesn't satisfy the point of try-with-resource, since you're not using the resource inside the block. Presumably your Closeable is already open before this statement.
I'm guessing that you have some code whereby a bunch of resources are opened, work is done, then they are all closed by working through the map.
This is OK, and sometimes unavoidable. But it's cleaner, where possible, to have open() and close() in the same method, with the close() in a finally block, so that you can see at a glance that every open() has a corresponding close() and you can be sure that the close() is always called.
MyCloseable c = MyCloseable.open(...);
try{
// do stuff with c;
} finally {
try {
c.close();
} catch (IOException e) {
// ...
}
}
Once you've achieved that, try-with-resources just makes things neater:
try(MyCloseable c = MyCloseable.open(...)) {
// do stuff with c;
}
If your requirements mean you can't get open and close into the same methods, then just stick with an explicit close() and ignore the warning.
I would just ignore this warning, If you are managing close operation on your own, then just call close(). Empty try-with-resource looks weird.
Consider to extend Map so close operation will be performed automatically on remove:
public class CloseableMap<K,V extends Closeable> extends HashMap<K,V> {
#Override
public R remove(K key) {
V resource = super.remove(key);
if (resource != null) {
resource.close();
}
return resource;
}
}

Will this release my resources after being used?

Will this release my resources after being used?
InputStream inputStream;
try (InputStream unverifiedStream = connection.getInputStream()){
inputStream = unverifiedStream;
} catch (Exception e) {
e.printStackTrace();
}
//and use stream here to do other stuff with other streams
That will release your resources (close the stream) and leave you talking to a closed stream.
The assignment to inputStream does not copy the stream object. It copies the reference to the stream object. You now have two different ways to talk to the same object.
Since you are using a try-with-resource statement, and if by "released" you mean "closed" then yes.
Any instance implementing AutoCloseable opened in a try-with-resources statement is .close()d right before catch, so in your case unverifiedStream will be closed before you catch Exception.
It should also be noted that Closeable extends AutoCloseable, so all existing classes implementing Closeable will "magically" work within a try-with-resources statement.
Sample code:
public final class AutoCloseableExample
{
private static final class Foo
implements AutoCloseable
{
#Override
public void close()
throws IOException
{
System.out.println("foo");
throw new IOException();
}
}
public static void main(final String... args)
{
try (
final Foo foo = new Foo();
) {
System.out.println("try block");
} catch (IOException ignored) {
System.out.println("exception!");
} finally {
System.out.println("finally block");
}
}
}
Output:
try block
foo
exception!
finally block
Side note: you should not catch Exception since this also catches all unchecked exceptions (ie, RuntimeException and derivates). Catch more specific exceptions instead.
I haven't tried this, but I don't think it will compile if you try to use inputStream after the try-catch block, because inputStream won't be initialized if connection.getInputStream() throws an exception. Your catch block should assign a value or introduce a different flow of control to take care of that possibility.
If the try block completes normally, inputStream will refer to a closed stream outside the try-catch block, and most implementations will throw an exception on any operation you attempt on the stream.

implements Closeable or implements AutoCloseable

I'm in the process of learning Java and I cannot find any good explanation on the implements Closeable and the implements AutoCloseable interfaces.
When I implemented an interface Closeable, my Eclipse IDE created a method public void close() throws IOException.
I can close the stream using pw.close(); without the interface. But, I cannot understand how I can implement theclose() method using the interface. And, what is the purpose of this interface?
Also I would like to know: how can I check if IOstream was really closed?
I was using the basic code below
import java.io.*;
public class IOtest implements AutoCloseable {
public static void main(String[] args) throws IOException {
File file = new File("C:\\test.txt");
PrintWriter pw = new PrintWriter(file);
System.out.println("file has been created");
pw.println("file has been created");
}
#Override
public void close() throws IOException {
}
AutoCloseable (introduced in Java 7) makes it possible to use the try-with-resources idiom:
public class MyResource implements AutoCloseable {
public void close() throws Exception {
System.out.println("Closing!");
}
}
Now you can say:
try (MyResource res = new MyResource()) {
// use resource here
}
and JVM will call close() automatically for you.
Closeable is an older interface. For some reason To preserve backward compatibility, language designers decided to create a separate one. This allows not only all Closeable classes (like streams throwing IOException) to be used in try-with-resources, but also allows throwing more general checked exceptions from close().
When in doubt, use AutoCloseable, users of your class will be grateful.
Closeable extends AutoCloseable, and is specifically dedicated to IO streams: it throws IOException instead of Exception, and is idempotent, whereas AutoCloseable doesn't provide this guarantee.
This is all explained in the javadoc of both interfaces.
Implementing AutoCloseable (or Closeable) allows a class to be used as a resource of the try-with-resources construct introduced in Java 7, which allows closing such resources automatically at the end of a block, without having to add a finally block which closes the resource explicitly.
Your class doesn't represent a closeable resource, and there's absolutely no point in implementing this interface: an IOTest can't be closed. It shouldn't even be possible to instantiate it, since it doesn't have any instance method. Remember that implementing an interface means that there is a is-a relationship between the class and the interface. You have no such relationship here.
It seems to me that you are not very familiar with interfaces. In the code you have posted, you don't need to implement AutoCloseable.
You only have to (or should) implement Closeable or AutoCloseable if you are about to implement your own PrintWriter, which handles files or any other resources which needs to be closed.
In your implementation, it is enough to call pw.close(). You should do this in a finally block:
PrintWriter pw = null;
try {
File file = new File("C:\\test.txt");
pw = new PrintWriter(file);
} catch (IOException e) {
System.out.println("bad things happen");
} finally {
if (pw != null) {
try {
pw.close();
} catch (IOException e) {
}
}
}
The code above is Java 6 related. In Java 7 this can be done more elegantly (see this answer).
Here is the small example
public class TryWithResource {
public static void main(String[] args) {
try (TestMe r = new TestMe()) {
r.generalTest();
} catch(Exception e) {
System.out.println("From Exception Block");
} finally {
System.out.println("From Final Block");
}
}
}
public class TestMe implements AutoCloseable {
#Override
public void close() throws Exception {
System.out.println(" From Close - AutoCloseable ");
}
public void generalTest() {
System.out.println(" GeneralTest ");
}
}
Here is the output:
GeneralTest
From Close - AutoCloseable
From Final Block
Recently I have read a Java SE 8 Programmer Guide ii Book.
I found something about the difference between AutoCloseable vs Closeable.
The AutoCloseable interface was introduced in Java 7. Before that, another interface
existed called Closeable. It was similar to what the language designers wanted, with the
following exceptions:
Closeable restricts the type of exception thrown to IOException.
Closeable requires implementations to be idempotent.
The language designers emphasize backward compatibility. Since changing the existing
interface was undesirable, they made a new one called AutoCloseable. This new
interface is less strict than Closeable. Since Closeable meets the requirements for
AutoCloseable, it started implementing AutoCloseable when the latter was introduced.
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();
}
}
Please refer to the docs.

BufferedWriter - Stream closed prematurely during program execution

I am defining a buffered writer in a class I am developing, but having problems with it.
In the class constructor I am defining:
public class RestHandler {
public static BufferedWriter rest_logger;
public RestHandler(parsedXMLConfigData _config, BufferedWriter writer) {
rest_logger = writer;
try {
rest_logger.write("RestHandler instance finished init and ready to receive calls!" + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This works and prints the text to my file. But when I try to use the same rest_logger in another one of my class methods:
#POST
#Path("{subResources: [a-zA-Z0-9_/]+}")
public void postHandler
(
#Context final UriInfo uriInfo,
#PathParam("subResources") String subResources) {
try {
rest_logger.write("TEXT...");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It gives me a stream closed exception! I should mention that I use this to close the stream:
protected void finalize() throws Throwable {
rest_logger.close();
}
There are several problems with your code:
the rest_logger variable should not be static
you shouldn't initialize it to a new BufferedWriter just to discard it afterwards and reinitialize it with the writer argument (that you have no control on)
you shouldn't ignore exceptions. If you don't know what to do with them, make your methods throw IOException and let the caller decide what to do
you should not use finalizers
you should not close a writer that you have not created. Let the opener of the writer close it.
Other than that, and since your code doesn't make much sense, it's hard to understand what the code is supposed to do.
Removing the exception handlers for clarity, your code does:
rest_logger = new BufferedWriter(new FileWriter("rest_logger.txt"));
rest_logger = writer;
You're throwing away that new BufferedWriter immediately there. It does not make much sense. rest_logger will be set to whatever was handed over to you in that constructor call. When that gets closed, rest_logger will be closed too.
I'm not quite sure I understood your question, BUT:
why exactly are you overwriting your newly created BufferedWriter?
rest_logger = writer;
maybe you should look into that...

Categories