Java for Beginner
710 subscribers
618 photos
166 videos
12 files
967 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
OkHttp для Java

OkHttp — это высокопроизводительный HTTP-клиент для Java и Android, разработанный компанией Square. С момента своего появления он стал стандартом де-факто для сетевых операций в Java-приложениях благодаря своей эффективности, поддержке современных протоколов и гибкости. OkHttp используется в популярных библиотеках, таких как Retrofit, Picasso и других, что подчеркивает его надежность и универсальность.

Почему стоит выбрать OkHttp?
Производительность: Встроенная поддержка HTTP/2, пулинг соединений и GZIP-компрессия обеспечивают оптимальную производительность.
Современные стандарты: Поддержка TLS 1.3, ALPN и привязки сертификатов гарантирует безопасность и совместимость.
Простота и гибкость: Флюентный API и неизменяемые объекты упрощают написание чистого кода, а интерсепторы позволяют настраивать поведение.
Надежность: Автоматическое восстановление после сбоев и поддержка альтернативных IP-адресов повышают устойчивость к сетевым проблемам.



Основные функции

OkHttp предлагает набор функций, которые делают его мощным инструментом для сетевых операций:
Поддержка HTTP/2: Позволяет нескольким запросам к одному хосту использовать одно соединение, снижая задержки.
Пулинг соединений: Повторно использует существующие соединения, минимизируя накладные расходы.
Прозрачная GZIP-компрессия: Автоматически сжимает ответы, уменьшая объем данных.
Кэширование ответов: Хранит ответы для повторного использования без сетевых запросов.
Восстановление сети: Автоматически повторяет попытки подключения и использует альтернативные IP-адреса.
TLS-функции: Поддерживает TLS 1.3, ALPN, привязку сертификатов и откат к старым версиям TLS.



Поддержка HTTP/2

HTTP/2 позволяет мультиплексировать несколько запросов через одно соединение, что особенно полезно для приложений с высокой нагрузкой. OkHttp автоматически использует HTTP/2, если сервер его поддерживает, обеспечивая оптимальную производительность.

Пулинг соединений
Когда HTTP/2 недоступен, OkHttp использует пулинг соединений для повторного использования сокетов. Это снижает затраты на установление новых соединений, что критично для приложений с частыми запросами.
Прозрачная GZIP-компрессия

OkHttp автоматически обрабатывает GZIP-компрессию ответов, что уменьшает объем передаваемых данных. Разработчику не нужно вручную декомпрессировать данные, так как OkHttp делает это прозрачно.

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

Восстановление сети
OkHttp устойчив к сетевым сбоям. Он автоматически повторяет попытки подключения и пробует альтернативные IP-адреса, если сервер доступен по нескольким адресам. Это особенно важно для поддержки IPv4+IPv6 и серверов в распределенных дата-центрах.

TLS-функции
OkHttp поддерживает современные TLS-протоколы (TLS 1.3, ALPN) и функции, такие как привязка сертификатов для повышения безопасности. При необходимости он может откатываться к TLS 1.0 для совместимости с устаревшими серверами.

Для улучшения TLS можно использовать Conscrypt:
Security.insertProviderAt(Conscrypt.newProvider(), 1);



Обзор API

OkHttp предоставляет интуитивно понятный API, основанный на шаблоне строителя (builder pattern), что упрощает создание и выполнение запросов.

Создание запросов

Запросы создаются с помощью Request.Builder, который позволяет задавать URL, метод, заголовки и тело запроса.
Request request = new Request.Builder()
.url("https://api.example.com/data")
.get()
.build();


Для запросов с параметрами можно использовать HttpUrl.Builder:
HttpUrl url = new HttpUrl.Builder()
.scheme("https")
.host("api.example.com")
.addPathSegment("data")
.addQueryParameter("id", "1")
.build();

Request request = new Request.Builder()
.url(url)
.build();



#Java #middle #on_request #OkHttp
👍3
Выполнение запросов

OkHttp поддерживает синхронные и асинхронные вызовы.

Синхронный вызов:
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
Response response = call.execute();


Асинхронный вызов:

Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.err.println("Request failed: " + e.getMessage());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String body = response.body().string();
System.out.println("Response: " + body);
}
}
});


Обработка ответов

Ответы в OkHttp неизменяемы и предоставляют доступ к заголовкам, телу и статусу ответа.
if (response.isSuccessful()) {
String body = response.body().string(); // Важно: вызывать .string() только один раз
System.out.println("Response body: " + body);
} else {
System.err.println("Request failed with code: " + response.code());
}
response.close(); // Закрытие ответа для освобождения ресурсов


Важно: Метод response.body().string() загружает тело ответа в память, поэтому для больших ответов рекомендуется использовать потоковую передачу:
try (ResponseBody body = response.body()) {
InputStream inputStream = body.byteStream();
// Чтение потока
}



Расширенные функции

Интерсепторы

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

OkHttp поддерживает два типа интерсепторов:
Прикладные интерсепторы (addInterceptor): Вызываются для каждого запроса и ответа, включая кэшированные. Подходят для логирования, добавления заголовков или модификации запросов.
Сетевые интерсепторы (addNetworkInterceptor): Вызываются только для сетевых запросов, игнорируя кэшированные ответы. Полезны для обработки перенаправлений и повторных попыток.


Пример интерсептора для логирования:
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
System.out.println(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));

Response response = chain.proceed(request);
long t2 = System.nanoTime();
System.out.println(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));

return response;
}
}


Добавление интерсептора:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();


Пример сетевого интерсептора для добавления заголовка Cache-Control:
public class CacheControlInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
return response.newBuilder()
.header("Cache-Control", "max-age=60")
.build();
}
}


Практическое применение интерсепторов:
Логирование запросов и ответов с помощью HttpLoggingInterceptor.
Добавление заголовков аутентификации.
Повторные попытки при сбоях (например, при 503 ошибках).
Модификация тела запроса или ответа (например, шифрование/дешифрование).



#Java #middle #on_request #OkHttp
👍3
Настройка клиента

OkHttpClient.Builder позволяет настраивать параметры клиента, такие как таймауты, пул соединений и интерсепторы.

OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();


Для отключения перенаправлений:
OkHttpClient client = new OkHttpClient.Builder()
.followRedirects(false)
.build();


Загрузка файлов

OkHttp поддерживает загрузку файлов с помощью MultipartBody:

File file = new File("src/test/resources/test.txt");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(), fileBody)
.build();

Request request = new Request.Builder()
.url("https://api.example.com/upload")
.post(requestBody)
.build();


