2

I'm working with a database in Java and have been writing multiple functions along the lines of

try {
    //acquire resources
}
finally {
    //release resources
}

I know that Java's try-with-resources is a decent way to deal with something like this, but I'm using Java 6. Is there a standard way to reduce code duplication? I'd love to have a clean way of writing multiple functions which have the same try/finally blocks for resource allocation, but whose body differs.

My current thought was to make the bodies of the function members of a class whose constructor acquires the resources. But, without RAII, it seems a bit messy still.

Viknesh
  • 505
  • 1
  • 4
  • 14

4 Answers4

3

If you can afford to use Guava (14.0+), you can use Closer. While it does not eliminate all duplication, it is a very convenient way to deal with resources implementing Closeable -- and more than one, at that:

final Closer closer = Closer.create();
final InputStream in1;
final InputStream in2; // whatever, as long as Closeable is implemented

try {
    in1 = closer.register(createIn1());
    in2 = closer.register(createIn2());
    // do stuff
} finally {
    closer.close();
}

This class will handle the closing of all resources gracefully, and in the reverse order in which you registered them.

If you cannot afford Guava, it is quite easy to code a simple version of it yourself.

fge
  • 119,121
  • 33
  • 254
  • 329
  • The xUnit Design Patterns book describes a similar way of closing resources using `@After` methods in JUnit. – Eric Jablow Jul 01 '13 at 21:11
  • @fge, following your comments I did a bit of reading re. `Closer`. In [the documentation](http://code.google.com/p/guava-libraries/wiki/ClosingResourcesExplained) they state _it's very important to follow the prescribed usage pattern_. It doesn't look like you're following the pattern (notably _any Throwable thrown from the block where the Closeable resources are used must be caught and rethrown through Closer's rethrow method_). – Boris the Spider Jul 02 '13 at 09:29
  • @BoristheSpider this is for exceptions other than IOExceptions (therefore all throwables inheriting IOException as well) – fge Jul 02 '13 at 09:35
1

Take a look at Project Lombock; it uses annotation processing to tidy up boilerplate.

More specifically you can use the @Cleanup annotation and it will wrap in try...finally at compile time.

So your code goes from

final Connection con...
try {
    //do stuff
} finally {
    con.close();
}

To

@Cleanup
final Connection con...

Both will compile to the same code.

Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
  • The problem with lombok in general is that it is fine when you see the original code; but the generated code can become quite ungainly... Especially with this annotation ;) – fge Jul 02 '13 at 07:34
  • @fge, yes - applying the most generic rules does result in somewhat ugly code, but it shouldn't impact on performance and you don't _see_ the ugly code. The JIT compiler doesn't care if the code is pretty or not. I admit I find myself writing lots of unit tests for things like this however to ensure that the generated code works correctly. – Boris the Spider Jul 02 '13 at 07:37
  • Well, you _do_ see the ugly code when you want to debug a library using it and want to debug the source. – fge Jul 02 '13 at 07:38
1

You can use aspects. The great example of aspects in work is the Spring framework. One of the features that is realized in that way is the transaction support. The transactional aspects are handling the transaction opening , committing (on normal proceed) or rollbacking (on exception), and releasing in each case.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
0

It seems that the Execute Around idiom describes exactly this use case - What is the "Execute Around" idiom?

However, it seems a bit messy to implement

Community
  • 1
  • 1
Viknesh
  • 505
  • 1
  • 4
  • 14