Sonar asks to “Use try-with-resources or close this ”Connection“ in a ”finally“ clause.”

◇◆丶佛笑我妖孽 提交于 2021-01-01 07:32:47

问题


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.


回答1:


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.




回答2:


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.




回答3:


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 {
        if(c != null)
           c.close();
    }

//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.




回答4:


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();
        }
    }


来源:https://stackoverflow.com/questions/59945517/sonar-asks-to-use-try-with-resources-or-close-this-connection-in-a-finally

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!