# Java : макросы

## JAVA_SRCS

```
JAVA_SRCS(SRCDIR path/to/sources PACKAGE_PREFIX java.package.name Globs... EXCLDUE ExcludeGlobs...)
```

Добавляет исходные файлы и ресурсы в сборку Java модуля. Сами списки файлы задаются Ant-подобными glob'ами (существенное отличие от Ant glob в том, что нельзя использовать `**` более одного раза). Самый простой пример использования: `JAVA_SRCS(**/*.java **/*.property)` добавит все java файлы в модульной директории и её поддиректориях в сборку, а все property файлы запакует в ресурсы финального jar архива.

Если требуется исключить из сборки часть собираемых файлов, то можно использовать именованный параметр `EXCLUDE`, например если из примера выше необходимо исключить из сборки все файлы лежащие в папке tests, то вызов макроса может выглядеть так `JAVA_SRCS(**/*.java **/*.property EXCLUDE tests/**/*)`

Если файлы расположены в поддиректории проекта (не совпадающей с именем пакета), то эту поддиректорию нужно указать используя параметр `SRCDIR`. Например, для сборки проекта на Java и Kotlin следующего стандартной Maven/Gradle структуре директорий, добавление исходников может выглядеть так: `JAVA_SRCS(SRCDIR src/main/java **/*.java **/*.kt)` (предполагается что структура поддиректорий внутри `src/main/java` соответствует структуре Java пакетов).

В случае когда все файлы в модуле относятся к одном и тому же пакету и при этом не хочется в дереве исходного кода создавать структуру пустых директорий соответствующих имени пакета, то можно использовать параметр `PACKAGE_PREFIX`. Например `JAVA_SRCS(PACKAGE_PREFIX ru.yandex.example props/*.property)` сложит все property файлы в директорию `ru/yandex/example` в файловой структуре генерируемого jar файла.

## WITH_KOTLIN

```
WITH_KOTLIN()
```

