Inheritance and Try-With-Resources - java

Suppose there are two classes implementing AutoCloseable Interface as below:
public class Closing1 implements AutoCloseable {
private boolean closed;
#Override
public void close() throws Exception {
if (closed) {
throw new Exception("Closed Already");
}
this.closed = true;
System.out.println("Closing1 closed");
}
public boolean isClosed() {
return closed;
}
}
and
public class Closing2 implements AutoCloseable {
private Closing1 cl1;
public Closing2(Closing1 cl1) {
this.cl1 = cl1;
}
#Override
public void close() throws Exception {
if(!cl1.isClosed()) {
throw new Exception("Closing1 not closed");
}
System.out.println("Closing2 closed");
}
}
I find that all variations with try with resources lead to an exception! Is there something I am missing here, or is it just the way TWR is designed?
try(Closing1 c1 = new Closing1();Closing2 c2 = new Closing2(c1)){
System.out.println("Done");
} //Exception while auto closing C2
or
try(Closing1 c1 = new Closing1();Closing2 c2 = new Closing2(c1)){
System.out.println("Done");
c1.close();
} // exception while auto closing c1

Try-with-resources will close the resources in the opposite order of their declaration. This means that c2.close() will be called first, which will throw the exception as you have coded it.

Start with try-with-resources first, https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
As the very first example shows already:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
people will not necessarily name everything in the chain.
Unless you explicitly need c1 for something (other than closing), in real life your snippet would rather look like
try(Closing2 c2 = new Closing2(new Closing1())){
System.out.println("Done");
}
and you would not call c1.close() in the try-block for sure, as there would be no c1 at all.
Keeping this in mind, throwing an exception from c2 because the contained c1 is not closed, is totally wrong, actually c2 owns the Closing1 object and should invoke close() on it:
class Close1 implements AutoCloseable {
#Override
public void close() throws Exception {
System.out.println("Closing c1");
}
}
class Close2 implements AutoCloseable {
Close1 c1;
Close2(Close1 c1) {
this.c1=c1;
}
#Override
public void close() throws Exception {
System.out.print("Closing c1 from c2: ");
c1.close();
System.out.println("Closing c2");
}
}
void test() {
System.out.println("Before try block");
try(Close2 c2=new Close2(new Close1())) {
System.out.println("In try block");
}
catch(Exception ex) {
System.out.println("Exception: "+ex);
}
finally {
System.out.println("In finally block");
}
System.out.println("After try block");
}
However, if someone gives a name to c1, it will be closed twice, that is where the idempotency comes into the picture, as suggested by someone already:
System.out.println("Before try block");
try(Close1 c1 = new Close1(); Close2 c2 = new Close2(c1)){
System.out.println("In try block");
}
catch(Exception ex){
System.out.println("Exception: "+ex);
}
finally{
System.out.println("In finally block");
}
System.out.println("After try block");
As BufferedReader was mentioned already, this is the close() method it has:
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();
} finally {
in = null;
cb = null;
}
}
}
If it has in, it gets closed, and nulled (in a finally block, so it happens even if an exception occurs), and all in a thread-safe block. (cb is just an array of characters, it gets null-ed too, simplifying the life of the garbage collector a little). Because of nulling everything in the finally block, any extra calls to this same method will not do anything (apart from synchronizing on the lock for a moment).

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.

Which close() runs first?

If I have multiple resources, in a try catch, which one gets closed called on first?
public class TestRes {
public static void main(String[] args) {
TestRes tr = new TestRes();
tr.test();
}
public void test() {
try (MyResource1 r1 = new MyResource1(); MyResource2 r2 = new MyResource2(); ) {
System.out.print("T ");
} catch (IOException ioe) {
System.out.print("IOE ");
} finally {
System.out.print("F ");
}
}
class MyResource1 implements AutoCloseable {
public void close() throws IOException {
System.out.print("1 ");
}
}
class MyResource2 implements Closeable {
public void close() throws IOException {
throw new IOException();
}
}
}
This sample outputs:
T 1 IOE F
If I change the order so...
public class TestRes {
public static void main(String[] args) {
TestRes tr = new TestRes();
tr.test();
}
public void test() {
try (MyResource2 r2 = new MyResource2(); MyResource1 r1 = new MyResource1();) {
System.out.print("T ");
} catch (IOException ioe) {
System.out.print("IOE ");
} finally {
System.out.print("F ");
}
}
class MyResource1 implements AutoCloseable {
public void close() throws IOException {
System.out.print("1 ");
}
}
class MyResource2 implements Closeable {
public void close() throws IOException {
throw new IOException();
}
}
}
I get the same output - why?
It seems that you believe an exception from a close() method will prevent other close() methods from being called. That is wrong.
The Java Language Specification, section 14.20.3. try-with-resources, says:
Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.
Which means that the close() method printing 1 will always be executed, and the first part answers your "Which close() runs first?" question.

