Jul 10

Currently I am working on a project that has been under development for almost 6 years now, so it contains a lot code written by a lot of people.

A couple of days ago, I was modifying a module in which We had a function like:

public ResponseObject perfromTask(/* params */)  {

  ResponseObject response;

  try {
  // — My Changes Start Here –

  //….

  //some statements

  //….

  // all done, return the object

  return response; // this response object is perfectly valid

  // — My Changes End Here –

  }

  catch(SomeException ex)  {  // handle exception

  }  finally {

  // some resource cleaning

  return response; // BOOM!!!!! I didn’t notice this statement at first

  }

}

and there was another method that was calling the above method like this:

public void callerMethod(/* params */) {

  // irrelevant code

  ResponseObject response = performTask( /* params */); // the response object received here was always null

  // irrelevant code

}

But strangely, I was always getting NullPointerException when the callerMethod tried to get response from perfromTask. So I placed a breakpoint at the line where I was returning the response in the performTask (the line that has a “this response is perfectly valid” comment) and another just after the line where performTask is called in the callerMethod. And when it interrupted the execution inside perfromTask, I could see that the response object was the one that should have been expected, so I just “resume” to jump to the next break point and OUCH! the response object received in the caller is indeed null.

After single stepping through performTask, I noticed that finally block had a return statement itself, I don’t know why it was returning null (since it had the same reference as the try block) but it, while at the same time being surprising, was quiet annoying because the code ran into an error when in fact there was no error (in the changes I made I mean). Anyway, removing return statement from finally block and making sure that try block was returning in every case it was supposed to return solved the problem.

I never thought of returning inside finally block before, but now that I have seen it, I know it is something mysterious and might get you into problems. Don’t know what java specs have to say about it.

written by ishaq