Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I want to have a clean project. So I used Sonar to detect potential defects, ...

On the below method, Sonar asks to : Use try-with-resources or close this "Connection" in a "finally" clause. .

private Connection createConnection() throws JMSException {
    MQConnectionFactory mqCF = new MQConnectionFactory();
    Connection connection = mqCF.createConnection(...);
    connection.start();
    return connection;

Can you explain me what I did wrong and how to do to avoid Sonar message? Thank you.

Connection implements AutoCloseable which Sonar is detecting (it doesn't care whether you're using a connection or some other auto closeable thingy).

Not closing such a resource could lead to a resource leak so Sonar wants you to do something like this:

//try-with-resources - the connection will be closed after this block
try(Connection connection = mqCF.createConnection(...)) {
  //use connection here
//traditional try - the connection will be closed after the finally block
Connection connection = mqCF.createConnection(...);
try {
  //use connection here
} finally {
   connection.close();

The problem in your case is that you're just creating the connection and then return it - and I strongly suspect you want to keep it open :)

Sonar can't be sure that you'll ever close the connection so it will complain. There might be ways to make Sonar ignore things like this (I don't use it that much so I'm not too familiar with the options here) but it's still a potential risk that you'd have to mitigate somehow.

Thank you for your comment. Yes exactly I want to keep it open :), so I guess here's no solution in this case – Royce Jan 28, 2020 at 9:32 No, try-with-resources is meant to close the auto closeable resources once you leave that block (which returning would do). – Thomas Jan 28, 2020 at 9:38

In java if you are using resource like FileInptStream, Connection, ResultSet, Input/OutputStream, BufferedReader, PrintWriter you have to close it before garbage collection happens. so basically whenever connection object no longer in use you have to close it.

try below snippet

Connection c = null;
    try {
        c = mqCF.createConnection(...);
        // do something
    } catch(SomeException e) {
        // log exception
    } finally {
      try {
        c.close();
      } catch(IOException e1){
        // log something else
//try-with-resources
try(Connection connection = mqCF.createConnection(...)) {
  //use connection here

In the try with resource case connection will automatically close by jvm, but Connection interface must be extends with AutoCloseable / Closable interface.

The code you have above has the potential to leave the Connection object open, which can cause significant issues.

You can guarantee that the Connection is closed when you are finished with it in a few ways:

public Connection createConnection() {
    return connectionFactory.createConnection(...);  // note that this method does not open the connection

Then, when you want to use the connection, either use try-catch-finally:

try {
    Connection c = createConnection();
    doSomethingWithPossibleException(c);
} catch(PossibleException e) {
    handleException(e);
} finally {
    // now close the connection
    c.close();

or you can use try-with-resources (from Java 7 onwards):

try (Connection c = getConnection()) {
    doSomethingWithPossibleException(c);
} catch (PossibleException e) {
    handle(e);

IMO try-with-resources is a little more readable, although tastes differ on this matter. Note, the object you create in the try-with-resources must implement the AutoCloseable interface.

You may want to look into "connection pooling". There are a few issues with using a single database connection for the entire lifespan of the application. Pooling can help eliminate those issues. In your code, you treat your connection pool like your current connection factory object, and close the connections when you are done with them. – cameron1024 Jan 28, 2020 at 9:44

I find out one solution to resolve this issue. you can override the existing DBManger like this:

@Override
    public Connection getConnection() throws SQLException {
        Connection conn = new ProxyConnection(DriverManager.getConnection(...));
        return conn;
    private static class ProxyConnection implements Connection {
        Connection connection;
        private ProxyConnection(Connection connection) {
            this.connection = connection;
         * Standard method, add logging.
        @Override
        public void close() throws SQLException {
            logger.debug("Connection to database was released");
            connection.close();
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.