Для отслеживания прогресса загрузки можно создать кастомный RequestBody:
public class ProgressRequestWrapper extends RequestBody {
private final RequestBody requestBody;
private final ProgressListener listener;

public ProgressRequestWrapper(RequestBody requestBody, ProgressListener listener) {
this.requestBody = requestBody;
this.listener = listener;
}

@Override
public MediaType contentType() {
return requestBody.contentType();
}

@Override
public void writeTo(BufferedSink sink) throws IOException {
CountingSink countingSink = new CountingSink(sink, this, contentLength());
BufferedSink bufferedSink = Okio.buffer(countingSink);
requestBody.writeTo(bufferedSink);
bufferedSink.flush();
}

public interface ProgressListener {
void update(long bytesWritten, long contentLength, boolean done);
}
}


Отмена запросов


Запросы можно отменить с помощью метода Call.cancel():
Call call = client.newCall(request);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.schedule(() -> {
call.cancel();
System.out.println("Request cancelled");
}, 1, TimeUnit.SECONDS);


Кэширование

Для настройки кэша:
File cacheDirectory = new File("src/test/resources/cache");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(cacheDirectory, cacheSize);

OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();



#Java #middle #on_request #OkHttp
👍3
Лучшие практики

Управление соединениями:
Используйте пулинг соединений для оптимизации производительности, но следите за количеством открытых соединений, чтобы избежать перегрузки ресурсов.
Настройте максимальное количество соединений с помощью ConnectionPool.


Обработка больших ответов:
Избегайте использования response.body().string() для больших ответов. Вместо этого используйте byteStream() для потоковой обработки.

Обработка ошибок:
Реализуйте повторные попытки для преходящих ошибок (например, 503) с помощью интерсепторов.
Всегда закрывайте Response с помощью response.close() или try-with-resources.


Безопасность:
Регулярно обновляйте OkHttp для получения последних исправлений безопасности.
Используйте привязку сертификатов для защиты от атак типа "человек посередине".


Асинхронные вызовы:
Предпочитайте асинхронные вызовы для Android-приложений, чтобы избежать блокировки UI-потока.


Интеграция с другими библиотеками

OkHttp часто используется в связке с другими библиотеками:

Retrofit: Упрощает создание RESTful API, используя OkHttp как базовый HTTP-клиент.
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();


Moshi/Gson: Для сериализации и десериализации JSON.
HttpLoggingInterceptor: Для логирования HTTP-запросов и ответов.


Тестирование

OkHttp предоставляет MockWebServer для имитации серверных ответов в тестах:
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("Hello, world!"));
server.start();

HttpUrl baseUrl = server.url("/test");
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(baseUrl).build();
Response response = client.newCall(request).execute();

assertEquals("Hello, world!", response.body().string());
server.shutdown();


Для добавления MockWebServer в проект:

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>5.1.0</version>
<scope>test</scope>
</dependency>


Требования и зависимости


Версии: OkHttp 5.x поддерживает Android 5.0+ (API 21+) и Java 8+. Для более старых платформ используйте ветку 3.12.x (Android 2.3+, Java 7+).
Зависимости: Okio и стандартная библиотека Kotlin. Опционально: Conscrypt для улучшенной TLS-поддержки.

Maven:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>5.1.0</version>
</dependency>


Для управления версиями рекомендуется использовать BOM:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-bom</artifactId>
<version>5.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>


Поддержка GraalVM

OkHttp совместим с GraalVM Native Image, начиная с версии 5.0.0-alpha.2.

Пример сборки:
./gradlew okcurl:nativeImage
./okcurl/build/graal/okcurl https://httpbin.org/get


Безопасность
Для обеспечения безопасности регулярно обновляйте OkHttp, чтобы использовать последние исправления. Следите за историей конфигурации TLS на странице OkHttp.


#Java #middle #on_request #OkHttp
👍4
Обзор платформ для разработки на Java

Для написания и запуска
Java-программ вам нужна платформа, где вы будете писать код, компилировать его и запускать. Выбор инструмента зависит от вашего уровня подготовки, целей и предпочтений. Ниже представлен обзор доступных вариантов — от простых текстовых редакторов до профессиональных IDE, включая новые российские разработки OpenIDE и GigaIDE, а также Cursor с поддержкой ИИ.

1. Текстовые редакторы (Блокнот, Notepad++, VS Code)

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

Блокнот (Notepad):
Плюсы: Бесплатный, предустановлен на Windows, минималистичный.
Минусы: Нет подсветки синтаксиса, автодополнения, отладки. Подходит только для простейших программ.
Когда использовать: Для первых шагов, чтобы понять, как работает компиляция (javac) и запуск (
java) вручную.

Пример:
Напишите код в HelloWorld.java в Блокноте, сохраните, затем скомпилируйте и запустите через командную строку:
javac HelloWorld.java
java HelloWorld


Notepad++:
Плюсы: Бесплатный, легкий, поддерживает подсветку синтаксиса для Java, плагины для автодополнения.
Минусы: Нет встроенной отладки или интеграции с JDK. Требуется ручная компиляция.
Когда использовать: Для небольших программ или если вы хотите минималистичную среду.



Visual Studio Code (VS Code):

Плюсы: Бесплатный, легкий, поддерживает плагины (например, «Java Extension Pack»), автодополнение, отладку и интеграцию с JDK. Популярен среди Java-разработчиков как легкая альтернатива IDE.
Минусы: Требует настройки плагинов для полноценной работы с
Java.
Когда использовать: Если вы хотите современный редактор с поддержкой
Java, но без громоздкости полноценной IDE.
Настройка:
Установите VS Code с code.visualstudio.com.
Установите расширение «
Java Extension Pack» через Marketplace.
Укажите путь к JDK (установленному ранее, например,
Java 17).

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


2. Интегрированные среды разработки (IDE)

IDE — это мощные инструменты, которые объединяют редактор кода, компилятор, отладчик и другие функции. Они идеальны для разработки сложных проектов и обучения, так как автоматизируют многие процессы. Рассмотрим популярные IDE, включая IntelliJ IDEA, OpenIDE, GigaIDE и Cursor.


IntelliJ IDEA:
Плюсы: Лидер среди IDE для Java. Умное автодополнение, мощная отладка, интеграция с фреймворками (Spring, Maven, Gradle), поддержка версий Java (включая 17, 21, 24 LTS). Community Edition бесплатна и подходит для большинства задач.
Минусы: Community Edition ограничена по сравнению с Ultimate (платной). Может быть тяжеловесной для слабых ПК. Не смотря на то, что корни проекта идут из России, доступ ограничен из-за санкций 😡.
Когда использовать: Для любых
Java-проектов, от учебных до профессиональных.

