Эту печальную историю стоит прочесть всем, кто еще не понял разницы между «создать» и «владеть» применительно к программному обеспечению.

Заодно узнаете, чем на самом деле занимаются большинство разработчиков на крупных проектах.

Виновник торжества в работе. Слева.
Виновник торжества в работе. Слева.

«Карпати, один из самых влиятельных людей в мире AI, собрал второй мозг на LLM. А ты до сих пор какой-то фигней занимаешься» — из отзывов.

Осенью 2012 года, устав ругать разработчиков за обмен корпоративными исходниками через публичный Pastebin, решил сделать его аналог, для внутреннего использования.

Так появился проект «Пастер», существующий до сих пор.

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

Идея

Как уже было упомянуто выше, главной идеей проекта была легковесная, развертываемая локально замена известному сервису Pastebin:

берется кусок кода, выдержка из логов, цитата древнегреческого философа или еще что-то такое непонятное — условно «паста», вставляется в специальную веб-форму и сохраняется.

Затем генерируется ссылка для просмотра, которая отправляется через мессенжеры всем заинтересованным лицам. Через какое-то время устаревшие записи удаляются.

Все просто.

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

Толщина линий специально сделана переменной длины, чтобы создавался эффект росчерка пером.
Толщина линий специально сделана переменной длины, чтобы создавался эффект росчерка пером.

Проектов, реализующих подобную идею в том или ином виде — как говна за баней очень и очень много. В Пастере тоже нет ничего нового или уникального, такой фунционал легко повторяем, а в 21м веке подобную штуку может сгенерировать любая приличная нейросеть.

Но как обычно есть нюанс:

как брак не заканчивается на свадьбе, так и программный проект не заканчивается на разработке.

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

Одна из первых версий, 2013 год. За фоновую картинку с голой бабой меня долго ругали тестировщицы ;)
Одна из первых версий, 2013 год. За фоновую картинку с голой бабой меня долго ругали тестировщицы ;)

Особенности реализации

Стоит сразу сказать, что «Пастер» никогда не был коммерческим проектом и всю свою 14 летнюю историю представлял из себя внутренний инструмент, разрабатываемый в свободное время и с чисто прикладными задачами.

Поэтому технологии для реализации проекта выбирались из того что было под рукой (например знаменитый в те годы Appfuse — предок JHipster) или из тех технологий, что были интересны автору.

Это кстати характерный штрих, поскольку именно из таких опций (интерес и наличие под рукой) чаще всего происходит выбор технологического стека на практике. Все эти ваши «оптимально для выбранной задачи», «применимость» или «успешные кейсы» остаются обычно на уровне презентации.

В итоге получился весьма занятный франкенштейн комбайн:

классический Spring-Hibernate-JSP стек, где вместо Java использовалась более интересная Scala

Были попытки обойтись и без СУБД, но довольно быстро выяснилось, что сопровождать на длинной дистанции физическое хранение и процесс записи на диск в рамках прикладного проекта слишком накладно. Хотя начальная разработка безусловно была проста и красива.

Не взлетела и реализация с хранением записей только в памяти — все закончилось на первом же обновлении:

внезапно оказалось, что утрата всех записей разом это не очень хорошо для пользователей.

Даже если записи считаются временными.

Примерно по той же причине сильной недооценки важности пользовательских данных отказались и от нереляционных СУБД и от попыток хранения записей в файлах и поисковых индексах.

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

Первые публичные коммиты.
Первые публичные коммиты.

Репозиторий

Практически все время — все 14 лет разработка Пастера велась в одном и том же публичном репозитории на Github.

Но ввиду загруженности по основным проектам — далеко не всегда получалось создавать нормальные коммиты с описанием функционала, так что треша внутри хватает.

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

Выбор Scala

Хотя Scala на 2012й год была весьма стабильной и для Пастера использовалась уже 2.х версия языка — связку Scala + Spring + Hibernate, где существенная часть логики связана с обработкой аннотаций на клиентских классах, на практике мало кто использовал.

Поэтому мы вдоволь наелись самых экзотических ошибок, выясняя методом разбитого лба как ведут себя сканеры классов Spring и Hibernate при обработке байткода, созданного компилятором Scala.

Для примера, далеко не сразу выяснилось, что у полей Entity класса, реализованного на Scala должно быть значение по-умолчанию:

