Java 声纳要求;使用try with resources或关闭此";“连接”;在“a”中;最后";第条;

Java 声纳要求;使用try with resources或关闭此";“连接”;在“a”中;最后";第条;,java,sonarqube,Java,Sonarqube,我想要一个干净的项目。所以我用声纳探测潜在的缺陷 在下面的方法中,Sonar要求:使用try with resources或在“finally”子句中关闭此“连接”。 private Connection createConnection() throws JMSException { MQConnectionFactory mqCF = new MQConnectionFactory(); ... Connection connection = mqCF.create

我想要一个干净的项目。所以我用声纳探测潜在的缺陷

在下面的方法中,Sonar要求:
使用try with resources或在“finally”子句中关闭此“连接”。

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

    Connection connection = mqCF.createConnection(...);
    connection.start();

    return connection;
}

你能解释一下我做错了什么,以及如何避免声纳信号吗?谢谢。

连接
实现声纳正在检测的自动关闭(它不关心您是在使用连接还是其他自动关闭的东西)

不关闭此类资源可能导致资源泄漏,因此Sonar希望您执行以下操作:

//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();
}
@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();
        }
    }
您的情况中的问题是,您只是创建了连接,然后返回了它—我强烈怀疑您希望保持连接处于打开状态:)


声纳无法确定你是否会关闭连接,所以它会抱怨。可能有办法让Sonar忽略这样的事情(我不经常使用它,所以我不太熟悉这里的选项),但这仍然是一个潜在的风险,您必须以某种方式减轻。

连接
实现
自动关闭
Sonar正在检测的(不管你是在使用连接还是其他自动关闭的东西)

不关闭此类资源可能导致资源泄漏,因此Sonar希望您执行以下操作:

//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();
}
@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();
        }
    }
您的情况中的问题是,您只是创建了连接,然后返回了它—我强烈怀疑您希望保持连接处于打开状态:)


声纳无法确定你是否会关闭连接,所以它会抱怨。可能有一些方法可以让Sonar忽略这样的事情(我没有太多地使用它,所以我对这里的选项不太熟悉),但这仍然是一个潜在的风险,您必须以某种方式加以缓解。

您上面的代码有可能使
连接
对象保持打开状态,这可能会导致重大问题

您可以通过以下几种方式保证
连接
在使用完毕后关闭:

public Connection createConnection() {
    return connectionFactory.createConnection(...);  // note that this method does not open the connection
}
然后,当您想使用连接时,可以使用try catch finally

try {
    Connection c = createConnection();
    doSomethingWithPossibleException(c);
} catch(PossibleException e) {
    handleException(e);
} finally {
    // now close the connection
    c.close();
}
或者您可以使用尝试使用资源(从Java 7开始):


虽然在这个问题上人们的口味不同,但我觉得《资源尝试》更具可读性。注意,您在“使用资源尝试”中创建的对象必须实现“可自动关闭的代码”界面。

您上面的代码可能会使“连接”对象保持打开状态,这可能会导致重大问题

您可以通过以下几种方式保证
连接
在使用完毕后关闭:

public Connection createConnection() {
    return connectionFactory.createConnection(...);  // note that this method does not open the connection
}
然后,当您想使用连接时,可以使用try catch finally

try {
    Connection c = createConnection();
    doSomethingWithPossibleException(c);
} catch(PossibleException e) {
    handleException(e);
} finally {
    // now close the connection
    c.close();
}
或者您可以使用尝试使用资源(从Java 7开始):


虽然在这个问题上人们的口味不同,但我觉得《资源尝试》更具可读性。注意,您在try with resources中创建的对象必须实现
自动关闭接口。

在java中,如果您使用的是
FileInputStream、Connection、ResultSet、Input/OutputStream、BufferedReader、PrintWriter等资源,则必须在垃圾收集发生之前将其关闭。
所以基本上只要连接对象不再使用,就必须关闭它

请尝试下面的代码片段

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
}

在try-with-resource案例中,jvm将自动关闭连接,但连接接口必须使用
自动关闭/可关闭接口进行扩展。

在java中,如果您使用的是
FileInputStream、connection、ResultSet、Input/OutputStream、BufferedReader、,PrintWriter
您必须在垃圾回收发生之前关闭它。 所以基本上只要连接对象不再使用,就必须关闭它

请尝试下面的代码片段

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
}

在try-with-resource案例中,jvm将自动关闭连接,但连接接口必须使用
AutoCloseable/Closable
接口进行扩展。

我找到了一个解决此问题的解决方案。 可以如下所示覆盖现有DBManger:

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

我找到了一个解决这个问题的方法。 可以如下所示覆盖现有DBManger:

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

一个选项是使用一个选项是使用谢谢你的评论。是的,确切地说,我想让它保持打开状态:),所以我想在这种情况下没有解决方案,请执行
返回连接在<代码>尝试使用资源
中无法解决此问题?不,尝试使用资源意味着在您离开该块后关闭自动关闭的资源(返回即可)。感谢您的评论。是的,确切地说,我想让它保持打开状态:),所以我想在这种情况下没有解决方案,请执行
返回连接在<代码>尝试使用资源
中无法解决此问题?不,尝试使用资源意味着在您离开该块后关闭自动关闭的资源(返回即可)。谢谢。但是,我不想关闭它,因为我想以后再使用它。您可能需要查看“连接池”。在应用程序的整个生命周期中使用单个数据库连接存在一些问题。合并有助于消除这些问题。在代码中,您将连接池视为当前连接工厂对象,并在处理完连接后关闭连接。谢谢。但是,我不想关闭它,因为我想以后再使用它。您可能需要查看“连接池”。在应用程序的整个生命周期中使用单个数据库连接存在一些问题。合并有助于消除这些问题。在代码中,将连接池视为当前的连接工厂对象,并在处理完连接后关闭连接。如果使用此选项,SonarQube不会显示任何冲突。如果使用此选项,SonarQube不会显示任何冲突