Home > Java > Execute Around Method in Java Example

Execute Around Method in Java Example

I was working hard to get work done, then I realized I was doing the same thing over and over.
A thought came to my mind: “This code is smelling funny, let me see if I can make it DRY and cleaner”.

This may not be the best use case, I’m posting here because I already had it.
Other, and perhaps more appropriate uses cases that I can think of at this moment is for instance,
when you’re dealing with external resources you want to make sure that they’re released
after usage by wrapping around a try/catch/finally.

Examples:

  • Make sure File is closed after IO operations.
  • Eliminate leaks in JDBC Connections, Statements and ResultSets.

Java is just not the most practical language to use this pattern, therefore this technique doesn’t worth implementing unless you have a lot of repetition in your code.

I want to emphasize that the method safeCall has a lot of boiler plate code that is almost generic enough to be reused in different contexts.
Note how the addition of static imports in Java 1.5 allows the cleaner syntax (without qualifying with the class name). This gives the impression that you augmented the java language with a new wrapper function to protect dangerous code

import static ExecuteAroundMethod.safeCall;
...
// Safely do dangerous and fun stuff :P
OperationInformation info = safeCall( new Fun<OperationInformation>()  {
     public void execute( final OperationInformation info )
      {
          DoMacTwist(); //http://www.youtube.com/watch?v=EXAwjsTbtMA&amp;NR=1&amp;feature=fvwp
          throw new BigNastyError("I failed");
       } );
...
//You would need to have multiple use cases of calling safeCall in order to justify the pattern,
// here goes one more ...
 info = safeCall( new Fun<OperationInformation>()  {
    public void execute( final OperationInformation info ) {
        SpendMardiGrasInNewOrleans();
     }  );

Tip : Make sure you do a *static* import of the Method

The Fun interface below can and should be implemented as an anonymous inner class , all you have to do is write your code to implement the execute method which will be called back by safeCall. I designed the Fun interface with the generic <P> Parameter to give you more flexibility when implementing it. In my case the type for the Param P was OperationInformation.

// { Fun.java }
/**
 * @author Mozart Brocchini
 * SAM (single abstract method) type 
 */
public interface Fun<P>
{
  void  execute(P param);
}

The class below contains just boiler plate code that I don’t want to repeat over and over. Again, the method was implemented static to allow a less intrusive code look.

//  { ExecuteAroundMethod.java }
/**
  * @author Mozart Brocchini
 */
public class ExecuteAroundMethod
{
    /**
     * Executes a method around a try/catch block with automatic
     * capture of errors produced by throwables.
     */
    public static OperationInformation safeCall( Fun<OperationInformation> fun )
    {
        final OperationInformation info = new OperationInformation();
        try
        {
            fun.execute( info );
            info.setResult( OperationInformation.RESULT_SUCCESS );
        }
        catch( final Throwable t )
        {
            info.getErrors().add( t.toString() );
            info.setResult( OperationInformation.RESULT_ERROR );
        }

        // Check if the function inserted any errors
        if( !info.getErrors().isEmpty() )
        {
            info.setResult( OperationInformation.RESULT_ERROR );
        }
        return info;
    }
}

The class below is a POJO to encapsulate the information collected before, during and after the call to safeCall. Note that the parameter info is passed to the anonymous inner class, so that the client code can add both messages and errors and even change the result.

// { OperationInformation.java }
/**
  * @author Mozart Brocchini
 */
public class OperationInformation
{
    /** Initial state */
    public static final int RESULT_UNKNOWN = -100;

    /** Indicates a successful operation */
    public static final int RESULT_SUCCESS = 0;

    /** Indicates a general operation error. */
    public static final int RESULT_ERROR = 1;

    private int result = RESULT_UNKNOWN;

    /** Encapsulate error messages*/
    private List errors;

    /** Encapsulate general messages*/
    private List messages;

    public int getResult()
    {
        return result;
    }

    public void setResult( int result )
    {
        this.result = result;
    }

    public List getErrors()
    {
        if( errors == null )
        {
            errors = new ArrayList();
        }
        return errors;
    }

    public void setErrors( List errors )
    {
        this.errors = errors;
    }

    public List getMessages()
    {
        if( messages == null )
        {
            messages = new ArrayList();
        }
        return messages;
    }

    public void setMessages( List messages )
    {
        this.messages = messages;
    }
}
About these ads
Categories: Java

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: