Введение
Сегодня в любой более-менее серьезной компании, где настроен 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 реализует широкий набор метрик, основанных на научных исследованиях и публикациях в области программной инженерии. Вот некоторые из них:
LCOM (Lack of Cohesion in Methods) — связность методов внутри класса
TCC (Tight Class Cohesion) и LCC (Loose Class Cohesion) — степень связности классов
CAMC (Cohesion Among Methods of Class) — степень пересечения списков типов параметров отдельных методов со списком типов всех методов в классе
MMAC (Method-Method through Attributes Cohesion) — средняя связность всех пар методов в программе на основе анализа типов параметров и возвращаемых значений
В отличие от 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.html
(и index.xml
) со ссылками на все метрики.


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
содержится следующая информация:
Параметр | Расшифровка |
| количество методов в классе |
| количество вызовов между методами |
| количество связанных пар методов |
| всего возможных пар методов |
Настройка 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 стал смотреть на архитектуру классов иначе. Попробуйте — это действительно стоит внимания.