Alex Rivera | Logout

advice on nested Java try/finally code sandwiches

Asked 2011-08-31T09:10:43.697
22

I would like some advice on a technique I bumped onto. It can be easily understood by looking at the code snippets, but I document it somewhat more in the following paragraphs.


Using the "Code Sandwich" idiom is commonplace to deal with resource management. Used to C++'s RAII idiom, I switched to Java and found my exception-safe resource management resulting in deeply nested code, in which I have a really hard time getting grip on the regular control flow.

Apparently (java data access: is this good style of java data access code, or is it too much try finally?, Java io ugly try-finally block and many more) I'm not alone.

I tried different solutions to cope with this:

  1. maintain the program state explicitly: resource1aquired, fileopened..., and cleanup conditionally: if (resource1acquired) resource1.cleanup()... But I shun duplicating the program state in explicit variables - the runtime knows the state, and I don't want to care for it.

  2. wrap every nested block in functions - results in even harder to follow control flow, and makes for really awkward function names: runResource1Acquired( r1 ), runFileOpened( r1, file ), ...

And finally I arrived at an idiom also (conceptually) backed by some research paper on code sandwiches:


Instead of this:

// (pseudocode)
try {
   connection = DBusConnection.SessionBus(); // may throw, needs cleanup
   try {
        exported = false;
        connection.export("/MyObject", myObject ); // may throw, needs cleanup
        exported = true;
            //... more try{}finally{} nested blocks
    } finally {
        if( exported ) connection.unExport( "
Edit
Report

1 Answer

3

A destructor like device for Java, that will be invoked at the end of the lexical scope, is an interesting topic; it's best addressed at language level, however the language czars don't find it very compelling.

Specifying destruction action immediately after construction action has been discussed (nothing new under the sun). An example is http://projectlombok.org/features/Cleanup.html

Another example, from a private discussion:

{
   FileReader reader = new FileReader(source);
   finally: reader.close(); // any statement

   reader.read();
}

This works by transforming

{
   A
   finally:
      F
   B
}

into

{
   A
   try
   {
      B
   }
   finally
   {
      F
   }
}

If Java 8 adds closure, we could implement this feature succinctly in closure:

auto_scope
#{
    A;
    on_exit #{ F; }
    B;
}

However, with closure, most resource library would provider their own auto cleanup device, clients don't really need to handle it by themselves

File.open(fileName) #{

    read...

}; // auto close
answered 2011-08-31T18:57:40.253

Your Answer