@ManyToOne(fetch = FetchType.EAGER,cascade= Array(CascadeType.PERSIST,CascadeType.MERGE))
@JoinColumn(name = "owner_id")
private var owner:User = null

Были проблемы с типами данных, с наследованием классов, с перечислениями (enum), с аннотациями — удалось собрать наверное все возможные проблемы совместимости Java и Scala с точки зрения прикладного проекта.

Кстати на момент создания Пастера, существовала только одна реализация Scala — на базе JVM и компиляцией в байткод, компиляторы в JavaScript (Scala.js) и нативный код появились позже. Так что технически Пастер работал и работает на обычной JVM, хотя его исходный код (бекэнд) написан на Scala.

История с Maven

Традиционной для проектов на Scala системой сборки считается sbt — такая своеобразная штука, больше всего похожая на Gradle, но использующая «Scala-based DSL» вместо Groovy в качестве языка сценариев.

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

Это сейчас проект на sbt легко подхватывается и на CI-сервере и в любой современной IDE, но в 2012м все было сильно хуже.

Вторым важным нюансом, повлиявшим на выбор была сложность сборки.

Даже в первой версии Пастера, выложенной на Github можно можно увидеть интеграцию с системой контроля качества кода SonarCube, генерацию номера сборки, поддержки нескольких разных СУБД и двух сервлет-контейнеров.

Повторить все это на sbt было откровенно непростой задачей.

Впрочем о выборе стандартного Maven в качестве средства сборки ни разу за 14 лет пожалеть не пришлось, благо этот проект удивительно стабилен и предсказуем.

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

Падение Compass Search

Проект «Compass Search» был далеким предком современного и известного ElasticSearch от того же автора:

The Compass Framework enables the power of Search Engine semantics to your application stack declaratively. Built on top of the amazing Lucene Search Engine, Compass integrates seamlessly to popular development frameworks like Hibernate and Spring.

На данный момент проект полностью заброшен и даже сайт уже не существует.

Тут можно посмотреть сохраненную копию документации, тут находится неофициальный форк исходников Compass Search, судя по датам созданный еще при жизни проекта.

Меньше, проще и с более интересным функционалом, чем у известного Hibernate Search, Compass казался отличным вариантом в качестве встраиваемого поискового движка для нашего Пастера.

Только мы не подозревали, что автор этого замечательного фреймворка давно все решил:

Developing a third version of Compass, he concluded that a full rewrite was necessary to build a scalable, distributed search solution using JSON over HTTP as a common interface.

Несмотря на дату сохраненного поста (2010 год), проект Elasticsearch еще довольно долго не был известен широкой публике, а сам автор не отказывался от поддержки «Compass Search».

Но уже к 2014му году проект «Compass Search» оказался полностью заморожен.

Вот так просто и на ровном месте мы оказались с мертвым фреймворком внутри нашего проекта, от которого зависел ключевой функционал поиска. 

С большой (по меркам прикладного проекта) и теперь уже мертвой кодовой базой, которая начинала портиться.

Compass Search зависел от множества внешних библиотек: Hibernate, Spring, генераторы байткода, обработчики аннотаций — все это быстро ехало вперед, постоянно выходили новые релизы, ломающие обратную совместимость. Поддерживать самостоятельно кодовую базу умершего Compass Search становилось все труднее.

Полностью избавиться от трупа Compass и переехать на Hibernate Search нам удалось лишь через пять лет и далеко не с первой попытки, убив перед этим несколько лет на поддержку умершего фреймворка.

Но это был далеко не конец.

Падение Apache Tiles

К сожалению описанные выше проблемы и беды с «Compass Search» были далеко не единственными. В Пастере использовался еще один интересный фреймворк, также успевший помереть за время жизни проекта:

A free open-sourced templating framework for modern Java applications.Based upon the Composite pattern it is built to simplify the development of user interfaces. For complex web sites it remains the easiest and most elegant way to work alongside any MVC technology.

Тут стоит пояснить подрастающему поколению, видевшему серверный шаблонизатор страниц только в виде SSR, что Apache Tiles добавлял один ключевой функционал, которого по какой-то причине не было в технологии Java Server Pages (JSP) — вложенность.

Нормальные веб-разработчики всегда отделяли шаблон страницы от ее содержимого и одно вставлялось в другое на этапе рендеринга.

