3

As per my understanding, I want to follow the best practice for releasing the resources at the end to prevent any connection leaks. Here is my code in HelperClass.

public static DynamoDB getDynamoDBConnection()
{   
    try
    {
        dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
    }
    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        dynamoDB.shutdown();
    }
    return dynamoDB;
}

My doubt is, since the finally block will be executed no matter what, will the dynamoDB returns empty connection because it will be closed in finally block and then execute the return statement? TIA.

Chandz
  • 1,173
  • 3
  • 18
  • 34
  • 2
    What happens when you try it? – JB Nizet Jun 19 '15 at 11:09
  • 3
    Better to do a null check on dynamoDB before calling dynamoDB.shutdown(); – paramupk Jun 19 '15 at 11:11
  • dynamoDB is shutdown no matter whether an exception happens or not.you only shutdown after its being used.If you want only connection why do u even need to shutdown it as you won't have the connection if something goes wrong and throws a null pointer exception and if you get a connection why do you want to shutdown? – geddamsatish Jun 19 '15 at 11:35
  • @aioobe Forgive me for my delayed response. All these days I was swapped into another project and didn't get chance to work on this one. Your answer is very much helpful and appreciated. Thanks alot. :+1 – Chandz Jun 29 '15 at 10:12

4 Answers4

9

Your understanding is correct. dynamoBD.shutdown() will always execute before return dynamoDB.

I'm not familiar with the framework you're working with, but I would probably organize the code as follows:

public static DynamoDB getDynamoDBConnection()
        throws ApplicationSpecificException {   
    try {
        return new DynamoDB(new AmazonDynamoDBClient(
                                    new ProfileCredentialsProvider()));
    } catch(AmazonServiceException ase) {
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);
        throw new ApplicationSpecificException("some good message", ase);
    }
}

and use it as

DynamoDB con = null;
try {
    con = getDynamoDBConnection();
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
} finally {
    if (con != null)
        con.shutdown();
}

You could also create an AutoCloseable wrapper for your dynamoDB connection (that calls shutdown inside close) and do

try (DynamoDB con = getDynamoDBConnection()) {
    // Do whatever you need to do with con
} catch (ApplicationSpecificException e) {
    // deal with it gracefully
}
Ozgur Vatansever
  • 49,246
  • 17
  • 84
  • 119
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • Thank you so much. I must take a learning here that I need not worry about releasing the connection in the place where I am getting it. (i.e., here in my case it is from helper class calling, public static DynamoDB getDynamoDBConnection(). But I must worry about closing the connection in the place where I am actually using it. Thank you so much. – Chandz Jun 29 '15 at 10:10
1

Yes,dynamoDB will return an empty connection as dynamoBD.shutdow() will be executed before return statement, Always.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
Rishi
  • 1,646
  • 2
  • 15
  • 34
1

Although I am not answering your question about the finally block being executed always (there are several answers to that question already), I would like to share some information about how DynamoDB clients are expected to be used.

The DynamoDB client is a thread-safe object and is intended to be shared between multiple threads - you can create a global one for your application and re-use the object where ever you need it. Generally, the client creation is managed by some sort of IoC container (Spring IoC container for example) and then provided by the container to whatever code needs it through dependency injection.

Underneath the hood, the DynamoDB client maintains a pool of HTTP connections for communicating the DynamoDB endpoint and uses connections from within this pool. The various parameters of the pool can be configured by passing an instance of the ClientConfiguration object when constructing the client. For example, one of the parameters is the maximum number of open HTTP connections allowed.

With the above understanding, I would say that since the DynamoDB client manages the lifecycle of HTTP connections, resource leaks shouldn't really be concern of code that uses the DynamoDB client.

0

How about we "imitate" the error and see what happens ? This is what I mean:

___Case 1___

try{
  // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
  throw new AmazonServiceException("Whatever parameters required to instantiate this exception");
}    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);

    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        //dynamoDB.shutdown();
        slf4jLogger.info("Database gracefully shutdowned");
    }

___Case 2___

try{
  // dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider()));
  throw new Exception("Whatever parameters required to instantiate this exception");
}    catch(AmazonServiceException ase)
    {
        //ase.printStackTrace();
        slf4jLogger.error(ase.getMessage());
        slf4jLogger.error(ase.getStackTrace());
        slf4jLogger.error(ase);

    }
    catch (Exception e)
    {
        slf4jLogger.error(e);
        slf4jLogger.error(e.getStackTrace());
        slf4jLogger.error(e.getMessage());
    }
    finally
    {
        //dynamoDB.shutdown();
        slf4jLogger.info("Database gracefully shutdowned");
    }

These exercise could be a perfect place to use unit tests and more specifically mock tests. I suggest you to take a close look at JMockit, which will help you write such tests much more easily.

Alp
  • 3,027
  • 1
  • 13
  • 28