0

我的 Java 项目中存在游标泄漏问题。

典型例子:

private void doSomething() throws Exception {
    String sql1= "some sql statement";
    String sql2= "some other sql statement";        
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {

        Connection con = getConnection();
        ps = con.prepareStatement(sql1);
        rs = ps.executeQuery();
        //do something with the ResultSet rs        
        //[Need to call ps.close here. Otherwise I risk getting ORA-01000.]
        ps = con.prepareStatement(sql2);              
        ps.executeQuery();
    } catch (Exception e) {
    } finally {
        ps.close();
        rs.close();
    }
}

由于我有一个相当大的代码库,我希望能够找到所有具有两个或多个名为sql.

交替查找具有两个(或多个)调用 prepareStatement 的方法,而无需ps.close;在两者之间调用。

我正在使用 Eclipse,文件搜索有一个正则表达式选项。也许这就是要走的路?如果是这样,它会是什么样子?

4

4 回答 4

0

您可以通过使用资源尝试来避免手动关闭资源(如果您至少使用 JDK 7)

try(con=getConnection()){
   try(ps = con.prepareStatement()){
      try(rs=ps.executeQuery()){
         ...
      }
   }
}

任何实现 Autoclosable 的东西都可以在 try 中使用资源,并且资源会自动为您关闭。不再需要执行复杂的资源关闭操作。

请参阅资源尝试教程

于 2014-01-15T12:00:28.333 回答
0

最新版本的 Eclipse(我使用 Juno [4.2])将在这些行上显示警告:

编辑器截图

您可以在 Eclipse 首选项中启用此警告:

在此处输入图像描述

即使对于较大的代码库,您也可以过滤此警告的问题视图,以便在代码中找到这些位置。

于 2014-01-15T13:24:29.673 回答
0

你想做的是一种静态程序分析。由于有专门的工具,您也可以为此特定任务编写自己的工具。这样,您可以计算包含rs=ps.executeQueryand的行数rs.close()

for(File file:sourceFiles) { 
  int openedResultSets = count("rs=ps.executeQuery");
  int closedResultSets = count("rs.close()");
  if (openedResultSets > closedResultSets) {
     log.error(file.getName());
  }
 } 

但它应该更复杂,因为您的项目中可能不仅使用了这个片段。因此我想你应该写一些代码,而不仅仅是一个正则表达式。尽管在大多数情况下专用工具很昂贵,但可能一些试用版对您来说就足够了。

于 2014-01-15T12:19:50.053 回答
0

FindBugs 规则可以找到这个,例如

  • ODR_OPEN_DATABASE_RESOURCE
  • ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH
  • OBL_UNSATISFIED_OBLIGATION
  • 如果您在错误描述中查找关键字“资源”,则更多

如果您不是专门查找资源泄漏,而是查找两个或多个名为 的变量sql*,则可以编写 Checkstyle 检查来查找它们,可能作为LocalVariableNameCheck的子类。这不是一种困难的检查,但需要编码和部署工作。

于 2014-01-15T13:32:58.883 回答