Pull to refresh

jpeek – когда SonarQube мало

Level of difficultyEasy
Reading time5 min
Views2.4K

Введение

Сегодня в любой более-менее серьезной компании, где настроен CI/CD, используется SonarQube. Это уже стандарт де-факто. Он умеет определять code smells, дублирование, уровень покрытия тестами, распознавать недостижимый код и многое другое. Настроили, подключили к CI — и вроде бы все хорошо.

Но...

Иногда SonarQube оказывается недостаточно злым. Он легко пропускает:

  • классы с кучей скрытых зависимостей

  • запутанную бизнес-логику, размазанную по методам

  • высокий coupling при почти идеальных метриках на дашборде

А ведь в этих местах чаще всего прячется технический долг, который больно вылезает через полгода — как только нужно что-то поменять.

Для таких случаев есть инструменты другого уровня. Не про стилистику и правила, а про архитектурную сложность. Один из таких инструментов — jpeek. Он не заменяет линтер, не ругается на System.out.println() и не просит добавить javadoc. Зато он умеет в цифрах показать насколько код близок к объектно-ориентированному аду.

Про jpeek

Как было упомянуто ранее, jpeek — это инструмент для анализа Java-кода, разработанный с акцентом на оценку архитектурной сложности и структурной связности классов. В отличие от линтеров и статических анализаторов, jpeek фокусируется на объектно-ориентированных метриках, таких как сцепленность (cohesion) и связность (coupling), предоставляя разработчикам более глубокое понимание качества архитектуры их кода.

Основной контрибьютор jpeek – Егор Бугаенко. Сам узнал о jpeek после его курса Software Quality Metrics (SQM Crash Course).

Метрики jpeek

jpeek реализует широкий набор метрик, основанных на научных исследованиях и публикациях в области программной инженерии. Вот некоторые из них:

В отличие от SonarQube, PMD и других популярных инструментов, которые фокусируются на синтаксических ошибках, стилевых нарушениях и т.п., jpeek предоставляет глубокий архитектурный анализ, помогая выявить структурные проблемы в дизайне классов, которые могут привести к трудностям при масштабировании системы.

Кроме того, jpeek легко конфигурируется. Благодаря XSL-конфигам, добавление новых метрик или адаптация существующих становится относительно простым процессом.

Аналоги

Существуют и другие инструменты, предлагающие анализ архитектурных метрик:

  • CodeMR — плагин для IntelliJ IDEA, предоставляющий визуализацию метрик, таких как LCOM3, CAMC, LCAM и др.

  • SQMetrics — учебный проект для оценки качества Java-кода с учетом метрик NOC, LLOC, LCOM и др.

  • JProbe — очень древний анализатор (преимущественно для Java EE проектов)

Однако jpeek выгодно отличается своей ориентацией на научно обоснованные метрики, простотой интеграции и возможностью расширения, что делает его ценным инструментом для команд, стремящихся к высокому качеству архитектуры своих Java-проектов.

Пример работы

Для демонстрации я взял небольшой Java-проект — jcabi-http, библиотеку с теми же контрибьюторами, что и jpeek. Проект простой, но с интересной структурой классов, что как раз подходит под анализ архитектуры.

Чтобы подключить jpeek, можно добавить maven-plugin в pom.xml:

<build>
  <plugins>
    <plugin>
      <groupId>org.jpeek</groupId>
      <artifactId>jpeek-maven-plugin</artifactId>
      <version>1.0.0</version>
      <executions>
        <execution>
          <goals>
            <goal>analyze</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Запускаем:

mvn clean compile jpeek:analyze

После выполнения плагина в папке target/jpeek появятся отчеты — один HTML-файл и один XML-файл на каждую метрику. Также сгенерируется index.htmlindex.xml) со ссылками на все метрики.

Главная страница HTML-отчета
Главная страница HTML-отчета
HTML-отчет по метрике CCM
HTML-отчет по метрике CCM

XML-отчет по метрике CCM выглядит следующим образом:

<package element="false" id="com.jcabi.http.response">
     <class color="red"
            element="true"
            id="JsonResponse$VerboseReader"
            value="0.25">
        <vars>
           <var id="methods">4</var>
           <var id="nc">6</var>
           <var id="ncc">4</var>
           <var id="nmp">6</var>
        </vars>
     </class>
     ...
</package>

Из отчета видно, что для внутреннего класса JsonResponse.VerboseReader значение CCM=0.25, что говорит о том, что методы класса тривиальны (без условий и ветвлений). В блоке vars содержится следующая информация:

Параметр

Расшифровка

methods

количество методов в классе

nc

количество вызовов между методами

ncc

количество связанных пар методов

nmp

всего возможных пар методов

Настройка CI

На момент написания статьи jpeek не предоставляет встроенных валидаторов. То есть, он генерирует метрики, но не говорит, что плохо, а что хорошо. Именно поэтому придется писать валидацию самостоятельно, под конкретный проект.

У меня когда-нибудь обязательно дойдут руки написать удобный валидатор для jpeek. Но пока можно обойтись простым питоновским скриптом вида:

import xml.etree.ElementTree as ET
import sys

# Пороговые значения метрик (определяются эмпирически для проекта)
thresholds = {
    'SCOM': 0.5,
    'LCOM2': 0.3,
    'CCM': 0.4  #  можно добавить еще метрик
}

report_path = 'target/jpeek/index.xml'

try:
    tree = ET.parse(report_path)
    root = tree.getroot()
except Exception as e:
    print(f"Can't read jpeek report: {e}")
    sys.exit(1)

for metric_name, max_defect in thresholds.items():
    metric = next((m for m in root.findall('metric') if m.get('name') == metric_name), None)
    if not metric:
        print(f"Can't find {metric_name} in report")
        continue

    try:
        defects = float(metric.get('defects', '0'))
    except ValueError:
        print(f"Invalid defects value for {metric_name}")
        continue

    print(f"{metric_name}: defects = {defects}; maximum value = {max_defect})")
    if defects > max_defect:
        print(f"{metric_name} validation failed")
        sys.exit(1)

print("jpeek validation passed successfull")

И дальше из CI можно вызвать:

python3 validate_jpeek.py

Заключение

SonarQube — отличная штука. Он действительно закрывает 90% проверок по качеству кода, распознавая возможные NPE, уязвимости и дублирование кода. Но если хочется получить более подробные и научно обоснованные отчеты, то без метрик вроде LCOM, CAMC или SCOM уже не обойтись.

Именно тут на сцену выходит jpeek — инструмент, который не заменяет привычные линтеры и анализаторы, а дополняет их. Он смотрит не на стиль, не на баги, а на структуру и связность кода.

Интеграция jpeek не требует большого количества усилий. А результаты, которые он дает, вполне можно превратить в часть CI.

Лично я после знакомства с jpeek стал смотреть на архитектуру классов иначе. Попробуйте — это действительно стоит внимания.

Only registered users can participate in poll. Log in, please.
Используете ли анализаторы кода помимо SonarQube?
70% Только SonarQube21
16.67% Даже SonarQube не используем5
0% jpeek0
0% CodeMR0
0% JProbe0
13.33% Другое4
30 users voted. 5 users abstained.
Tags:
Hubs:
+2
Comments5

Articles