Так это работало и работает во всех популярных фреймворках, включая ваши любимые Angular, Vue и React. И только в JSP решили, что будет достаточно лишь явно включать отдельные части. Поэтому любая страница на чистом JSP выглядит примерно так:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
   <!-- кусок HTML с заголовком -->
   <c:import url="header.jsp" />
</head>
<body>
  <!-- содержимое страницы -->
   <%@include file="body.jsp"%>
</body>
<footer>
   <!-- кусок HTML с футером -->
   <jsp:include page="footer.jsp" />
</footer>
</html>

Повторюсь, что такая дичь с указанием всех включаемых частей должна быть на каждой странице JSP, если только не использовать внешний фреймворк, реализующий композицию.

Нетрудно догадаться, что сопровождение проекта и рефакторинг при таких вводных быстро превращается в кромешный ад.

Поскольку ада и так хватало в коммерческой разработке, добавлять его еще и в домашний проект было излишим. Поэтому был подключен Apache Tiles, решающий эту проблему с композицией.

Композиции указывались в специальном конфигурационном файле, где сначала описывался шаблон страницы:

<definition name=".mainTemplate" 
      template="/WEB-INF/pages/template/main.jsp" 
      preparer="uber.paste.tiles2.ELViewPreparer">
    <put-attribute name="pageTitle"  expression="${requestScope.title}" />
    <put-attribute name="menu" value="/WEB-INF/pages/template/menu.jsp" />
    <put-attribute name="content" value="" />                
</definition>

А затем сами страницы, использующие этот шаблон:

<definition name="/paste/list" extends=".mainTemplate">
      <put-attribute name="content" value="/WEB-INF/pages/paste/list.jsp" />
</definition>

На выходе рендера получалась готовая страница, на уровне кода — разделение на общий шаблон и шаблон отдельной страницы.

С учетом поддержки прекомпиляции JSP-страниц, решение было еще и весьма производительным — фактически самые быстрые страницы на Диком Западе.

Точно быстрее любой реализации JSF и тем более чистых парсеров вроде Velocity или Freemarker.

И все были счастливы и довольны, пока не закачался трон под самим JSP — случилась «утрата интереса к технологии» (отчасти искусственная, организованная ради перехода на JSF), с чего будущее проекта Apache Tiles внезапно стало туманным.

К 2017 году проект «Apache Tiles» оказался полностью заморожен.

Что характерно, обе технологии нижнего уровня — JSP и JSF продолжают развиваться и все также остаются частью стандарта JakartaEE, но зависимый от них «Apache Tiles» зиму не пережил.

С «Apache Tiles» случилась еще одна беда, предсказуемо последовавшая за заморозкой проекта — из Spring выкинули его интеграцию. Причем случилось это на весьма небольшом временном отрезке — всего за пару лет жизни Пастера.

Удаление интеграции означало невозможность дальнейшего использования Apache Tiles в проекте, начиная с определенной версии Spring.

А дыры в безопасности при всем этом никто не отменял — оставлять устаревшие версии Spring ныне не дает даже Github, задалбывая уведомлениями о «страшных ошибках в безопасности».

На этот раз, ввиду небольшого объема «Apache Tiles» было принято решение его форкнуть и поддерживать своими силами:

благодаря мощному движку для рефакторинга в Intellij Idea удалось выкинуть из Apache Tiles все лишнее, заодно портировав на современную Jakarta.

Слой интеграции со Spring MVC был переписан целиком на Scala. Разумеется это отняло много времени и сил, но других разумных вариантов попросту не нашлось.

Например переезд на стандартный для современного Spring Boot фреймворк Thymeleaf означал бы полное переписывание всех JSP-страниц с нуля. Плюс падение производительности, поскольку Thymeleaf заметно медленнее JSP.

Но это еще не все несчастья, собранные Пастером за годы жизни.

Падение Mootools

Mootools когда-то был вторым по популярности веб-фреймворком после jQuery в мире веб-разработки:

MooTools is a compact, modular, Object-Oriented JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write powerful, flexible, and cross-browser code with its elegant, well documented, and coherent API.

Он был заметно легче jQuery, поэтому был популярен среди продвинутых веб-разработчиков, особенно отечественных. Поэтому именно Mootools был взят за основу для создания JavaScript-логики в Пастере, которой с самого начала было очень много.

Вообще с JavaScript-частью случился однажды неприятный конфуз, приведший к срыву переговоров и потере потенциального клиента. По какой-то причине GitHub не смог адекватно распознать используемые технологии, поэтому в плашке проекта до сих пор висит только JavaScript:

