## Java проверки checkstyle в аркадии
[Пост в этушке](https://clubs.at.yandex-team.ru/java/746)
TODO: перенести сюда

## Работа с contrib/java в arcadia
[обсуждение в Этушке](https://clubs.at.yandex-team.ru/java/292)

К Java-библиотекам применяются все [общие правила по сontrib](https://wiki.yandex-team.ru/devrules/overall/contrib)

Все Java-библиотеки, доступные для сборки через ```ya make``` в Аркадии, хранятся в виде дескрипторов в
[директории](https://a.yandex-team.ru/arc/trunk/arcadia/contrib/java) (сами артефакты лежат в sandbox).
Есть техническая возможность импортировать (например, из Maven Central) любую библиотеку,
используя команду ```ya maven-import``` и закоммитить в contrib.

+ Все библиотеки разбиваются на 3 группы:
  - **рекомендованные** к использованию — список библиотек будет пополняться на wiki странице. Это библиотеки,
    по которым имеется экспертиза в компании, и они должны быть дефолтом для построения новых проектов (с аргументацией)
  - **запрещённые** к использованию — список библиотек будет пополняться на wiki странице. Это библиотеки,
    которые не следует использовать в проектах, так как они или имеют известную проблему, или у них есть хорошие аналоги
    в списке рекомендованных или разрешенных  (с аргументацией)
  - **разрешённые** — библиотеки из директории contrib/java
+ Java-комитет начинает собирать список рекомендованных к использованию в новых проектах библиотек:
  - в список попадают библиотеки и фреймворки, решающие поставленную задачу лучше других, распространенные в индустрии
    и по которым в компании есть хорошая экспертиза
  - аналогично списку рекомендованных библиотек также будет собираться список и аргументация для проблемных зависимостей,
    которые запрещены к использованию
+ На директорию contrib/java добавляется код ревью:
  - SLA 2 рабочих дня, по истечении которых изменение можно считать согласованным
  - за ревью будет ответственна команда комитета
  - в рамках ревью для каждой библиотеки будет пройден базовый чеклист, например:
    * проверка лицензии
    * анализ транзитивных зависимостей на предмет известных конфликтов и проблемных библиотек
    * активность проекта и комьюнити
    * при необходимости консультация СИБ
  - в случае наличия аналога в списке рекомендованных коммитеру вероятнее всего зададут вопрос, почему нельзя использовать
    уже имеющуюся библиотеку
+ Если библиотека успешно прошла код ревью в contrib/java, то она автоматически становится разрешенной к использованию
   и при необходимости добавляется в список рекомендованных
+ Транзитивные зависимости импортируемой библиотеки также автоматически добавляются в contrib/java,
но для них могут быть следующие варианты:
  - библиотека является рекомендованной или разрешенной — всё ок, проблем нет
  - библиотека имеет известную зафиксированную проблему и не должна использоваться — в этом случае коммитеру стоит
    задуматься о необходимости использования у себя библиотек с сомнительными зависимостями, но если необходимость
    действительно есть, то для такой транзитивной библиотеки средствами инструмента сборки будет проставлен запрет
    на прямую зависимость в модулях (требуется доработка инструмента)

## Стратегия работы с зависимостями в мире Java в Аркадии
[обсуждение в Этушке](https://clubs.at.yandex-team.ru/java/448)

Есть задача гарантии совместимости общих библиотек яндекса между собой, чтобы подключать их было легко и удобно.
Один из аспектов совместимости является то, что все 3d-party зависимости общих библиотек не должны конфликтовать друг с другом.
Для того, чтобы это обеспечить, сделан общий dependency management list для
[общих библиотек](https://wiki.yandex-team.ru/devrules/Java/CommonLibraries/), в котором определены единые версии всех
3d-party зависимостей, а в самих общих библиотеках для указания зависимостей должны использоваться только артефакты без версий.
Dependency management list опубликован в аркадии [тут](https://a.yandex-team.ru/arc/trunk/arcadia/library/java/dependency_management.inc),
а [директория](https://a.yandex-team.ru/arc/trunk/arcadia/library/java/) это дом для общих библиотек, с едиными правилами разработки.

Текущие правила добавления библиотек в ```dependency_management.inc```
* библиотека является зависимостью для одной из общих библиотек в ```library/java``` (текущий состав - это базовые либы, которые точно пригодятся)
* вместе с требуемой зависимостью также фиксируются версии всего бандла библиотек
* все библиотеки в списке входят в список рекомендованных или разрешенных (см. [детали](https://wiki.yandex-team.ru/devrules/Java/Contrib/))

Для конечных сервисов остается свобода в виде использования или не использования общих списков зависимостей и предлагается
решить этот вопрос внутри команды. Возможные варианты могут быть - это использование списка зависимостей на:
* группу тесно связанных модулей
* команду
* сервис
* и т. п.

В качестве рекомендации проектам, планирующим зависимости от общих библиотек, предлагается добавить инклуд в свой проект файла ```dependency_management.inc``` следующим макросом:
```
INCLUDE(${ARCADIA_ROOT}/library/java/dependency_management.inc)
```

## Рекомендации по использованию библиотек для решения стандартных задач
### Глоссарий
- **рекомендованные** — те библиотеки, которые мы рекомендуем новым проектам для решения данного класса задач (они популярны в мире, имеют хорошую документацию, в Яндексе есть большая экспертиза по их использованию)
- **допустимые** — альтернативные библиотеки, использование которых допускается, но не рекомендуется для новых
- **запрещённые** — вредные библиотеки, от использования которых мы хотели бы избавиться вообще, а новым проектам вообще запрещаем (авторы перестали их развивать, известно о больших проблемах или багах, в Яндексе есть много негативного опыта использования)

### Логирование

[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/419)

Для «фронтенда» логирования мы:
- **рекомендуем** использовать [slf4j](https://www.slf4j.org/)
- все остальные интерфейсные библиотеки **запрещаем** (в том числе mlf из iceberg)
По этому вопросу slf4j де-факто общепринятый стандарт.

В качестве «бэкендов» логирования мы:
- **рекомендуем** использовать [log4j 2.x](https://logging.apache.org/log4j/2.x/)
- **допускаем** использование logback
- **запрещаем** использовать log4j 1.x
«Log4j 1.x had reached end of life», поэтому его запрещаем. Log4j второй версии и logback более-менее одинаковы, но в log4j есть GC-free appender и аснихронные appender'ы по нашему опыту там сделаны лучше, поэтому рекомендуем для новых проектов log4j.

### Dependency Injection
[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/420)

Для новых проектов мы **рекомендуем** использовать [Spring](https://spring.io).

Java-комитету кажется довольно перспективным [Dagger 2](https://github.com/google/dagger), из-за того, что он легковесный и в нём управление зависимостями происходит на этапе компиляции. Мы хотели бы провести управляемый **эксперимент** по использованию Dagger 2 внутри Яндекса и ждём команду-добровольца, которые хотят его себе внедрить.

Все остальные библиотеки (в частности, [Guice](https://github.com/google/guice) и Dagger 1) **запрещаем**.


### Работа с JSON
[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/421)

Для работы с JSON мы **рекомендуем** две библиотеки:
- [Jackson](https://github.com/FasterXML/jackson) — удобнее для задачи databind с Java-классами при помощи аннотаций,
- [Gson](https://github.com/google/gson) — имеет меньше зависимостей и удобнее для задачи парсинга и создания JSON-а из кода.
**Запрещаем** мы использование внутренней библиотеки [misc-bender](https://a.yandex-team.ru/arc/trunk/arcadia/iceberg/misc-bender)
(и вместе с ней [misc-bender-annotations](https://a.yandex-team.ru/arc/trunk/arcadia/iceberg/misc-bender-annotations))
из iceberg ввиду того, что она очень сильно похожа по функциональности на Jackson, вкладываться в её поддержку нецелесообразно.


### Web Server
[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/526)

Наверное большинство Java-проектов это веб-приложения, поэтому возникает логичный вопрос, какой веб-сервер использовать.
Первое, что хочется постулировать, что для новых проектов мы запрещаем все варианты использования веб-серверов,
кроме как в embedded режиме. Веб-сервер должен подключаться по зависимостям и собираться в одну единицу деплоя
вместе с кодом приложения. Кажется, что во времена контейнеризации и облаков нет необходимости держать сервер приложений
с кучей war-ников внутри. Рекомендуем всем Java-проектам, кто живёт в другой парадигме, задуматься об изменениях.

Второе касается выбора конкретного веб-сервера.
Для новых проектов мы:
- **рекомендуем** использовать [Jetty](http://www.eclipse.org/jetty/) как наиболее распространённое и известное внутри компании решение,
- **допускаем** по согласованию с комитетом использование [Netty](https://netty.io/) в особо высокопроизводительных проектах,
- **запрещаем** использование [Tomcat](https://tomcat.apache.org/).
Если у вас есть опыт использования каких-то других вариантов, приходите в комментарии с рассказом.


### Web services
[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/524)

Для общения между бэкендами мы **рекомендуем** использовать [gRPC](https://grpc.io/), это универсальный протокол с типизированным описанием
интерфейсов и передаваемых данных, в C++ мире в Аркадии он уже достаточно популярен, мы верим, что и в Java за ним будущее.
Подробнее про релизацию для Java можно посмотреть [тут](https://github.com/grpc/grpc-java).

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

Для построения REST сервисов **рекомендуем** использовать [OpenApi](https://swagger.io/specification/),
так как он позволяет решить проблему генерации клиента для сервиса, а также получить готовые интерфейсы
для реаллизации контроллеров, в том числе для [Spring MVC](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html).

**Запрещаем в новых проектах** для использования внутреннюю библиотеку [commune-a3](https://a.yandex-team.ru/arc/trunk/arcadia/iceberg/commune-a3)
из iceberg, т.к. существуют open-source аналоги, вкладываться в её развитие нецелесообразно.


### Lombok
[обсуждение в этушке](https://clubs.at.yandex-team.ru/java/525)

Нас просили прояснить статус использования [Project Lombok](https://projectlombok.org) в Аркадии.
В ходе обсуждения мы поняли, что есть два лагеря ярых сторонников и ярых противников, каждый со своими аргументами.
Мы не хотим нарушать идиллию, поэтому не будем ни рекомендовать, ни запрещать использование Lombok в листовых проектах.
Однако, с целью минимизации трудозатрат мы решили запретить использование Lombok в [общих библиотеках](https://clubs.at.yandex-team.ru/java/311).


## Регламент обновления на новые версии JDK
Инициатором обновления default-JDK на новую версию выступает java-комитет. Исполнителями задачи являются devtools@ с привлечением по мере необходимости владельцев java-проектов. Работы по подготовке кодовой базы состоят из следующих шагов:

1) Создание автосборочной платформы, использующей новый компилятор. Список ее сборочных целей изначально пуст (потому что с новым JDK ничего не собирается).
2) Исправление ошибок компиляции и тестов под новую версию JDK. Фиксы делаются devtools@ совместно с владельцами проектов. Готовые проекты добавляются в список целей новой платформы, но при этом не удаляются из default. Таким образом, на этапе миграции код должен поддерживаться в состоянии совместимости с 2-мя версиями компилятора.
3) Составление списка проектов, владельцы которых хотят поддерживать совместимость с предыдущей версией JDK и после переключения. devtools@ коммитит в Аркадию ya.make файл с пустым набором RECURSE. Владельцы самостоятельно добавляют туда свои проекты (об этом файле сообщается либо в анонсе (2), либо отдельно). В дальнейшем таргеты из этого ya.make используются в качестве стартовых для legacy-платформы.
4) Когда все проекты становятся совместимыми с новой версией JDK (список java-целей у default и новой платформ совпадают), происходит переключение:
  * для default-платформы меняется компилятор
  * созданная в п.1 платформа удаляется
  * в автосборке создается legaсy-платформа для проектов из п.3

В процессе работы над задачей ожидается публикация как минимум 3-х анонсов:
1) Декларация о намерении обновить JDK (после принятия решения комитетом).
2) Анонс с указанием примерной даты переключения (за ~2-3 недели до предполагаемого момента).
3) Анонс [в этушку](https://clubs.at.yandex-team.ru/arcadia) того, что переключение состоялось.

Силами devtools@ также собирается deb-пакет с новой версией JDK. Появление пакета декларируется в анонсе (2) либо отдельным постом (но не позднее анонса (2)).

При переключении JDK также требуется обновлять porto-слой для YT. Сборка автоматизирована, инициировать ее можно при помощи нажатия "Run once" [в шедулере](https://sandbox.yandex-team.ru/scheduler/16265/view).
По вопросам, связанным с porto-слоем можно обращаться к staff:psushin, staff:andozer

