Общее·количество·просмотров·страницы

Java Dev Notes - разработка на Java (а также на JavaScript/Python/Flex и др), факты, события из АйТи

вторник, 16 июня 2009 г.

FindBugs

FindBugs - утилита-анализатор исходного кода на Java на наличие потенциально опасных конструкций в нем. Тулза сделана в Университете Мэриленда, распространяется под лицензией LGPL.

FindBugs отлавливает так называемые bug patterns - т.e. конструкции в коде, которые, скорее всего, являются ошибкой. Причем, для ее работы не обязательно иметь исходный код приложения - на самом деле она выполняет анализ байт-кода, используя для этих целей библиотечку Apache BCEL (ByteCode Engineering Library), которая уже упоминалась в этом сообщении. Таким образом, можно даже сторонние JARы проанализировать на наличие ошибок - FindBugs может обрабатывать JAR-, ZIP-файлы, и, конечно, class-файлы.

Установка сей тулзы подробно описана здесь. Я устанавливал FindBugs таким образом: скачал findbugs-1.3.8.zip c SourceForge.net, разархивировал его в каталог D:\tools\findbugs-1.3.8, установил переменную среды FINDBUGS_HOME=D:\tools\findbugs-1.3.8.

Далее мы разберем работу с FindBugs c использованием Ant. Кстати, у FindBugs есть также плагин к Eclipse. Но поскольку я являюсь сторонником использования командной строки (и особенно люблю Ant =) ), то именно совместное использование Ant & FindBugs - предмет данного поста.

FindBugs довольно требователен к памяти - в руководстве на сайте программы еще в первой главе отмечают, что для работы FindBugs потребуется минимум полгигабайта оператиной памяти, а лучше больше, конечно. При первых запусках на моей машине FindBugs выбрасывал исключение java.lang.OutOfMemoryError до тех пор, пока я не увеличил объем памяти, доступной JVM до 512Mb. В команде <findbugs> (о ней речь пойдет ниже) есть параметр jvmargs, который, как понятно из названия, содержит параметры, передаваемые JVM. Установив jvmargs="-Xmx512M" я избавился от java.lang.OutOfMemoryError.

Далее предполагается, что Ant установлен в каталог ANT_HOME, а FindBugs установлен в каталог FINDBUGS_HOME. Как я уже говорил, у меня на компьютере установлена переменная среды FINDBUGS_HOME=D:\tools\findbugs-1.3.8. Первым делом самолеты надо скопировать два файла FINDBUGS_HOME/lib/bcel.jar и FINDBUGS_HOME/lib/findbugs-ant.jar в каталог ANT_HOME/lib. Затем в файле сборки (build.xml) декларируется новая команда - <findbugs>:


<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"/>

Рассмотрим параметры команды <findbugs> (в таблице ниже перечислены не все параметры, а только самые важные, на мой взгляд):

















ПараметрОписаниеОбязательный
classДочерний элемент, указывающий, что именно анализировать. Должен содержать атрибут location, в котором указывается путь к анализируемому объекту. Это может быть директория, JAR или ZIP файл, class-файл. Тэг <findbugs> может содержать несколько дочерних элементов <class>. Пример:

<class location="${build.dir}"/>
<class location="resulted.jar"/>
<class location="Test.class"/>


Да
auxClasspathДочерний элемент, содержащий библиотеки, которые используются в анализируемом коде, но которые пользователь не будет анализировать. Этот элемент объявляется так же, как и classpath в команде <java>. Пример:
<auxClasspath refid="main.classpath"/>
- здесь идет ссылка на main.classpath, который ранее объявлен в файле сборки. Например, он может быть объявлен следующим образом:

<path id="main.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>

Нет
homeЭтот атрибут должен содержать имя каталога, где находится FindBugs. Пример:
<findbugs home="${findbugs.home.dir}">
Да
reportLevelЭтот атрибут определяет уровень ошибок, которые выводятся в файл результатов. Есть три уровня:
  • low - рапортуются все ошибки

  • medium - (значение по умолчанию) рапортуются только ошибки уровня medium, high

  • high - рапортуются только ошибки уровня high