Eclipse:
Плюсы: Бесплатный, open-source, поддерживает Java и множество плагинов, подходит для больших проектов.
Минусы: Менее интуитивный интерфейс, чем у IntelliJ IDEA. Требует больше ручной настройки.
Когда использовать: Если вы хотите бесплатную IDE с долгой историей и широкой поддержкой.


NetBeans:
Плюсы: Бесплатный, простой в использовании, хорошая поддержка Java EE и Maven.
Минусы: Менее популярен, чем IntelliJ IDEA или Eclipse, медленнее обновляется.
Когда использовать: Для учебных проектов или если вам нужна простая IDE.


BlueJ:
Плюсы: Создан специально для обучения Java. Простой интерфейс, визуализация объектов.
Минусы: Ограниченные возможности для реальных проектов.
Когда использовать: Для абсолютных новичков, изучающих основы ООП.


#Java #для_новичков #beginner #IDEA's
👍3
OpenIDE:
Плюсы: Российская IDE с открытым исходным кодом, основана на IntelliJ IDEA Community Edition. Поддерживает Java 24, Spring, Docker, Maven, Gradle и интеграцию с российским GitFlic. Не зависит от зарубежных серверов, что исключает риски блокировки. Имеет собственный маркетплейс с более чем 300 плагинами. Работает быстрее оригинальной IntelliJ IDEA за счет удаления телеметрии и проприетарных компонентов. Встроенная поддержка Spring и Docker. Удалена вся телеметрия IntelliJ IDEA.
Минусы: Находится на стадии бета-тестирования. Поддерживает только
Java и Kotlin, хотя в планах добавление Go, TypeScript, Rust. Некоторые функции, например работа с базами данных, пока ограничены.
Когда использовать: Для российских разработчиков, которым важна независимость от зарубежных сервисов и открытый код. Подходит для проектов, требующих поддержки
Java 24 и Spring.

GigaIDE:
Плюсы: Российская IDE от Сбера, также основана на IntelliJ IDEA Community Edition. Поддерживает Java, Kotlin, Groovy, Scala, Python, JavaScript, TypeScript, SQL. Включает AI-ассистент GigaCode для автодополнения и генерации кода. Интеграция с GitVerse, GitHub, Bitbucket. Доступна в версиях Desktop и Cloud. Поддержка Spring Framework ожидается в профессиональной версии.
Минусы: Код закрыт, процесс разработки менее прозрачен, чем у OpenIDE. Зависимость от одной компании (Сбер) может быть риском. Работа с базами данных ограничена, требуется плагин Database Navigator.
Когда использовать: Для разработчиков, которым нужен привычный интерфейс IntelliJ IDEA с AI-ассистентом и поддержкой множества языков. Подходит для корпоративных проектов в России.


Cursor:
Плюсы: Современная IDE на базе VS Code с мощным AI-ассистентом, который понимает контекст проекта, предлагает сложные конструкции кода и помогает с рефакторингом. Поддерживает более 30 языков, включая Java. Упрощает написание кода для новичков благодаря ИИ.
Минусы: Платная подписка (от $20/месяц с квотами на AI-запросы). Требует настройки для полноценной работы с
Java (установка Java Extension Pack). UI может быть менее удобным для профессиональных разработчиков по сравнению с IntelliJ IDEA.
Когда использовать: Для новичков или разработчиков, которые хотят использовать ИИ для ускорения кодирования. Подходит для небольших проектов или экспериментов.


Рекомендация: Для новичков я советую IntelliJ IDEA Community Edition как основной выбор благодаря интуитивному интерфейсу и мощным функциям. OpenIDE и GigaIDE — отличные альтернативы для российских разработчиков, особенно если важна независимость от зарубежных сервисов. Cursor подойдет, если вы хотите попробовать ИИ-поддержку, но требует дополнительных затрат и настройки для Java.



Установка и настройка IntelliJ IDEA

Теперь давайте разберем, как установить и настроить IntelliJ IDEA Community Edition для разработки на Java. Мы будем использовать Java 17 (LTS), но шаги подойдут и для Java 21 или 24.

Шаг 1: Скачивание IntelliJ IDEA
Перейдите на официальный сайт: www.jetbrains.com/idea/download.
Выберите Community Edition (бесплатная версия) для вашей операционной системы:
Windows: .exe.
macOS: .dmg.
Linux: .tar.gz или пакет для дистрибутива.
Нажмите «Download» и сохраните установочный файл.


Шаг 2: Установка IntelliJ IDEA
Для Windows
Запустите скачанный .exe файл.
Следуйте инструкциям мастера установки:
Выберите папку установки (например, C:\Program Files\JetBrains\IntelliJ IDEA Community Edition).
Установите флажки для создания ярлыка на рабочем столе и добавления в PATH (опционально).
Выберите ассоциацию файлов .
java с IntelliJ IDEA.
Нажмите «Install» и дождитесь завершения установки.
Запустите IntelliJ IDEA, выбрав «Run IntelliJ IDEA» в конце установки.


Для macOS
Откройте .dmg файл и перетащите IntelliJ IDEA в папку «Программы» (Applications).
Запустите IntelliJ IDEA из папки «Программы» или через Spotlight.


Для Linux (на примере Ubuntu)
Распакуйте .tar.gz:tar -xzf ideaIC-*.tar.gz -C ~/idea
Перейдите в папку bin и запустите IDE:cd ~/idea/idea-IC-*/bin
./
idea.sh
Следуйте инструкциям установщика (обычно это GUI-мастер).


#Java #для_новичков #beginner #IDEA's
👍4🔥1
Краткая установка и настройка OpenIDE, GigaIDE и Cursor

OpenIDE
Скачивание:
Перейдите на openide.ru или GitFlic для загрузки.
Выберите версию для Windows, macOS или Linux.


Установка:
Windows: Запустите .exe и следуйте мастеру установки.
macOS: Откройте .dmg и перетащите OpenIDE в «Программы». После установки выполните в терминале:xattr -c /Applications/
OpenIDE.app
Linux: Распакуйте .tar.gz и запустите скрипт openide.sh из папки bin.

GigaIDE
Скачивание:
Перейдите на
gitverse.ru/features/gigaide. Требуется авторизация через Сбер ID или cloud.ru.
Выберите GigaIDE Desktop для Windows, macOS или Linux.