Включает поддержку Kotlin в текущем модуле. Зависимость от компилятора kotlic и стандартной библиотеки языка будет добавлена автоматически. Все `*.kt` файлы, добавленные в модуль с помощью макроса [`JAVA_SRCS`](macros.md#java_srcs), будут автоматически отданы на компиляцию. Если этот макрос не вызвался в текущем модуле то `*.kt` файлы попавшие в `JAVA_SRCS` будут считаться ресурсами и просто запакуются в итоговый ar файл.

## JAVAC_FLAGS

```
JAVAC_FLAGS(Opt...)
```

Позволяет добавить дополнительные опции Java компилятору.

## KOTLINC_FLAGS

```
KOTLINC_FLAGS(Opt...)
```

Позволяет добавить дополнительные опции Kotlin компилятору. Не имеет эффекта если в модуле не вызывался макрос [`WITH_KOTLIN`](macros.md#with_kotlin)

## WITH_KOTLINC_ALLOPEN

```
WITH_KOTLINC_ALLOPEN(Opts...)
```

Включает поддержку  [kotlin all-open compiler plugin](https://kotlinlang.org/docs/all-open-plugin.html). Opts - параметры плагина. В опциях надо указывать только value (без префикса -P plugin:org.jetbrains.kotlin.allopen: - он будет добавлен автоматически). Не имеет эффекта если в модуле не вызывался макрос [`WITH_KOTLIN`](macros.md#with_kotlin)

## ANNOTATION_PROCESSOR

```
ANNOTATION_PROCESSOR(Java.Annotation.Processsor.Class1 Java.Annotation.Processsor.Class2 ...)
```

Включает использование перечисленных процессоров Java аннотаций в процессе копмиляции исходного кода модуля. Классы процессоров должны присутствовать в classpath модуля.

## RUN_JAVA_PROGRAM

```
RUN_JAVA_PROGRAM(
    jvm_arg1 jvm_arg2 ...
    MainClass arg1 arg2 ...
    IN_DIR dir1 dir2 ...
    IN file1 file2 ...
    OUT_DIR dir1 dir2 ...
    CWD cwd
    CLASSPATH path/to/java/program
)
```

Запускает в процессе сборки Java приложение `$(JDK)/bin/java -classpath <java_prog_classpath> jvm_arg1 jvm_arg2 ... MainClass arg1 arg2 ...`. Результат работы приложения может использоваться как дополнительный исходный код для компиляции вместе с основными исходными кода модуля, либо как ресурсы генерируемого jar фалйа.

 * `CLASSPATH` - путь до модуля `JAVA_PROGRAM` чей classpath будет использоваться для запуска.
 * `IN` - список входных файлов в Аркадии
 * `IN_DIR` - список входных директорий в Аркадии
 * `OUT_DIR` - список выходных директорий в BUILD_ROOT. Во избежании путаницы рекомендуется использовать пути, начинающиеся явно с `BINDIR` или `ARCADIA_BUILD_ROOT`. Например, передать программе как аргумент директорию `${BINDIR}/generated`, объявить эту директорию выходной, сказав `OUT_DIR` `${BINDIR}/generated`, и использовать ее как `JAVA_SRCS(SRCDIR ${BINDIR}/generated **/*)`
 * `CWD` - директория выполнения программы в Аркадии или в BUILD_ROOT

Ключевое слово `CLASSPATH` обязательно. Все остальные ключевые слова опциональны.

Очень часто значения `IN`, `IN_DIR`, `OUT_DIR` совпадают с какими-либо аргументами программы. Это происходит, потому что указывая какую-то директорию в аргументах, мы сообщаем самой программе о том, куда сложить результаты, а указывая ее повторно в OUT_DIR, мы сообщаем системе сборки, что данная директория появится после выполнения программы, и ее следует поместить в outputs ноды, чтобы потом переиспользовать ее в ноде компиляции. Это необходимое дублирование.

## UBERJAR

```
UBERJAR()
```

Включает запаковку всех классов из зависимостей модуля в итоговый jar файл модуля, позволяя получить полностью самодостаточный артефакт. Гарантированна работоспособность макроса совместно с [`JAVA_PROGRAM`](modules.md#java_program), но не [`JAVA_LIBRARY`](modules.md#java_library).

Пример тонокой настройки `UBERJAR` программы модно посмотреть [здесь](https://a.yandex-team.ru/arc/trunk/arcadia/devtools/dummy_arcadia/test_uberjar/projectMain/ya.make).

## UBERJAR_HIDING_PREFIX

```
UBERJAR_HIDING_PREFIX(Prefix)
```

Префикс для перемещаемых (shade) классов (по-умолчанию все остается на своих местах).

## UBERJAR_HIDE_EXCLUDE_PATTERN

```
UBERJAR_HIDE_EXCLUDE_PATTERN(Globs...)
```

Набор Ant подобных шаблонов путей для классов, которые перемещать не надо (по-умолчанию исключений нет).

## UBERJAR_PATH_EXCLUDE_PREFIX

```
UBERJAR_PATH_EXCLUDE_PREFIX(Classes...)
```

Префикс для путей, которые не должны попасть в jar-архив (по-умолчанию попадают все).

## DEPENDENCY_MANAGEMENT

```
DEPENDENCY_MANAGEMENT(contrib/java/path/to/exact/version1 contrib/java/path/to/exact/version2)
```

Фиксирует версии сторонних библиотек которые должны быть использованы для копмиляции текущей `JAVA_LIBRARY` или компиляции и запуска текущего `JAVA_PROGRAM`. Если в транзитивных зависимостях есть другие версии указанных библиотек, то они будет заменены не те которые запрошены данным макросом. Если в прямых зависимостях есть одна из библиотек без указания конкретной версии, то будет использована версия запрошенная через данный макрос. Подробней про управление зависимостями можно прочитать [здесь](dependencies.md).

## EXCLUDE

```
EXCLUDE(path/prefix1 path/prefix2 ....)
```

Исключает из транзитивных зависимостей текущего модуля все библиотеки находящиеся в указанных поддиректориях. Подробней про управление зависимостями можно прочитать [здесь](dependencies.md).

## JAVA_DEPENDENCIES_CONFIGURATION

```
JAVA_DEPENDENCIES_CONFIGURATION(Checks...)
```

Включает дополнительные проверки classpath модуля:
 * `FORBID_DIRECT_PEERDIRS` - найдёт в модуле все прямые `PEERDIR` (полный путь, с версией).
 * `FORBID_CONFLICT` - найдёт все ситуации когда в транзитивном замыкании зависимостей модуля есть разные версии одной и той же библиотеки и нет правила `DEPENDENCY_MANAGEMENT` для неё.
 * `FORBID_CONFLICT_DM`  - найдёт все ситуации когда в транзитивном замыкании зависимостей модуля есть версии библиотеки отличные от версии прописанной в `DEPENDENCY_MANAGEMENT` модуля.
 * `FORBID_CONFLICT_DM_RECENT`  - аналогична предыдущей, но сработает только тогда, когда в `DEPENDENCY_MANAGEMENT` указана более старая версия библиотеки, чем та, которая приехала по зависимости.
 * `REQUIRE_DM` - найдёт все зависимости, версии которых были выбраны не при помощи `DEPENDENCY_MANAGEMENT` (даже если в транзитивном замыкании присутствует только одна версия библиотеки, но для неё нет правила `DEPENDENCY_MANAGEMENT`).
 
Проверки, инициируемые данными макросами, выполняются на этапе построения сборочного графа и поэтому их срабатывания отображаются как ошибки конфигурации.

{% note info %}

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

{% endnote %}

## DIRECT_DEPS_ONLY

```
DIRECT_DEPS_ONLY()
```

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

## CHECK_JAVA_DEPS

```
CHECK_JAVA_DEPS(<yes|no|strict>)
```

Управление проверками на конфликт полных имён классов в classpath модуля. Если проверка включена, то будут найдены все ситуации когда в classpath модуля содержатся файлы классов с одинаковым именем. Если включен `strict` режим, то дополнительно будет выполнена проверка совпадения содержимого классов и диагностироваться будет только наличие двух разных классов имеющих одно и то же имя.
