… Мне пришло в голову, что есть инструмент, который мог бы помочь с проблемой System.gc () . Он удачно называется FindBugs . На самом деле их несколько ( PMD и CheckStyle — другие, похожие инструменты), но FindBugs хорош, потому что вам на самом деле не нужен исходный код приложения для проверки на наличие ошибок. Все, что вам нужно, это файлы JAR и / или файлы классов. Еще одна замечательная особенность заключается в том, что каждый отчет очень хорошо документирован. Вы не просто получаете смутные предупреждения, от которых вы отказываетесь через несколько минут, но вы можете найти объяснение для каждого предупреждения в режиме онлайн .
Вот пример вывода FindBugs , когда вы запускаете его для зонда Java-монитора .
01
02
03
04
05
06
07
08
09
10
11
12
|
$ findbugs -textui -effort:max java-monitor-probes /build/WEB-INF/classes The following classes needed for analysis were missing: javax.servlet.http.HttpServlet javax.servlet.Filter javax.servlet.http.HttpServletResponse javax.servlet.ServletException javax.servlet.ServletConfig javax.servlet.FilterConfig javax.servlet.ServletRequest javax.servlet.ServletResponse javax.servlet.FilterChain Missing classes: 7 |
Из этого отчета вы можете видеть, что FindBugs не может найти никаких проблем с самим кодом. Есть несколько классов, от которых зависит код. Они не были включены в анализ. Поскольку это все классы, предоставляемые Sun, я предполагаю, что они не содержат ошибок. *кашель*
Так или иначе. Давайте сделаем анализ немного более сочным. Вот вывод при запуске FindBugs против известного драйвера MySQL JDBC. Я уверен, что многие из вас сегодня используют его в производстве. Этот код дает значительно больше результатов, и FindBugs занимает некоторое время для анализа всего пакета. Я показал только несколько строк из 154 предупреждений.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
$ findbugs -textui -effort:max mysql-connector-java-5.1.5-bin.jar ...... H C NP: Method call in com.mysql.jdbc.profiler.ProfilerEvent.pack() passes null for unconditionally dereferenced parameter of writeBytes(byte[], byte[], int) Method invoked at ProfilerEvent.java:[line 375] ...... M D NP: Possible null pointer dereference of s1 on path that might be infeasible in com.mysql.jdbc.ConnectionImpl.nullSafeCompare(String, String) Dereferenced at ConnectionImpl.java:[line 341] ...... M C NP: Method call in com.mysql.jdbc.DatabaseMetaData.getInstance(ConnectionImpl, String) passes null for unconditionally dereferenced parameter of new DatabaseMetaData(ConnectionImpl, String) Method invoked at DatabaseMetaData.java:[line 632] ...... H S SQL: Method com.mysql.jdbc.DatabaseMetaData.getColumnPrivileges(String, String, String, String) passes a nonconstant String to an execute method on an SQL statement At DatabaseMetaData.java:[line 2156] H S SQL: Method com.mysql.jdbc.DatabaseMetaData.getTablePrivileges(String, String, String) passes a nonconstant String to an execute method on an SQL statement At DatabaseMetaData.java:[line 4638] M S SQL: Method com.mysql.jdbc.ConnectionImpl.setSessionVariables() passes a nonconstant String to an execute method on an SQL statement At ConnectionImpl.java:[line 5074] ...... M M IS: Inconsistent synchronization of com.mysql.jdbc.CallableStatement.outputParameterResults; locked 50% of time Unsynchronized access at CallableStatement.java:[line 1948] M M IS: Inconsistent synchronization of com.mysql.jdbc.StatementImpl.wasCancelledByTimeout; locked 83% of time Unsynchronized access at PreparedStatement.java:[line 1756] ...... Warnings generated: 154 ...... |
Научиться читать вывод FindBugs занимает немного времени. Что я делаю, так это просто прорабатываю определенную ошибку или предупреждение, когда мне надоедает или разочаровывается код, который я должен писать. Это моя прокрастинация. ?
Я выбрал только то, что мне как разработчику кажется проблематичным: «пропускает ноль для безусловного разыменованного параметра». Ик. NullPointerException кто-нибудь? Конечно, это может быть тестовый код или даже неиспользуемый код, который все еще находится в стадии разработки. Как насчет этого: «передает непостоянную строку в метод execute для оператора SQL». Хм. Если этот флажок не установлен, это может быть причиной уязвимости SQL-инъекций.
Ранее я говорил, что FindBugs не требует от вас доступа к исходному коду приложения для поиска ошибок в нем. Просто для смеха, давайте посмотрим на один из краеугольных камней наших серверов приложений Java EE: драйвер Oracle JDBC.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
$ findbugs -textui -effort:max ojdbc6.jar ...... M B Dm: oracle.sql.ConverterArchive.openArchiveforRead() invokes System. exit (...), which shuts down the entire virtual machine At ConverterArchive.java:[line 375] M B Dm: oracle.sql.ConverterArchive.closeArchiveforRead() invokes System. exit (...), which shuts down the entire virtual machine At ConverterArchive.java:[line 390] ...... M B ES: Comparison of String objects using == or != in oracle.jdbc.connector.OracleConnectionRequestInfo.equals(Object) At OracleConnectionRequestInfo.java:[line 104] ...... H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateBlob(int, InputStream, long) At OracleCachedRowSet.java:[line 6365] H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateClob(int, Reader, long) At OracleCachedRowSet.java:[line 6445] H C IL: There is an apparent infinite recursive loop in oracle.jdbc.rowset.OracleCachedRowSet.updateNClob(int, Reader, long) At OracleCachedRowSet.java:[line 6535] ...... Warnings generated: 1028 ...... |
Этот водитель выдает не менее 1028 предупреждений. Ух ты. Я не утверждаю, что драйвер Oracle JDBC на самом деле является плохим фрагментом кода. Я просто нахожу, что это пахнет немного . ? Разработчики Oracle, возможно, захотят иметь дело с устранением предупреждений о сообщении findbugs. Там есть много небольших предложений по производительности и стабильности.
И да: findbugs проверяет использование System.gc () .
PS. Пожалуйста, имейте в виду, что я использовал FindBugs 1.3.7. В этой версии FindBugs есть ошибка, из-за которой он генерирует ложные срабатывания для очистки ресурсов базы данных .
PPS. Кого я шучу: я думаю, что драйвер Oracle плох. Бесконечные циклы? System.exit ()? Пожалуйста.
Всегда помогайте… нуждающемуся кодеру ?
Byron
Статьи по Теме: