I'm trying to create a Java class which manages multiple Closeable
resources. The C++ solution would be straightforward and easily scalable with a larger number of resources:
class composed_resource
{
resource_a a;
resource_b b;
resource_c c;
composed_resource(int x)
: a(x), b(x), c(x)
{ }
~composed_resource()
{ }
};
My naive Java solution:
public class ComposedResource implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource(int x) /* throws ... */ {
a = new ResourceA(x);
try {
b = new ResourceB(x);
try {
c = new ResourceC(x);
} catch (Throwable t) {
b.close();
throw t;
}
} catch (Throwable t) {
a.close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
a.close();
} finally {
try {
b.close();
} finally {
c.close();
}
}
}
}
A slightly improved version:
public class ComposedResource2 implements Closeable
{
private final ResourceA a;
private final ResourceB b;
private final ResourceC c;
public ComposedResource2(int x) /* throws ... */ {
try {
a = new ResourceA(x);
b = new ResourceB(x);
c = new ResourceC(x);
} catch (Throwable t) {
close();
throw t;
}
}
@Override
public void close() throws IOException {
try {
if (a != null) a.close();
} finally {
try {
if (b != null) b.close();
} finally {
if (c != null) c.close();
}
}
}
}
Is there a more elegant solution which avoids nested try-catch-blocks while still maintaining exception safety? It is manageable with three resources, but anything more is getting unwieldy. (If it was a local scope, I could just use a "try-with-resources" statement, but that's not applicable here.)
I thought about this while working with java.rmi
. In the constructor I'm creating/looking up the registry, looking up objects and exporting objects. The close() needs to unregister and unexport objects. I thought about creating wrapper objects to handle the export/unexport (like I'd do in C++ to take advantage of RAII), but then I noticed that won't help me much (I'm not that much of a Java expert, but I have to use it for university).
At the moment I'm using something like ComposedResource2
above, and it works fine. But now I'm interested to know if there is a more elegant solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With