Установка:
Windows: Запустите .exe и следуйте инструкциям.
macOS: Откройте .dmg и перетащите GigaIDE в «Программы». Выполните:xattr -c /Applications/GIGA\ IDE\ CE\
2024.1.1.app
Linux: Распакуйте .tar.gz и запустите gigaide.sh из папки bin.

Cursor
Скачивание:
Перейдите на
cursor.com и скачайте версию для Windows, macOS или Linux. Требуется регистрация для доступа к AI-функциям.

Установка:
Windows: Запустите .exe и следуйте инструкциям.
macOS: Перетащите .dmg в «Программы».
Linux: Распакуйте .tar.gz и запустите
cursor.sh.


Полезные советы для новичков


Выбор IDE: Начните с IntelliJ IDEA Community для универсальности. Используйте OpenIDE или GigaIDE для работы в российской инфраструктуре. Cursor подойдет для экспериментов с ИИ, но требует затрат.
Изучите горячие клавиши: Например, в IntelliJ IDEA и OpenIDE/GigaIDE: Ctrl+Alt+L (форматирование кода), Alt+Enter (исправление ошибок).
Практикуйтесь: Создайте простые программы, такие как калькулятор, в каждой IDE, чтобы сравнить их.
Ресурсы:
IntelliJ IDEA:
www.jetbrains.com/idea/documentation.
OpenIDE:
openide.ru.
GigaIDE:
gitverse.ru/features/gigaide.
Cursor:
cursor.com/docs.
Stack Overflow для решения проблем.


#Java #для_новичков #beginner #IDEA's
👍5
Задачи и жизненный цикл в Gradle


Task API: Task, DefaultTask, @TaskAction

Задачи (tasks) — это основная единица работы в Gradle, представляющая такие действия, как компиляция, тестирование или упаковка. Task API предоставляет инструменты для создания и настройки задач.


Основные компоненты

Task:
Интерфейс org.gradle.api.Task, определяющий базовую функциональность задачи (например, выполнение, зависимости).
Все задачи в Gradle реализуют этот интерфейс.


DefaultTask:
Класс org.gradle.api.DefaultTask, стандартная реализация интерфейса Task.
Используется для создания пользовательских задач.


Пример (Groovy DSL):
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

class CustomTask extends DefaultTask {
@TaskAction
void executeTask() {
println 'Executing custom task'
}
}

tasks.register('customTask', CustomTask)


@TaskAction:
Аннотация, указывающая метод, который выполняется при запуске задачи.

Пример (Kotlin DSL):
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

open class CustomTask : DefaultTask() {
@TaskAction
fun executeTask() {
println("Executing custom task")
}
}

tasks.register<CustomTask>("customTask")


В памяти: Каждая задача представлена как объект в JVM, содержащий метаданные (имя, зависимости, действия). Gradle загружает все задачи в память во время фазы конфигурации, что увеличивает потребление памяти пропорционально их количеству. Плагины, такие как java, добавляют множество задач (например, compileJava, test), увеличивая overhead.


Gradle Lifecycle

Жизненный цикл Gradle состоит из трех фаз: Initialization, Configuration и Execution. Каждая фаза выполняет определенные функции и влияет на производительность и память.

Initialization Phase:
Gradle загружает settings.gradle для определения структуры проекта (корневое имя, подмодули).
Создает объекты Project для корневого проекта и подпроектов.
Устанавливает начальные настройки, такие как репозитории и плагины.

В памяти: Минимальная фаза по потреблению ресурсов, так как загружается только settings.gradle и связанные плагины. Объем памяти зависит от количества модулей (обычно 50-100 МБ).


Configuration Phase:

Gradle парсит все файлы build.gradle, создавая модель проекта и граф задач (Directed Acyclic Graph, DAG).
Все скрипты конфигурации выполняются, даже для задач, которые не будут запущены.
Пример: Определение зависимостей, задач и плагинов.

В памяти: Самая ресурсоемкая фаза, так как Gradle загружает и компилирует все скрипты, плагины и зависимости. Для крупных проектов может потребоваться 500-1000 МБ памяти.

Оптимизация: Используйте флаг --configure-on-demand для конфигурации только необходимых модулей:
./gradlew build --configure-on-demand


Execution Phase:
Gradle выполняет задачи, указанные в командной строке (например, ./gradlew build), в порядке, определенном DAG.
Инкрементальность пропускает задачи, чьи входные/выходные данные не изменились (см. ниже).

В памяти: Зависит от сложности задач. Например, compileJava загружает исходные файлы и зависимости, а test — тестовые классы и фреймворки. Параллельное выполнение (--parallel) увеличивает пиковое потребление памяти.


Нюансы:

Конфигурация выполняется всегда, что замедляет сборку, особенно для крупных проектов.
Gradle Daemon сохраняет JVM между сборками, ускоряя повторные запуски, но увеличивая базовое потребление памяти (200-300 МБ).
Используйте --no-daemon для одноразовых сборок:

./gradlew build --no-daemon


#Java #middle #Gradle #Task #Lifecycle
👍1
Task Graph, зависимости между задачами

Gradle строит Directed Acyclic Graph (DAG) для задач, где узлы — задачи, а ребра — зависимости. Это определяет порядок выполнения.


Зависимости между задачами

dependsOn:
Указывает, что задача зависит от выполнения других задач.

Пример:
task compileJava {
doLast { println 'Compiling Java' }
}
task test(dependsOn: compileJava) {
doLast { println 'Running tests' }
}

Gradle выполнит compileJava перед test.


mustRunAfter:
Определяет порядок выполнения без строгой зависимости.

Пример:

task taskA {
doLast { println 'Task A' }
}
task taskB {
mustRunAfter 'taskA'
doLast { println 'Task B' }
}

Если обе задачи выполняются, taskB будет после taskA, но taskB может выполняться отдельно.


finalizedBy:
Указывает задачу, которая выполняется после завершения текущей, даже при ошибке.

Пример:
task build {
doLast { println 'Building' }
}
task cleanUp {
doLast { println 'Cleaning up' }
}
build.finalizedBy cleanUp


В памяти: DAG задач хранится как структура данных в JVM, где каждая задача — объект с метаданными (зависимости, действия). Размер графа пропорционален количеству задач, что может увеличить потребление памяти до нескольких сотен МБ в крупных проектах.



Incremental Build и Up-to-Date Checks

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

Механизм:
Gradle проверяет хэши входных (исходные файлы, свойства) и выходных данных (скомпилированные классы, JAR).
Если хэши совпадают, задача помечается как up-to-date и пропускается.


Пример вывода:
> Task :compileJava UP-TO-DATE


