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.
Related
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;
}
}
I'm writing a class to manage files locking named FileLocker.
Its buildier method locks a file (which directory is received as a method's parameter) thanks to java.nio.channels.FileLock.The FileLocker class also contains a release() method that release the FileLock created in its buildier method. The problem is that the release() method have to be called, otherwise the file's lock will never be released and other processes won't be allowed to use this file (during the current JVM). So my question is: Does exist a way to indicate that release() method have to be called in all codes that use a FileLocker object, so that during those codes compilations an error is thrown if release() method isn't used? (Here I post FileLocker class code, just to show how it works):
package essentialServer_Service;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import essentialServer_Exception.EssentialServerException;
public class FileLocker implements ServerConfiguration{
String fileDirectory;
int filelockingAttempts;
int maxFilelockingAttempts;
FileChannel fileChannel;
RandomAccessFile randomAccessFile;
FileLock lock;
file f;
public FileLocker (String fileDirectory) throws EssentialServerException {
this.fileDirectory = fileDirectory;
filelockingAttempts = 0;
maxFilelockingAttempts = maxDatabaseFilesLockingAttempts();
f = new file(fileDirectory);
f.make(); // To open a channel for a specific file, this file must exist
// Note that the file.make() method throws an EssentialServerException if it seems to be impossible to create the file
fileChannel = null;
randomAccessFile = null;
try{
randomAccessFile = new RandomAccessFile(f, "rw");
fileChannel = randomAccessFile.getChannel();
}catch (FileNotFoundException e){
throw new EssentialServerException(4);
}
lock = null;
while (true) {
try{
lock = fileChannel.tryLock();
}catch (OverlappingFileLockException e){
filelockingAttempts++;
if (filelockingAttempts > maxFilelockingAttempts && maxFilelockingAttempts > -1){
try{
fileChannel.close();
randomAccessFile.close();
}catch (IOException ee){
throw new EssentialServerException(7);
}
throw new EssentialServerException(5);
}
}catch (IOException e) {
filelockingAttempts++;
if (filelockingAttempts > maxFilelockingAttempts && maxFilelockingAttempts > -1){
try{
fileChannel.close();
randomAccessFile.close();
}catch (IOException ee){
throw new EssentialServerException(8);
}
throw new EssentialServerException(6);
}
}
}
}
public void release (int ExceptionType) throws EssentialServerException{
//The int value ExceptionType indicate the EssentialServerException's type that the FileLocker class should throw if the file unlocking fails
try{
lock.release();
fileChannel.close();
randomAccessFile.close();
}catch (IOException ee){
throw new EssentialServerException(ExceptionType);
}
}
}
To directly answer your question - I do not know a way to directly enforce this. However, I would like to refer you to the AutoCloseable interface. It allows you to write code that can be used in a try-with-resources code block.
Not knowing (ignoring really) all the details of your code, using it might look like something like this:
try (FileLocker locker = new FileLocker(filename)) {
// Use locker
}
Optionally you can add your catch and finally blocks. But the point is that this guarantees that locker will be 'closed' before exiting the try-block.
Additionally, if FileLocker is only an arbitrary object that won't be further used inside the try {} block, other than releasing it again, then you could simplify this as follows:
try (new FileLocker(filename)) {
// Your code during FileLocker
}
In order for this to work, your FileLocker will have to extend AutoCloseable. Actually, if your FileLocker will throw an IOException, you can also consider extending Closeable instead. You will be required to implement the close method, which would basically have to call your release method.
Locking a file is quite simple in Java. The FileChannel (Java Doc) provides all methods we need to lock files. The tryLock() (Java Doc) method will try to obtain the lock on the file without waiting. If the lock is acquired an instance of FileLock (Java Doc) is returned, otherwise this method returns null.
FileLock is only for interprocess locking, javadoc reads:
"File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine."
To lock between java threads (same JVM) you need to use some shared lock. I would suggest within the file writing class to use a synchronized block (which according to these articles is likely to perform best):
An alternative approach is to use a ReentrantLock :
final ReentrantLock lock = new ReentrantLock();
public void write(...){
try {
lock.lock()
// do the writing
} finally {
// forget this and you're screwed
lock.unlock();
}
}
This case uses the lock to resolve interleaving of writes, not concurrent access.Further concurrent lock is more feature rich.However sync lock does the task as well.read doc
Both locks and reentrant locks however are mandtory to close.so new try with resource feature is handy that implements AutoCloseable interface, which is required for use with the new try-with-resource syntax. so you can write a simple wrapper like:
public class LockWrapper implements AutoCloseable
{
private final Lock _lock;
public LockWrapper(Lock l) {
this._lock = l;
}
public void lock() {
this._lock.lock();
}
public void close() {
this._lock.unlock();
}
}
Now you can write code like this:
try (LockWrapper someLock = new LockWrapper(new ReentrantLock()))
{
someLock.lock();
// ...
}
I have a very simple question that seems to be stupid to me but yet asking .How BufferedReader call the close() method of Autocloseable interface. or how we can implement Autocloseable that call the close() automatically.
It's syntactic sugar. The javac compiler inserts the close() call into the compiled class at the end of the try block where the BufferedReader is declared, as you can see if you disassemble the class file with javap -c.
There's nothing you have to do in your own code besides implement AutoCloseable and provide a close() method. Java takes care of calling for you the close() method at the end of the try statement. Consider the following minimal demonstration:
class MyCloseable implements AutoCloseable {
public void close() { System.out.println("Close was called"); }
}
public class Ac {
public static void main(String[] args) {
try (MyCloseable mc = new MyCloseable()) {
}
}
}
$ java Ac
Close was called
try(AutoClosable x = open()) {}
is usually seen as short-hand version of
try {
Resource x = open();
} finally {
x.close();
}
There are two actual differences :
If both blocks throw, the autoclosable try statement will throw the exception from within the try statement, whereas the try...finally will throw the exception from the finally block. An exception from the other block would be suppressed.
In addition the exact behaviour is like this:
try(Autoclosable x = open) {
//do something
} do_close {
x.close();//not actually there - executed before catch and finally!
} catch (WhateverException e){
//catch an exception
} finally {
//finally do something
}
From the Oracle Docs:
"A try-with-resources statement can have catch and finally blocks just
like an ordinary try statement. In a try-with-resources statement, any
catch or finally block is run after the resources declared have been
closed."
So due to these two technical details it is not just syntactic sugar, but in practice it is used where formerly try...finally would have been used.
There is no actual way to imitate the behavior of try-with-resources for other interfaces than Autoclosable afaik. If you want to do some cleanup after a try you will have to either use finally or implement Autoclosable. Finalizers seem to do something similar, but actually they don't. I just mention them here to advise you not to use them.
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.
It turns out that almost nobody closes resources in Java correctly. Programmers either do not use try-finally block at all, or just put resource.close() in finally which is also incorrect (because Throwable from close() can shadow Throwable from try block). Sometimes they put something like IOUtils.closeQuietly() with is only correct for InputStream, but not for OutputStream. try-with-resources solves all of these problems but there are still huge number of projects written in Java 6.
What is the best way to emulate try-with-resources in Java 6? Now I use Guava Closer, which is better than nothing but still much uglier than try-with-resources. Also, there is a pattern called a loan-pattern, but the absence of lambdas in Java makes this pattern very cumbersome. Is there a better way?
I've found a good replacement for try-with-resources. It uses Lombok library with annotation processing:
#Cleanup InputStream in = new FileInputStream(args[0]);
#Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
However, it doesn't handle exception correctly. This bug is more than 1 year old and still is not closed: https://code.google.com/p/projectlombok/issues/detail?id=384
Though anonymous class is quite verbose, it's still acceptable in java land
new TryWithResource<InputStream>(){
protected InputStream init() throws Exception {
return new FileInputStream("abc.txt");
}
protected void use(InputStream input) throws Exception{
input.read();
}
};
----
abstract class TryWithResource<R>
{
abstract protected R init() throws Exception;
abstract protected void use(R resource) throws Exception;
// caution: invoking virtual methods in constructor!
TryWithResource() throws Exception
{
// ... code before
R r = init();
use(r);
// ... code after
}
}
If your only problem with IOUtils.closeQuietly is that it ignores exceptions on OutputStreams, then you can either simply call close() on them, or create your own utility class which automatically treats the two differently, like this:
public static void close(Closeable resource)
{
try
{
resource.close();
}
catch(Exception e)
{
//swallow exception
}
}
public static void close(OutputStream o)
{
//throw any exceptions
o.close();
}
The correct overloaded method will be selected at compile time in all common situations, although if you're passing OutputStreams around as Closeables then you'll have to change this to do a dynamic instanceof check to make sure OutputStreams always throw exceptions.