If multiple resources are closed inside a finally block, is exception handling necessary?

A coworker just unsettled me concerning finally blocks. He claimed that if multiple resources are closed inside a finally block, I do not have to worry about exception handling.
So if I close my resources like this
try {
// do stuff
} catch(Exception e) {
// handle stuff
} finally {
resource1.close();
resource2.close();
}
and an exception occurs at resource1.close(), will the close() method of resource2 get called?
A simple check would confirm:
class MyResource implements AutoCloseable {
private final String name;
MyResource(String name) { this.name = name; }
#Override public void close() throws IOException {
System.out.println("Closing " + name);
throw new IOException();
}
}
public static void main(String[] args) throws IOException {
MyResource a = new MyResource("a");
MyResource b = new MyResource("b");
try {
} finally {
a.close();
b.close();
}
}
This would print "Closing a" and then print a stack trace; "Closing b" would not be printed. In contrast:
try (MyResource a = new MyResource("a");
MyResource b = new MyResource("b")) {
}
would print both.
That depends. If the only exception throwing things (explicitly or potentially) you have inside your try-catch block are close operations, you wouldn't need exception handling. However, most of the times, the close operations are themselves declared as throwing exceptions, thus, you'd need to put them inside a try-catch block anyway.

Executing code after exception is thrown