Когда мы показывали Пастер потенциальному заказчику в качестве примера проекта на Scala — тот подумал, что мы его обманываем, пытаясь подсунуть какую-то хрень на Node.js.

Но вернемся к истории с Mootools.

Хотя к тому времени появилась первая версия знаменитого Angular (тогда еще AngularJS), вызвавшая немалый интерес у веб-разработчиков, столь резкого падения проекта Mootools не ожидал никто. 

Тем более что его аналог — jQuery жив и развивается до сих пор.

Mootools активно использовался в популярных движках CMS, CRM, блогов, в открытых и коммерческих проектах.

В 2013 году Mootools встречался повсеместно, но уже к 2015 — полностью пропал.

Можно разумеется пытаться искать причины и подбирать тайные смыслы, но повторюсь:

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

В итоге получилось, что примерно 40% кодовой базы проекта (практически весь фронтэнд) напрямую зависела от ключевого фреймворка, который приказал долго жить.

Попробовав разные варианты, вдоволь наигравшись с разными версиями Angular и их замечательной совместимостью, к 2020му году пришли к выводу, что стоит полностью отвязаться от больших фреймворков и переделать фронтэнд на чистый ES6.

Благо его поддержка (пусть и не полная) к тому времени появилась во всех основных браузерах и работала уже без транспилеров.

Часть библиотек, зависимых от Mootools, например LazyPagination была переписана на чистый ES6, часть заменена на аналоги, часть просто выкинута.

Вот так постепенно, маленькими шажками удалось избавиться от Mootools, хотя на весь процесс ушел примерно год.

Спросите, почему не взяли Angular/React/Vue ?

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

Только вам об этом конечно никто не расскажет.

Как-то так эта библиотека выглядела в оригинале.
Как-то так эта библиотека выглядела в оригинале.

Падение SyntaxHighlighter

Жил-был на свете (в солнечной Калифорнии) отличный разработчик Alex Gorbatchev, создавший в 2004м году уникальную и очень популярную библиотеку для подсветки синтаксиса, которая так и называлась «Syntax Highlighter».

Написано все было на чистом JavaScript и без внешних зависимостей а уникальна библиотека в первую очередь своей производительностью:

это фактически единственная библиотека, осиливающая подсветку синтаксиса для мегабайта кода без подвисания браузера.

Не каждый нативный редактор с таким справляется в 2026 году, а тут какая-то библиотека на JavaScript.

К сожалению со временем автор потерял интерес к собственному детищу и к 2016 году разработка проекта «Syntax Highlighter» была прекращена. Вот тут находятся исходники последней релизной 3.х версии, четвертую, которая находится в том же репозитории автор так и не выпустил.

Что характерно, история «Syntax Highlighter» закончилась на попытке переписать на Typescript. Совпадение?

Да, мы тоже использовали эту замечательную библиотеку в Пастере.

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

Со временем форкнутый код подвергся большим изменениям:

ненужный для Пастера функционал был удален, код почищен, добавлена специфичная логика и нынешняя версия уже сильно отличается от оригинала.

Хотя конечно с точки зрения проектного управления и ресурсных трат это был полный провал:

Syntax Highlighter — сложная библиотека, написанная профессионалом и разобраться в ее внутреннем устройстве удалось далеко не сразу.

В коммерческом проекте я бы такое делать не стал.

Так выглядит запуск последней версии Пастера с помощью встроенного Jetty 12
Так выглядит запуск последней версии Пастера с помощью встроенного Jetty 12

Ужасы Jetty и Spring Boot

На момент начала работы над Пастером, концепция «пихаем все в один большой запускаемый JAR» еще не стала массовой.

Конечно с таким подходом активно экспериментировали, например в знаменитом Jenkins, но стандартом пока еще оставалось развертывание в сервлет-контейнере или на сервере приложений, задача настройки которых была на совести сисадмина, а не разработчика.

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

Spring Boot появится только в 2014м и на фоне возрастающего интереса к микросервисам, быстро приучит Java-разработчиков к тому, что пихать целиком сервлет-контейнер в каждое отдельное приложение это нормально. Даже если таких приложений больше сотни, а отличаются они лишь набором методов выдаваемого API.