Пример настройки:
tasks.named('compileJava') {
inputs.files('src/main/java')
outputs.dir('build/classes/java/main')
}


В памяти: Gradle хранит хэши входов/выходов в памяти и в ~/.gradle/caches для сравнения. Это добавляет небольшой overhead (около 10-50 МБ), но значительно ускоряет сборку.


Нюансы:

Неправильная настройка входов/выходов может привести к ненужному выполнению задач.
Используйте --info для анализа, почему задача не была пропущена:

./gradlew build --info



Gradle Inputs/Outputs (Task Inputs/Outputs)

Задачи Gradle имеют входы и выходы, которые определяют, что влияет на выполнение задачи и что она производит.

Inputs:
Файлы, свойства или другие данные, от которых зависит задача.

Пример:
task processFiles {
inputs.files fileTree('src/main/resources')
doLast {
println 'Processing files'
}
}


Outputs:
Файлы или директории, создаваемые задачей.

Пример:
task generateReport {
outputs.file file('build/report.txt')
doLast {
file('build/report.txt').text = 'Report content'
}
}


В памяти: Gradle хранит метаданные входов/выходов в памяти и кэширует хэши в ~/.gradle/caches. Для задач с большим количеством файлов (например, compileJava) это увеличивает потребление памяти, так как Gradle сканирует файловую систему.


Нюансы:
Явно указывайте входы/выходы для кастомных задач, чтобы включить инкрементальность.

Используйте inputs.property для не-файловых входов:
task customTask {
inputs.property 'version', project.version
doLast { println "Version: ${project.version}" }
}



#Java #middle #Gradle #Task #Lifecycle
👍1
Do-first/do-last и ленивость (Provider, Property)

Gradle поддерживает гибкую настройку задач через doFirst и doLast, а также ленивую конфигурацию через Provider и Property.

doFirst и doLast:
doFirst: Добавляет действие в начало выполнения задачи.
doLast: Добавляет действие в конец выполнения задачи.


Пример:
task example {
doFirst { println 'Starting task' }
doLast { println 'Ending task' }
}


Ленивость (Provider, Property):
Gradle использует ленивую оценку для отсрочки вычислений до фазы выполнения.

Provider: Интерфейс для ленивых значений.def version = providers.provider { project.version }
task printVersion {
doLast {
println "Version: ${version.get()}"
}
}


Property: Для управления свойствами задачи.

task customTask {
def outputFile = objects.property(String)
outputFile.set('build/output.txt')
doLast {
println "Output: ${outputFile.get()}"
}
}


В памяти: doFirst и doLast добавляют действия как объекты в задачу, минимально увеличивая память. Ленивые Provider и Property хранят ссылки на значения, а не сами значения, что оптимизирует память до их вычисления в фазе выполнения.



Gradle Listeners и хуки

Gradle предоставляет хуки для мониторинга и настройки жизненного цикла и задач.

BuildListener:
Устаревший интерфейс для мониторинга событий сборки.

Пример:
gradle.buildFinished {
println 'Build completed'
}



TaskExecutionListener:

Отслеживает выполнение задач.

Пример:
gradle.taskGraph.whenReady {
println 'Task graph is ready'
}


Project.afterEvaluate:
Выполняется после фазы конфигурации.

Пример:
project.afterEvaluate {
println 'Project configured'
}

В памяти: Хуки создают дополнительные объекты-слушатели в памяти, увеличивая overhead. Для крупных проектов с множеством слушателей это может добавить 10-50 МБ памяти.


Нюансы:

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



Gradle Build Cache

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

Настройка:
buildCache {
local {
enabled = true
}
remote(HttpBuildCache) {
url = 'https://cache.example.com/'
push = true
}
}


Как работает:
Gradle кэширует выходные данные задач (например, скомпилированные классы, JAR) в ~/.gradle/caches/build-cache или на удаленном сервере.
При повторной сборке Gradle проверяет хэши входов/выходов и использует кэшированные результаты, если они совпадают.
Пример: Задача compileJava кэширует классы в build/classes.


Использование:
Включите кэш:
./gradlew build --build-cache


Очистка локального кэша:
rm -rf ~/.gradle/caches/build-cache


В памяти: Build Cache требует хранения хэшей и метаданных в памяти во время выполнения, что добавляет 50-100 МБ overhead. Удаленный кэш увеличивает сетевые операции, но снижает локальные вычисления.


Нюансы:
Настройте входы/выходы задач точно, чтобы кэш работал корректно.
Build Cache наиболее эффективен для CI/CD, где результаты задач переиспользуются между сборками.



#Java #middle #Gradle #Task #Lifecycle
👍1
Основы работы с терминалом в Java


Зачем работать с терминалом?

Терминал (или командная строка в Windows) — это фундаментальный инструмент для разработчиков Java.

Хотя IDE, такие как IntelliJ IDEA, автоматизируют многие процессы, знание терминала важно по следующим причинам:
Полный контроль: Вы понимаете каждый шаг компиляции и запуска.
Обучение: Работа в терминале помогает разобраться, как
Java преобразует код в исполняемые программы.
Реальные проекты: На серверах, в CI/CD-системах (например, Jenkins) и скриптах терминал используется для автоматизации.
Отладка: Знание терминала помогает решать проблемы, когда IDE недоступна или возникают ошибки.

Для работы вам нужен установленный JDK (Java Development Kit). Если JDK ещё не установлен, обратитесь к моей предыдущей инструкции по установке Java 17, 21 или 24 LTS.


Основные команды: javac и java

Java-программы проходят два основных этапа:
Компиляция: Команда javac (Java Compiler) преобразует исходный код (файлы .java) в байт-код (файлы .class), который является платформонезависимым.
Запуск: Команда
java исполняет байт-код на виртуальной машине Java (JVM).


Предварительные проверки

Перед началом убедитесь, что JDK настроен:

Откройте терминал:
Windows: Win + Rcmd или PowerShell.
macOS/Linux: Откройте приложение «Терминал».


Проверьте версии:
java -version
javac -version


Ожидаемый вывод (для Java 17, например):
openjdk version "17.0.8" 2023-07-18
OpenJDK Runtime Environment (build 17.0.8+7)
javac 17.0.8


Если команды не работают, проверьте переменные JAVA_HOME и PATH:
Windows: Убедитесь, что JAVA_HOME указывает на папку JDK (например, C:\Program Files\Java\jdk-17), а %JAVA_HOME%\bin добавлен в PATH.
macOS/Linux: Проверьте, что JAVA_HOME установлена (например, export JAVA_HOME=/usr/lib/jvm/jdk-17) и добавлена в PATH в ~/.zshrc или ~/.bashrc.


