Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compose Closeable objects in Java?

Tags:

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.