Первые установки Пастера были в обычном Apache Tomcat или Eclipse Jetty, а само приложение поставлялось в виде WAR-файла, который надо было закидывать в специальный каталог для развертывания.

Так что вся цепочка была слишком сложной для столь простого проекта:

  • Установка JDK (обычные JSP-страницы на JRE не работали);

  • Установка сервлет-контейнера Tomcat или Jetty;

  • Копирование приложения Пастера в специальный каталог webapps;

  • Запуск сервлет-контейнера.

Добавьте сюда особенности настройки сервлет-контейнеров и проблемы совместимости между Tomcat/Jetty разных версий — поймете, что сил на поддержку уходило немеряно. Со временем изменилось и окружение:

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

Требовалось серьезное упрощение.

Конечно мы экспериментировали и со Spring Boot, тем более что параллельно шли коммерческие проекты с его использованием. Но оказалось, что поддержка JSP в случае приложения на Spring Boot откровенно хромает и чинить ее никто особо не собирается:

команда Spring активно продвигала Thymeleaf как полную замену «устаревшему» JSP, хотя тот был и остается частью спецификации JEE/JakartaEE, а Thymeleaf — непонятная приблуда, ни с чем не совместимая.

С точки зрения Spring все было разумеется прекрасно, поскольку Thymeleaf идеально вписывался в экосистему фреймворка и был полностью подконтролен. Собственно развитие Thymeleaf до сих пор происходит под чутким руководством ребят из Spring и каким-то удивительным образом используется Thymeleaf по большей части только в составе Spring.

Ну а мы — простые исполнители получили очередную нерешаемую проблему, хотя и не эксклюзивную: отголоски всех этих разборок с упаковкой приложения можно обнаружить например в знаменитой Atlassian Jira, в ее self-hosted версии.

Вообще на свете до сих пор существует довольно много разных CMS/CRM/ERP систем и портальных движков, чья разработка началась еще в начале 2000х и где присутствует эта проблема с развертыванием.

Мы же дети советских инженеров решили пойти особым путем — попытаться забороть проблему загрузки JSP и сканирования TLD-файлов без распаковки WAR.

Долго и внимательно изучая механизм загрузки классов в Jetty и «черную магию» Spring Boot с многоступенчатой загрузкой классов, удалось-таки создать работающее решение.

Ушло всего-то пару лет.

Зато теперь мы полностью контролируем весь процесс запуска, при этом сам Пастер все также остается стандартным сервлет-приложением и легко может быть развернут в обычном Apache Tomcat.

Так выглядел Пастер в 2014м году, кастомизацию фона с тех пор решили убрать.
Так выглядел Пастер в 2014м году, кастомизацию фона с тех пор решили убрать.

Мертвые фичи

За годы работы Пастера, добавлялись и удалялись самые разные фичи, часто уводившие проект сильно далеко от основной задачи.

Думаю рассказ о том, какой функционал «не пережил зиму», оказавшись неактуальным на длинной дистанции будет весьма показателен — уверяю в вашем проекте причины удаления фич будут похожими.

Отображение в офисные форматы

В Spring MVC еще с тех лет, когда разработка Пастера только начиналась существует интересный функционал, позволяющий выдавать из слоя View (V — в аббревиатуре MVC) не только стандартные HTML, XML или JSON, но и другие форматы данных: PDF, DOCX, XLS и так далее.

С его помощью были реализованы генераторы в docx для записей и в xlsx для списков и поиска — можно было получить результат поиска и фильтрации сразу в виде документа Microsoft Excel.

Почему не взлетело:

простой текст, вставленный в подготовленный шаблон документа Microsoft Word оказался мало актуальным а полноценное превращение текста в документ — с абзацами и форматированием требовало слишком больших ресурсов.

Та же самая история повторилась и с форматом Excel — без существенных затрат на разработку сложного шаблона с типами данных, статистикой и аггрегацией полей все это не имело практического смысла. Но фича красивая да.

Интеграция с почтой

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

Почему не взлетело:

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

Итеграция со Skype

С помощью неофициального API, имитирующего веб-клиент, были реализованы оповещения о новых записях Пастера в Skype — некий аналог современного Телеграм-бота.

Почему не взлетело:

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

К тому же к 2018 году пришел Телеграм, в который очень бысто перетекла вся рабочая переписка, а скайп стал постепенно умирать.