So I have a bit of situation here with my design and was wondering whether I could
get some feedback.
public class Class1 {
public void eatFish(){}
}
public class Class2 {
public void eatBacon(){
// some nasty code here to cause an exception
}
}
public class Class3 {
public void eatFruit(){}
}
public InvokeAllClasses() {
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
c1.eatFish();
c2.eatBacon();
c3.eatFruit();
}
}
See the problem here in InvokeAllClasses is that, because c2.eatBacon();
blows up, c3.eatFish() would not be executed. Is there a way to still execute
c3 although c2 blew up?
Update
After thinking more about, I guess I could wrap each call in a try...catch block but that is just messy.
Put the try...catch in the method defintion:
public void eatBacon(){
try{
// some nasty code here to cause an exception
} catch(Exception e){
//do something
}
}
This won't look as bad as putting it when you call the method. If you know where exactly in the code the exception could be happening, then only surround those statements.
You could handle the exceptions within the methods themselves so they aren't thrown back up to the calling method, but other than try/catch/finally blocks, there isn't a good practice way to ignore exceptions.
Unless you are sure that you will never have to handle any exceptions thrown by those methods, it might be better to avoid swallowing all of them at the source.
It's been a while since I wrote Java code and I could not try and compile it, but the idea is to create an object which has the responsability to execute tasks and swallow any exceptions.
It may look like:
public class SilentExecutor {
List<Runnable> tasks;
public SilentExecutor(List<Runnable) tasks) {
this.tasks = tasks == null? new List<Runnable>() : tasks;
}
public void execute() {
for (Runnable task : this.tasks) silentlyExecute(task);
}
private void silentlyExecute(Runnable task) {
try { task.run(); }
catch (Exception e) {}
}
}
Then your code could be something like:
new SilentExecutor(Arrays.asList(
() -> { c1.eatFish(); },
() -> { c2.eatBacon(); },
() - > { c3.eatFruit(); }
)).execute();
Why not just catch the exception and move on? I honestly don't think it will be messy.
Make your method to throw an exception.
public InvokeAllClasses() throws Exception {
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
try{
c1.eatFish();
}catch(Exception e){System.out.println("Oh noes! There was something wrong!!!")}
finally{
c2.eatBacon();
c3.eatFruit();
}
}
As you can see. The "finally" statement will force your code to perform no matter if the statement inside the try fails or throws an exception.
There are two approaches you could take. The first option is to ignore the exceptions completely.
try {
c1.eatFish();
} catch(Exception e) {//Ignore}
try {
c2.eatBacon();
} catch(Exception e) {//Ignore}
try {
c3.eatFruit();
} catch(Exception e) {//Ignore}
If you want the exception to be thrown in the end, you can put the result into a variable and then throw it at the end or use the finally clause.
try {
c1.eatFish();
finally {
try {
c2.eatBacon();
} finally {
c3.eatFruit();
}
}
If you are looking for something more readable, you could wrap the method calls.
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
Class3 c3 = new Class3();
callEatFishIgnoringException(c1);
callEatBaconIgnoringException(c2);
callEatFruitIgnoringException(c3);
}
private static void callEatFishIgnoringException(Class1 c1) {
try {c1.eatFish()} catch (Exception e) {//Ignore}
}
private static void callEatBaconIgnoringException(Class2 c2) {
try {c2.eatBacon()} catch (Exception e) {//Ignore}
}
private static void callEatFruitIgnoringException(Class3 c3) {
try {c3.eatFruit()} catch (Exception e) {//Ignore}
}

Concurrency with Java's LinkedList class

Good Day,
I am having concurrency problems with a LinkedList in Java. I have an Object type called "Connection" which has as a member variable LinkedList of "MessageHandlers" called "listeners". I then have two different threads, one modifying and one iterating over the same LinkedList.
I've seen many many other StackOverflow questions that suggest to use the sychronized block of code, but that doesn't appear to be helping it all. I've also try creating the LinkedList as a concurrent linked list, but I am still receiving the
Exception in thread "Thread-1" java.util.ConcurrentModificationException
exception. Does anyone have any other suggestions to try? Here are some snipbits of my code...
public synchronized Object ReadObject() throws java.io.IOException
{
Object obj = null;
try
{
obj = input.readObject();
synchronized(listeners)
{
Iterator<MessageHandler> i = listeners.iterator();
while(i.hasNext())
{
i.next().MessageReceived(obj, this);
}
}
}
catch (IOException e)
{
e.printStackTrace();
throw e;
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}
The above code is inside my connection object. It gets called from a function that has a socket's ObjectInputStream reading data from the socket."input" is an instance of ObjectInputStream.
public void addNewLoggedInUser(User user) throws Exception
{
for(User u:loggedInUsers)
{
if(u == user)
{
throw new Exception("That user is already logged in");
}
}
//Add the new users
loggedInUsers.add(user);
synchronized(user.getConnection().getListeners())
{
user.getConnection().getListeners().add(this);
}
this.SendGameStatusUpdateToAllLoggedinPlayers();
}
I then call the method user.getConnection().getListeners().add(this) and thus am getting the exception.
public Connection()
{
//Initialize the variables to NULL
socket = null;
output = null;
input = null;
receiveThread = null;
runReceiveThread = false;
listeners = Collections.synchronizedList(new LinkedList<MessageHandler>());
//Handle the ID counter. Now we have a unique ID for every connection that comes in
connectionID = counterID;
counterID = counterID + 1;
}
This is the constructor for the connection class. Notice he Collections.synchronizedList
Any ideas? Thank you very much for your help!
java.util.ConcurrentModificationException isn't really a threading issue. It is cause by modification of a list locked by it's iterator. I think you are calling addNewLoggedInUser() from MessageReceived(). This would cause the concurrent modification exception since the calling function already has iterator lock on the linkedlist.
Go through BlockingQueue javadoc. It mentions a simple scenario as well that fits your requirements i.e.
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
The synchronized blocks look like they should work. I would expect that there is activity in methods called from within the ReadObject synchronized block which modify the list. Do any of your MessageHandlers call or chain to a call to addNewLoggedInUser (or any other method that might update the listener list)?
If so, the thread would already have the monitor grabbed by the ReadObject synchronized block, and would be able to enter the block in addNewLoggedInUser.

Categories

Resources