Пример:
<findbugs reportLevel="low">
Нет
outputЭтот атрибут определяет формат файла отчета. Принимает следующие значения:
  • xml - (значение по умолчанию) формат XML. Файл отчета в этом формате можно затем открыть с помощью GUI-интерфейса

  • xml:withMessages - вывод в формате XML дополнен поясняющими сообщениями. Файл отчета в этом формате также можно затем открыть с помощью GUI-интерфейса. Этот файл с сообщениями можно затем обработать XSLT-процессором, чтобы получить, допустим, расширенный отчет в HTML.

  • html - вывод в формате HTML

  • text - вывод в текстовом формате

  • emacs - вывод в формате сообщений об ошибках, принятых в Emacs

  • xdocs - вывод в формате sdocs для дальнейшей обработки в Maven

Пример:
<findbugs output="xml:withMessages">

Нет
outputFileЭтот атрибут определяет имя файла отчета.

Пример:
<findbugs outputFile="${reports.file}">

Нет
jvmargsЭтот атрибут определяет параметры, передаваемые JVM. Чаще всего для анализа проектов следует увеличить память, доступную JVM. Делается это с помощью параметра -Xmx, пример:
<findbugs jvmargs="-Xmx512M">

Нет
failOnErrorЭтот логический атрибут определяет, следует ли останавливать процесс сборки, если в при проверке обнаружены ошибки. Принимает значения true/false, по умолчанию false
Нет
errorPropertyЭтот атрибут определяет имя свойства, которое будет установлено в true, если при проверке будут обнаружены ошибки. Пример:

<findbugs errorProperty="errors.present">

Нет
warningsPropertyЭтот атрибут определяет имя свойства, которое будет установлено в true, если при проверке будут сгенерированы предупреждения. Пример:

<findbugs warningsProperty="warnings.present">

Нет


Остальные параметры можно посмотреть здесь.

Теперь напишем цель для файла сборки, которая будет проверять наш (а может быть, и не наш) код на наличие ошибок.


<target name="findbugs" depends="compile">
<findbugs home="${findbugs.home.dir}" output="xml:withMessages" outputFile="${home.dir}/findbugs.xml" jvmargs="-Xmx512M">
<sourcePath path="${src.dir}" />
<class location="${build.dir}"/>
<auxClasspath refid="main.classpath"/>
</findbugs>
</target>


После прогона FindBugs по коду одного из проектов (который писал не я =))) ) командой

> ant findbugs

были получены, например, следующие сообщения (всего получено сообщений 261):

Class defines clone() but doesn't implement Cloneable
May expose internal representation by returning reference to mutable object
Comparison of String objects using == or !=
Class defines compareTo(...) and uses Object.equals()
int division result cast to double or float
clone method does not call super.clone()
Method concatenates strings using + in a loop
Unread field

+ куча сообщений по поводу неосовобождения ресурсов после их использования (незакрытые java.sql.PreparedStatement, java.sql.ResultSet и т.п.).

FindBugs имеет удобный графический интерфейс для просмотра файла отчета. На Windows для запуска GUI можно запустить файл FINDBUGS_HOME\bin\findbugs.bat, или выполнить команду

java [JVM arguments] -jar $FINDBUGS_HOME/lib/findbugs.jar options...


Просмотр ошибок в GUI выглядит следующим образом:



В общем, после такой проверки, я предложил использовать FindBugs в нашем стандартном цикле разработки на каждой девелоперской машине. Каждый девелопер перед коммитом своих изменений в SVN обязан проверить свой код с помощью FindBugs и исправить конструкции в коде, на которые FindBugs ругается. Мое предложение было принято, и я ожидаю, что качество кода в наших проектах повысится благодаря использованию этого инструмента.

Комментариев нет:

Отправить комментарий

Постоянные читатели