Вступление

Java называют языком программирования. С формальной точки зрения это правда. На практике картина более широкая. Я часто люблю повторять, что Java -- это целая программная система для agile разработки. В ней можно выделить три ключевые подсистемы, которые работают одновременно:

  1. Система формальной верификации типов со строгими контрактами, дженериками и всей этой математикой про ковариантность и правила подстановки.

  2. Среда выполнения с линковщиком внутри JVM, который динамически связывает символические ссылки между загруженными библиотеками.

  3. Документация и ментальная модель, которую каждый разработчик выстраивает у себя в голове про то, как работают используемые библиотеки.

Поэтому когда автор библиотеки меняет сигнатуру метода, говорят что меняются не просто пара байтов в class-файле, а целый контракт (как технический, так и социальный). Да, это потенциальная проблема для линковщика, но о чём часто забывают, что это и удар по тому, как разработчик привык видеть "стабильный" API.

Инструментов для анализа версий библиотек сейчас хватает. Они умеют проверять бинарную совместимость, смотреть исходники, сравнивать сигнатуры. Всё это давно изучено и описано. JVM-спецификация чётко говорит, когда мы получим NoSuchMethodError, а когда код продолжит работать.

Но совместимость не сводится к вопросу «упадёт или не упадёт». Речь про то, как развивается API, как методы переезжают из класса в класс, как меняются иерархии и ответственность между ними. И главное -- понимает ли разработчик, что на самом деле произошло с библиотекой, которую он обновил.

Представьте: метод перенесли из подкласса в суперкласс. Большинство анализаторов покажут два факта:

  • метод удалён в подклассе;

  • метод добавлен в базовом классе.

Технически -- правда, но по сути это ничего не обьясняет. Есть такое понятие, как Human-Centered Design -- т.е. эмпатический подход к решению проблем, который ставит человеческие потребности и опыт во главу угла на протяжении всего процесса разработки продукта. Библиотеки и фреймворки есть такие же продукты, поэтому мне кажется очень важным так же применять практики человеко-ориентированного проектирования и в основной профессии Хабровчан, то есть инженерии ПО.

Поэтому я хочу рассказать про другой подход к аудиту версий Java-библиотек, который я применил при создании нового Аудитора. Инструмент, о котором пойдёт речь, умеет проверять и бинарную, и исходную совместимость, но не останавливается на этом. Он пытается распознавать рефакторинги по их смыслу и собирать человеко-читаемые отчёты на вики-страницах проекта. Цель -- дать потребителям ваших библиотек четко и лаконично понять, как эволюционировала сама структура, а не только точки линковки.

План следущий: сначала расскажу теорию, откуда происходят и что означают понятия исходной и бинарной совместимостей, обсужу, почему важен именно автоматический аудит при выпуске новых версий; затем на практическом примере java-protobuf покажу, как мой Аудитор справляется с задачами экзаменации и презентации изменений и чем он лучше других тулзов таких как japicmp, а также объясню, как грамотный подход к архитектуре решения делает его полноценным фреймворком с потенциалом для экспансии в другие ЯП.

Введение

Комментарии (0)