Шаг 1: Подготовка рабочего пространства

Создайте папку для проекта:
mkdir java-projects
cd java-projects


Напишите простую программу:Создайте файл
HelloWorld.java в текстовом редакторе (например, Notepad++, VS Code или Блокнот):
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}


Убедитесь, что имя файла точно совпадает с именем класса (HelloWorld.java), включая регистр.
Сохраните файл в папке
java-projects.


Шаг 2: Компиляция с помощью javac

Команда javac компилирует исходный код в байт-код.

Перейдите в папку с файлом:
cd java-projects


Скомпилируйте программу:
javac HelloWorld.java


Если всё успешно, в папке появится файл HelloWorld.class — это байт-код.

Если возникла ошибка, проверьте:
Имя файла совпадает с именем класса.
Код не содержит синтаксических ошибок (например, пропущена ; или скобка).
JDK установлен (javac -version работает).



Полезные опции javac

-d <папка>: Указывает, куда сохранить .class файлы.

Например:
javac -d bin HelloWorld.java


Создает папку bin и помещает туда HelloWorld.class.

-cp <путь> или -classpath <путь>: Указывает путь к библиотекам или другим .class файлам, если программа использует зависимости.

Например:
javac -cp lib/my-lib.jar HelloWorld.java


-source <версия>: Указывает версию Java для компиляции (например, -source 17).
-target <версия>: Указывает версию байт-кода (обычно совпадает с -source).
-encoding <кодировка>: Указывает кодировку исходного файла (полезно для русских символов на Windows):


javac -encoding UTF-8 HelloWorld.java


-g: Добавляет отладочную информацию в .class файлы для упрощения отладки.
--release <версия>: Компилирует для конкретной версии Java, автоматически настраивая совместимость (например, --release 17).


Компиляция нескольких файлов

Если у вас несколько .java файлов, скомпилируйте их все:
javac *.java


Или укажите конкретные файлы:

javac Main.java Helper.java


#Java #для_новичков #beginner #Java_terminal
🔥1
Шаг 3: Запуск с помощью java

Команда java запускает скомпилированный байт-код на JVM.

Запустите программу:
java HelloWorld


Ожидаемый вывод:
Hello, World!


Указывайте имя класса (HelloWorld), а не файла (HelloWorld.class

Если использовали -d


Если .class файлы находятся в другой папке (например, bin), укажите путь через -cp:
java -cp bin HelloWorld



Полезные опции java

-cp <путь> или -classpath <путь>: Указывает путь к .class файлам или библиотекам.

Например:
java -cp .:lib/my-lib.jar HelloWorld
(На Windows используйте ; вместо : для разделения путей.)


-Xmx<размер>: Устанавливает максимальный объем памяти для JVM (например, -Xmx512m для 512 МБ).
-Xms<размер>: Устанавливает начальный объем памяти (например, -Xms256m).
-D<свойство>=<значение>: Устанавливает системные свойства. Например:
java -Dfile.encoding=UTF-8 HelloWorld
--enable-preview: Включает экспериментальные возможности Java (например, для новых фич в Java 17+).
-jar <файл.jar>: Запускает приложение из JAR-файла (см. ниже).




Шаг 4: Дополнительные команды и процедуры

1. Создание и запуск JAR-файлов
JAR (
Java Archive) — это архив, содержащий .class файлы и ресурсы. Он удобен для распространения программ.

Создание JAR:

Скомпилируйте программу:
javac -d bin HelloWorld.java


Создайте JAR:
jar cf myapp.jar -C bin .


Это создаст myapp.jar, содержащий все файлы из папки bin.
Для запуска через main добавьте манифест:
jar cfm myapp.jar Manifest.txt -C bin .


Где Manifest.txt содержит:
Main-Class: HelloWorld

(Добавьте пустую строку в конце файла.)


Запуск JAR:
java -jar myapp.jar



2. Работа с пакетами
Если ваш код использует пакеты (например, package com.example;), структура папок должна соответствовать имени пакета.

Пример:
package com.example;

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}


Сохраните файл в com/example/HelloWorld.java.

Компиляция:
javac com/example/HelloWorld.java


Запуск:
java -cp . com.example.HelloWorld

(Обратите внимание: используйте полное имя класса с точками, а не слэшами.)


3. Отладка с помощью jdb
JDK включает отладчик jdb для анализа программ.

Скомпилируйте с отладочной информацией:
javac -g HelloWorld.java


Запустите отладчик:
jdb HelloWorld


Основные команды jdb:
stop at HelloWorld:3 — установить точку останова на строке 3.
run — запустить программу.
next — выполнить следующую строку.
print variable — вывести значение переменной.



4. Генерация документации с javadoc

Команда javadoc создает HTML-документацию из комментариев в коде.

Пример кода с Javadoc-комментариями:
/
* Простая программа для вывода приветствия.
* @author Алексей
*/
public class HelloWorld {
/
* Главный метод программы.
* @param args аргументы командной строки
*/
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}


Создание документации:

javadoc -d docs HelloWorld.java

Это создаст папку docs с HTML-файлами документации.


5. Управление зависимостями
Для проектов с внешними библиотеками (например, JAR-файлами):
Укажите библиотеки при компиляции:
javac -cp lib/my-lib.jar MyProgram.java


Укажите их при запуске:
java -cp .:lib/my-lib.jar MyProgram

Для больших проектов используйте системы сборки, такие как Maven или Gradle, которые автоматизируют работу с зависимостями.


6. Работа с модулями (Java 9+)
С Java 9 введена модульная система (JPMS).

Если ваш проект использует модули, создайте файл module-info.java:
module my.module {
requires java.base;
}


Компилируйте с учетом модулей:
javac --module-path lib -d bin com/example/HelloWorld.java module-info.java


Запускайте:
java --module-path bin -m my.module/com.example.HelloWorld


#Java #для_новичков #beginner #Java_terminal
👍1
Шаг 5: Частые ошибки и их решения

Ошибка: javac: command not found:
JDK не установлен или PATH не настроен. Проверьте java -version и javac -version. Настройте JAVA_HOME и добавьте %JAVA_HOME%\bin (Windows) или $JAVA_HOME/bin (macOS/Linux) в PATH.

Ошибка: Error: Could not find or load main class:
Проверьте, что файл .class существует.
Убедитесь, что вы используете имя класса (
java HelloWorld), а не файла (java HelloWorld.class).
Если класс в пакете, укажите полное имя:
java com.example.HelloWorld.
Проверьте -cp:
java -cp bin HelloWorld.