Телеграм принес с собой новую культуру отказа от раздражителей и теперь любые оповещения стали восприниматься как отвлекающий фактор. Поэтому на сегодня мы от них полностью отказались.

Авторизация через социальные сети

Когда-то в Spring был дочерний проект, посвященный авторизации через социальные сети:

The Spring Social project enables your applications to establish Connections with Software-as-a-Service (SaaS) Providers such as Facebook and Twitter to invoke APIs on behalf of Users.

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

Мы использовали Spring Social в Пастере для авторизации через социальные сети: Google, VK, LinkedIn и это даже работало, включая связывание разных профилей.

Почему не взлетело:

Использование Spring Social было частью концепции облачного использования Пастера для публичных проектов — хотели сделать что-то типа Github в плане коллаборации.

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

Смерть проекта Spring Social окончательно похоронила эту идею и возвращаться к ней в современных реалиях откровенно бессмысленно.

Интеграция с Jira

Одна из самых долгоживущих интеграций была с знаменитым багтрекером Atlassian Jira. Специальный плагин, устанавливаемый в Jira подтягивал на странице детализации записи из Пастера, связанные с просматриваемой задачей.

Таким образом сам трекер не захламлялся кусками логов и трассировками ошибок.

Почему не взлетело:

Проектов, использующих Jira становилось все меньше, а там где она еще использовалась — нам не давали доступ для установки плагина.

Нашим внутренним трекером постепенно стал Redmine, так что интеграция потеряла всякую актуальность.

Интеграция с файловым хранилищем

Помимо обмена кусками кода через публичные сервисы, с разработчиками была еще одна проблема — постоянное перекидывание файлов через публичные сервисы. Народ запросто выкладывал фактически в публичный доступ бинарные сборки, скрипты, библиотеки, логи и конфиги. Вплоть до сканов собственных паспортов.

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

Поскольку оба проекта работали одновременно, логично было их интегрировать. Что в итоге и произошло: со стороны Пастера появился специальный виджет, позволяющий цеплять файлы к записи, либо просматривать существующие.

Со стороны хранилища работала версионность, поэтому можно было легко отслеживать изменения.

Почему не взлетело:

со временем концепция обмена файлами при командной разработке поменялась и мы в итоге пришли к Телепорте

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

Исходники этого проекта находятся в одном репозитории с Пастером и все еще доступны в старых версиях.

Туманное будущее

На момент написания этой статьи готовится новый релиз Пастера — с переездом на Jakarta 11, обновлением всех используемых библиотек и мелким рефакторингом.

Немедленно выяснилось, что в Spring 7 решили полностью отказаться от логики «Content Negotiation» — переключение типа выдаваемых данных в зависимости от расширения файла (одна из ключевых фишек Пастера) будет полностью похоронено.

Никакаких альтернатив разработчиками Spring предложено не было и что теперь с этим делать не очень понятно.

Одновременно с этим разработчики Scala грозятся похоронить 2.х ветку и начать переводить всех в принудительном порядке на Scala3 — фактически другой язык. Конечно же без альтернативных вариантов.

Конечно и с этим мы тоже справимся, вопрос как обычно лишь в сроках и масштабе работ. Вполне возможно, что придется отказаться от Spring целиком.

Эпилог

Перед вами история небольшого внутреннего проекта, поддерживаемого пусть и по остаточному принципу, но на протяжении последних 14 лет. В его разработке никогда не участвовало больше трех человек одновременно, функционал весьма ограничен а решаемая задача проста и очевидна.

Тем не менее, даже при таких вводных поддержка на длинной дистанции превратилась в остросюжетный боевик про зомби и апокалипсис.

Пусть где‑то там далеко Андрей Карпати в очередной раз генерирует нейросеть нейросетью или находит своим третьим глазом путь в другие измерения — к обычной повседневной разработке все это не имеет отношения.

Чтобы система продолжала работать и крутились колеса разработки, ее надо постоянно поддерживать в рабочем состоянии, постоянно решая тысячи проблем.

Именно долгорочная проддержа сейчас, во времена открытого кода означает владение программным продуктом. Поэтому постоянно умирают независимые форки, дистрибутивы и сборки, поэтому у вас не получится «просто взять и скопировать» чужой проект, даже с помощью нейросетей — на длинной дистанции все это не работает.

Мы в полной мере владеем Пастером, не просто создав но и поддерживая его на протяжении последних 14 лет, можете ли вы сказать так о вашем проекте?