Поиск нескольких вхождений переменных в методе
У меня проблема с утечкой курсора в моем проекте 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 ответа
Последние версии Eclipse (я использовал Juno [4.2]) будут показывать предупреждение в этих строках:
Вы можете включить это предупреждение в настройках Eclipse:
Даже для кодовых баз большего размера вы можете отфильтровать представление проблем для этого предупреждения, чтобы найти эти места в коде.
Есть правила FindBugs, чтобы найти это, такие как
- ODR_OPEN_DATABASE_RESOURCE
- ODR_OPEN_DATABASE_RESOURCE_EXCEPTION_PATH
- OBL_UNSATISFIED_OBLIGATION
- больше, если вы ищете ключевое слово "ресурс" в описании ошибки
Если вы специально не ищете утечки ресурсов, а скорее для двух или более переменных с именем sql*
, вы можете написать проверку Checkstyle, чтобы найти их, возможно, как подкласс LocalVariableNameCheck. Это не сложный вид проверки, но требует работы по кодированию и развертыванию.
Вы можете избежать необходимости закрывать ресурсы вручную (если вы используете хотя бы JDK 7), используя попытку с ресурсами
try(con=getConnection()){
try(ps = con.prepareStatement()){
try(rs=ps.executeQuery()){
...
}
}
}
Все, что реализует Autoclosable, может быть использовано в попытках с ресурсами, и ресурс автоматически закрывается для вас. Больше не нужно реализовывать сложные операции закрытия ресурсов.
То, что вы хотите сделать, это вид статического анализа программы. Поскольку для этого есть специализированные инструменты, вы также можете написать свой собственный инструмент для этой конкретной задачи. Таким образом, вы можете считать строки, содержащие rs=ps.executeQuery
а также rs.close()
:
for(File file:sourceFiles) {
int openedResultSets = count("rs=ps.executeQuery");
int closedResultSets = count("rs.close()");
if (openedResultSets > closedResultSets) {
log.error(file.getName());
}
}
Но это должно быть более сложным, потому что, вероятно, не только этот фрагмент используется в ваших проектах. Поэтому я полагаю, вы должны написать некоторый код, а не только одно регулярное выражение. Хотя специализированные инструменты в большинстве случаев дороги, вероятно, вам подойдет какая-то пробная версия.