Ошибка: Main method not found:

Убедитесь, что метод main имеет сигнатуру: public static void main(String[] args).

Кодировка (Windows):
Если русские символы отображаются некорректно, используйте:
javac -encoding UTF-8 MyProgram.java
java -Dfile.encoding=UTF-8 MyProgram


Ошибка: incompatible types или синтаксические ошибки:
Проверьте код на опечатки (например, пропущенные ; или неправильные типы).
Убедитесь, что версия
Java соответствует (например, используйте --release 17).


Полезные советы для новичков

Практикуйтесь: Напишите программы, такие как калькулятор или обработчик текстовых файлов, чтобы освоить javac и java.
Организуйте проект:
Храните исходники в src (например, src/com/example/).
Компилируйте в bin: javac -d bin src/com/example/*.
java.
Создавайте JAR для распространения.


Изучите документацию:
javac --help и java --help для списка опций.
Oracle
Java Docs: docs.oracle.com/en/java.

Переходите к IDE: После освоения терминала попробуйте IntelliJ IDEA, OpenIDE или GigaIDE для автоматизации.
Автоматизация: Для больших проектов изучите Maven или Gradle, чтобы упростить компиляцию и управление зависимостями.
Ресурсы: Stack Overflow, Oracle Tutorials, документация OpenJDK.


#Java #для_новичков #beginner #Java_terminal
👍2
Плагины и расширение функциональности в Gradle

Плагины в Gradle — это основной механизм расширения функциональности, позволяющий добавлять задачи, конфигурации и зависимости для автоматизации сборки. Они обеспечивают модульность и гибкость, позволяя адаптировать Gradle под конкретные проекты. Эта статья подробно описывает типы плагинов, встроенные и сторонние плагины, создание собственных плагинов, публикацию на Gradle Plugin Portal, стратегии разрешения плагинов и управление через pluginManagement. Особое внимание уделяется внутренним механизмам, управлению памятью и нюансам.



Типы плагинов

Gradle поддерживает два основных типа плагинов: Script Plugins и Binary Plugins.

Script Plugin (apply from)
Описание: Скриптовые плагины — это файлы Gradle (обычно .gradle или .gradle.kts), которые содержат логику сборки и подключаются к build.gradle через apply from.

Пример (Groovy DSL):
apply from: 'other.gradle'


Содержимое other.gradle:
task customTask {
doLast {
println 'Custom task from script plugin'
}
}


Kotlin DSL:
apply(from = "other.gradle.kts")


Содержимое other.gradle.kts:
tasks.register("customTask") {
doLast {
println("Custom task from script plugin")
}
}


Использование: Для небольших проектов или повторно используемых фрагментов кода в рамках одного проекта.
В памяти: Скриптовые плагины парсятся как обычные Gradle-скрипты, добавляя задачи и конфигурации в модель проекта. Это увеличивает потребление памяти, аналогично основному build.gradle, но overhead минимален (10-50 МБ).



Binary Plugin (apply plugin:)

Описание: Бинарные плагины — это скомпилированные Java/Groovy/Kotlin-классы, распространяемые как JAR-файлы. Они подключаются через apply plugin или блок plugins.

Пример (Groovy DSL):
apply plugin: 'java'


В памяти: Бинарные плагины загружаются как Java-классы в JVM, включая их зависимости. Это увеличивает потребление памяти пропорционально сложности плагина (50-200 МБ для крупных плагинов, таких как android).


plugins {} vs apply plugin:

plugins {}:
Современный способ подключения плагинов, введенный в Gradle 2.1.
Использует декларативный синтаксис и разрешает плагины из Gradle Plugin Portal или репозиториев.


Пример:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.18'
}


Kotlin DSL:
plugins {
java
id("org.springframework.boot") version "2.7.18"
}


Преимущества: Автоматическое разрешение версий, поддержка Gradle Plugin Portal, меньшая вероятность ошибок.



apply plugin:
Традиционный способ, используемый в старых версиях Gradle.

Требует явного указания зависимости в buildscript:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.7.18'
}
}
apply plugin: 'org.springframework.boot'


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

В памяти: plugins {} использует внутренний механизм разрешения Gradle, минимизируя overhead по сравнению с buildscript, который загружает дополнительные зависимости в classpath.

Рекомендация: Используйте plugins {} для современных проектов, так как он проще и поддерживает автоматическое разрешение.


#Java #middle #Gradle #Task #Plugin
👍2
Built-in плагины

Gradle поставляется с набором встроенных плагинов, которые покрывают стандартные сценарии сборки.

java:
Добавляет задачи для компиляции, тестирования и упаковки Java-проектов (например, compileJava, test, jar).

Пример:
plugins {
id 'java'
}


В памяти: Загружает задачи и конфигурации (implementation, testImplementation), увеличивая модель проекта (50-100 МБ).


application:
Добавляет задачи для запуска Java-приложений (run, installDist).

Пример:
plugins {
id 'application'
}
application {
mainClass = 'com.example.Main'
}


В памяти: Добавляет задачи и classpath, минимально увеличивая overhead.


base:
Базовый плагин, добавляющий задачи жизненного цикла (clean, assemble, check).

Пример:
plugins {
id 'base'
}

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


java-library:
Расширяет java, добавляя конфигурации api и implementation для библиотек.

Пример:

plugins {
id 'java-library'
}
dependencies {
api 'org.apache.commons:commons-lang3:3.12.0'
}

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


checkstyle:
Интегрирует проверку стиля кода с помощью Checkstyle.

Пример:
plugins {
id 'checkstyle'
}
checkstyle {
toolVersion = '8.45'
configFile = file('config/checkstyle/checkstyle.xml')
}

В памяти: Загружает конфигурацию Checkstyle и отчеты, увеличивая потребление памяти (50-100 МБ для крупных проектов).


maven-publish:

Позволяет публиковать артефакты в Maven-репозитории.

Пример:
plugins {
id 'maven-publish'
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
maven {
url 'https://nexus.example.com/repository/maven-releases'
}
}
}

В памяти: Загружает метаданные публикации и артефакты, увеличивая overhead при публикации.



#Java #middle #Gradle #Task #Plugin
👍2
Плагины для Kotlin, Android

Kotlin:
Плагин org.jetbrains.kotlin.jvm для JVM-проектов или org.jetbrains.kotlin.android для Android.

Пример:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.9.0'
}
dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.0'
}

В памяти: Загружает Kotlin-компилятор и зависимости, добавляя 100-200 МБ overhead.


Android:

Плагин com.android.application или com.android.library для Android-проектов.

Пример:
plugins {
id 'com.android.application' version '8.1.0'
id 'org.jetbrains.kotlin.android' version '1.9.0'
}
android {
compileSdk 33
defaultConfig {
applicationId 'com.example.app'
minSdk 21
targetSdk 33
versionCode 1
versionName '1.0'
}
}

В памяти: Android-плагины загружают Android SDK, инструменты сборки (dexer, aapt2) и зависимости, что может потребовать 500-1000 МБ памяти.



Создание собственных плагинов

Собственные плагины позволяют кастомизировать сборку. Они могут быть написаны на Groovy, Kotlin или Java.

Плагин на Groovy

Создайте проект с структурой:
my-plugin/
├── src/main/groovy/com/example/MyPlugin.groovy
├── build.gradle


Реализуйте плагин:
package com.example
import org.gradle.api.Plugin
import org.gradle.api.Project

class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.tasks.register('myTask') {
doLast {
println 'Hello from MyPlugin!'
}
}
}
}


Настройте build.gradle:
plugins {
id 'groovy'
id 'maven-publish'
}
group = 'com.example'
version = '1.0'
publishing {
publications {
maven(MavenPublication) {
from components.java
}
}
}


Опубликуйте:
./gradlew publish.

В памяти: Groovy-плагины загружают Groovy-библиотеки, добавляя 50-100 МБ overhead.



Плагин на Kotlin

Создайте проект:
my-plugin/
├── src/main/kotlin/com/example/MyPlugin.kt
├── build.gradle.kts


Реализуйте плагин:
package com.example
import org.gradle.api.Plugin
import org.gradle.api.Project

class MyPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register("myTask") {
doLast {
println("Hello from MyPlugin!")
}
}
}
}


Настройте build.gradle.kts:
plugins {
`kotlin-dsl`
`maven-publish`
}
group = "com.example"
version = "1.0"
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
}
}
}


Опубликуйте:
./gradlew publish.

В памяти: Kotlin-плагины загружают Kotlin-библиотеки, добавляя 50-100 МБ overhead, но обеспечивают строгую типизацию.


Плагин на
Java
Аналогично, но используйте Java-классы:
package com.example;
import org.gradle.api.Plugin;
import org.gradle.api.Project;

public class MyPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getTasks().register("myTask", task -> {
task.doLast(t -> System.out.println("Hello from MyPlugin!"));
});
}
}

В памяти: Java-плагины легче, чем Groovy/Kotlin, так как не требуют дополнительных библиотек DSL.



Публикация плагина
Опубликуйте в локальный репозиторий:
./gradlew publishToMavenLocal


Используйте в другом проекте:
plugins {
id 'com.example.my-plugin' version '1.0'
}



#Java #middle #Gradle #Task #Plugin
👍2
Gradle Plugin Portal

Gradle Plugin Portal (plugins.gradle.org) — центральный репозиторий для публикации и загрузки плагинов.

Публикация:
Зарегистрируйтесь на plugins.gradle.org.
Получите API-ключ.


Настройте build.gradle:
plugins {
id 'com.gradle.plugin-publish' version '1.2.0'
}
pluginBundle {
plugins {
myPlugin {
id = 'com.example.my-plugin'
displayName = 'My Plugin'
description = 'A custom Gradle plugin'
tags = ['custom', 'example']
version = '1.0'
}
}
}


Опубликуйте:
./gradlew publishPlugins.


Использование:
plugins {
id 'com.example.my-plugin' version '1.0'
}

В памяти: Gradle Plugin Portal загружает метаданные плагинов в память при разрешении, добавляя небольшой overhead (10-50 МБ).


Plugin Resolution Strategy

Gradle разрешает плагины из репозиториев, указанных в pluginManagement или buildscript.

Стратегия разрешения:
Поиск: Gradle ищет плагин в Gradle Plugin Portal, Maven Central или пользовательских репозиториях.
Конфликты: Если плагин доступен в нескольких версиях, Gradle выбирает новейшую или указанную версию.


Настройка:
configurations.all {
resolutionStrategy {
force 'com.example:my-plugin:1.0'
}
}

В памяти: Разрешение плагинов загружает их метаданные и зависимости в память, аналогично зависимостям проекта.


pluginManagement в settings.gradle

Блок pluginManagement в settings.gradle позволяет централизованно управлять плагинами для всех модулей.

Пример:
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
plugins {
id 'org.springframework.boot' version '2.7.18'
}
}


Kotlin DSL:
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
plugins {
id("org.springframework.boot") version "2.7.18"
}
}


Назначение:
Указывает репозитории для плагинов.
Фиксирует версии плагинов для всех модулей.


Поддерживает кастомные разрешения:

pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == 'com.example.my-plugin') {
useModule('com.example:my-plugin:1.0')
}
}
}
}

В памяти: pluginManagement загружает метаданные плагинов во время инициализации, добавляя минимальный overhead (10-30 МБ), но обеспечивая согласованность версий.



Нюансы и внутренние механизмы

Управление памятью:
Плагины загружаются как Java-классы в JVM, включая их зависимости. Крупные плагины (например, android) могут добавлять 500-1000 МБ overhead.
Скриптовые плагины парсятся как Groovy/Kotlin-скрипты, увеличивая потребление памяти из-за динамической компиляции.
Оптимизируйте с помощью pluginManagement для централизованного управления и минимизации дублирования.


Кэширование:
Плагины и их зависимости кэшируются в ~/.gradle/caches/modules-2, снижая сетевые запросы.
Очистка кэша:
rm -rf ~/.gradle/caches.


Производительность:
plugins {} быстрее, чем apply plugin:, за счет оптимизированного разрешения.
Параллельное выполнение задач (--parallel) ускоряет сборку, но увеличивает пиковое потребление памяти.
Используйте --configure-on-demand для сокращения времени конфигурации.


Отладка:
Используйте --info или --debug для анализа загрузки плагинов:
./gradlew build --debug


Проверьте список задач:
./gradlew tasks --all.


Build Scans (--scan) показывают влияние плагинов на сборку.

Совместимость:

Убедитесь, что плагины совместимы с версией Gradle (например, Android-плагины требуют Gradle 7.0+).
Используйте JAVA_HOME с JDK 8+ (рекомендуется 11+).


Безопасность:
Храните учетные данные для репозиториев в ~/.gradle/gradle.properties с ограниченными правами (chmod 600).
Проверяйте плагины из Gradle Plugin Portal на наличие GPG-подписей.


#Java #middle #Gradle #Task #Plugin
👍2