ClassGraph
Если вы когда-либо писали плагины, делали автоконфигурацию или искали классы с аннотациями — вам пригодится ClassGraph. Это быстрый и гибкий инструмент для сканирования classpath'а, аналог Reflections, но с куда лучшей производительностью и расширенной функциональностью.
📌 Что умеет ClassGraph:
— Находит классы по аннотациям, интерфейсам, суперклассам
— Позволяет искать ресурсы, inner-классы, модули, методы и поля
— Работает с JAR-файлами, модулями JPMS, Android, OSGi и даже нестандартной загрузкой классов
— Позволяет делать глубокий анализ зависимостей и иерархий
— Поддерживает черный/белый список пакетов (include/exclude)
⚡️ Почему лучше, чем Reflections:
— Существенно быстрее при сканировании большого classpath
— Умнее — может обрабатывать class-loader’ы, не теряя контекста
— Поддерживает более новые фичи JVM, включая модули (Java 9+)
— Активно поддерживается и обновляется
🧠 Полезно для:
— Фреймворков с динамической загрузкой
— Плагинных систем
— Анализа и визуализации зависимостей
— Разработки DI-контейнеров, автосканеров и DSL'ов
🔗 classgraph на GitHub
✅ Java библиотека #java
Если вы когда-либо писали плагины, делали автоконфигурацию или искали классы с аннотациями — вам пригодится ClassGraph. Это быстрый и гибкий инструмент для сканирования classpath'а, аналог Reflections, но с куда лучшей производительностью и расширенной функциональностью.
📌 Что умеет ClassGraph:
— Находит классы по аннотациям, интерфейсам, суперклассам
— Позволяет искать ресурсы, inner-классы, модули, методы и поля
— Работает с JAR-файлами, модулями JPMS, Android, OSGi и даже нестандартной загрузкой классов
— Позволяет делать глубокий анализ зависимостей и иерархий
— Поддерживает черный/белый список пакетов (include/exclude)
⚡️ Почему лучше, чем Reflections:
— Существенно быстрее при сканировании большого classpath
— Умнее — может обрабатывать class-loader’ы, не теряя контекста
— Поддерживает более новые фичи JVM, включая модули (Java 9+)
— Активно поддерживается и обновляется
🧠 Полезно для:
— Фреймворков с динамической загрузкой
— Плагинных систем
— Анализа и визуализации зависимостей
— Разработки DI-контейнеров, автосканеров и DSL'ов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤3🔥3
Для Java-приложений в Docker лучше всего использовать многоступенчатую сборку с
jlink
или jpackage
, чтобы собрать кастомный JRE только с нужными модулями.
# Этап сборки jar
FROM maven:3.9.8-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests
# Этап с оптимизированным JRE
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
COPY --from=builder /app/target/myapp.jar myapp.jar
# Оптимизация: ограничим потребление памяти JVM в контейнере
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75", "-jar", "myapp.jar"]
💡 Такой подход:
- уменьшает размер образа,
- использует только нужные зависимости,
- и корректно учитывает ограничения памяти/CPU контейнера.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14👍10🔥5
Хотите быстро замерить время выполнения кода без тяжёлых библиотек?
Используйте
System.nanoTime()
- он точнее, чем currentTimeMillis()
, и подходит для измерения производительности:
long start = System.nanoTime();
// код, который нужно замерить
Thread.sleep(500);
long end = System.nanoTime();
System.out.println("Время выполнения: " + (end - start) / 1_000_000 + " ms");
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍7🔥3
Работаете с классом на 500 строк? Теряетесь в методах и полях? Structure Tool Window помогает быстро сориентироваться в любом файле.
— Показывает структуру текущего файла: методы, поля, вложенные классы
— Подсвечивает override-методы, конструкторы, аннотации
— Поддерживает навигацию и поиск по элементам
— Работает для Java, Kotlin, XML, и даже .properties
— Быстро находите нужный метод без скроллинга
— Помогает понять, как устроен чужой код
— Ускоряет навигацию по большим классам и конфигурациям
— Alt+7 (или Cmd+7 на macOS) — откроет Structure
— Можно настроить сортировку, группировку и фильтры
— Клик — и вы уже в нужном месте кода
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥6❤4
🦙 Jlama — LLM-движок для Java-разработчиков. Проект поддерживает популярные модели вроде Llama 3, Mistral и Gemma 2, предлагая инструменты для их загрузки, квантования и запуска. Он работает с Java 20+ и поддерживает распределенные вычисления.
Разработчики могут использовать Jlama как через CLI-интерфейс для локального тестирования моделей, так и встраивать его в свои проекты через Maven-зависимости. Проект будет полезен для интеграции LLM в enterprise-решения без перехода на Python-стек.
🖥 GitHub
✅ Java библиотека #java
Разработчики могут использовать Jlama как через CLI-интерфейс для локального тестирования моделей, так и встраивать его в свои проекты через Maven-зависимости. Проект будет полезен для интеграции LLM в enterprise-решения без перехода на Python-стек.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍9❤4
S3-совместимое хранилище (AWS S3, MinIO, Yandex Object Storage и т.п.) — удобный способ хранить файлы вне приложения. Подключим его к Spring Boot и реализуем минимальный upload/download.
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.25.60</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
ИЛИ
implementation 'software.amazon.awssdk:s3:2.25.60'
implementation 'org.springframework.boot:spring-boot-starter-web'
s3:
region: eu-central-1
accessKey: minioadmin
secretKey: minioadmin
bucket: demo-bucket
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
@Configuration
public class S3Config {
@Bean
public S3Client s3Client(S3Props props) {
var builder = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(props.accessKey(), props.secretKey())))
.region(Region.of(props.region()))
.httpClientBuilder(UrlConnectionHttpClient.builder());
if (props.endpoint() != null && !props.endpoint().isBlank()) {
builder = builder
.endpointOverride(java.net.URI.create(props.endpoint()))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(props.pathStyleAccess())
.build());
}
return builder.build();
}
@Bean
public S3Props s3Props(org.springframework.core.env.Environment env) {
return new S3Props(
env.getProperty("s3.endpoint"),
env.getProperty("s3.region", "eu-central-1"),
env.getProperty("s3.accessKey"),
env.getProperty("s3.secretKey"),
env.getProperty("s3.bucket", "demo-bucket"),
Boolean.parseBoolean(env.getProperty("s3.pathStyleAccess", "true"))
);
}
public record S3Props(String endpoint, String region, String accessKey,
String secretKey, String bucket, boolean pathStyleAccess) {}
}
@Service
@RequiredArgsConstructor
public class S3StorageService {
private final S3Client s3;
private final S3Config.S3Props props;
public String upload(String originalName, String contentType, byte[] bytes) {
String key = UUID.randomUUID() + "_" + originalName;
s3.putObject(PutObjectRequest.builder()
.bucket(props.bucket())
.key(key)
.contentType(contentType)
.build(),
RequestBody.fromBytes(bytes));
return key;
}
public byte[] download(String key) {
GetObjectResponse[] meta = new GetObjectResponse[1];
try (var resp = s3.getObject(GetObjectRequest.builder()
.bucket(props.bucket()).key(key).build())) {
meta[0] = resp.response();
return resp.readAllBytes();
} catch (Exception e) {
throw NoSuchKeyException.builder().message("Object not found: " + key).build();
}
}
public void createBucketIfMissing() {
var bucket = props.bucket();
var exists = s3.listBuckets().buckets().stream().anyMatch(b -> b.name().equals(bucket));
if (!exists) s3.createBucket(CreateBucketRequest.builder().bucket(bucket).build());
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15🔥7👍3⚡1
В Java часто нужно работать с датами и временем. Вместо устаревших Date и Calendar лучше использовать современное API java.time, появившееся в Java 8. Оно более удобное, безопасное и читаемое.
Например, если нужно добавить дни к текущей дате:
import java.time.LocalDate;
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusDays(7);
System.out.println("Сегодня: " + today);
System.out.println("Через неделю: " + nextWeek);
}
}
✅ Код становится проще и понятнее.
📌 Совет: всегда отдавайте предпочтение java.time вместо старых классов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤21💯6🔥3
В свежем релизе — важные улучшения, о которых стоит знать каждому Java-разработчику:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4🎉4❤1
Интеграция системы оповещений через почтовую рассылку
Нужна быстрая интеграция с системой оповещений для отправки уведомлений по электронной почте? Используйте AI, чтобы автоматизировать подключение почтового сервиса и эффективно управлять рассылками.
📝 Промпт:
💡 Расширения:
— Добавьте
— Добавьте
✅ Java библиотека #java
Нужна быстрая интеграция с системой оповещений для отправки уведомлений по электронной почте? Используйте AI, чтобы автоматизировать подключение почтового сервиса и эффективно управлять рассылками.
📝 Промпт:
Generate an email notification system integration for a Spring Boot 3 application.
— Set up SMTP configuration in application.properties with email provider details (e.g., Gmail, SendGrid).
— Implement EmailService to send notifications using JavaMailSender and MimeMessage.
— Create a method to send transactional emails (e.g., order confirmation, password reset).
— Integrate email templates using Thymeleaf or FreeMarker for dynamic content generation.
— Set up email queues using Spring’s @Async to process notifications asynchronously.
— Handle email failures gracefully with retry mechanisms and user feedback.
— Добавьте
Send welcome emails with a personalized subject and content for new user registrations
для приветственных писем.— Добавьте
Implement email subscription management for users to opt-in/opt-out from specific notifications
для управления подписками пользователей.Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4❤2😁1
При работе с коллекциями часто нужно проверить элемент на наличие в списке.
Если использовать
List.contains()
, то поиск будет O(n) — медленно на больших данных. Лучше сразу применять
Set
(например, HashSet
) для поиска за O(1). Пример
import java.util.*;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "orange", "grape");
// Медленно — O(n)
boolean slowCheck = list.contains("orange");
// Быстро — O(1)
Set<String> set = new HashSet<>(list);
boolean fastCheck = set.contains("orange");
System.out.println("List check: " + slowCheck);
System.out.println("Set check: " + fastCheck);
}
}
📌 Итог:
- Для поиска в коллекции всегда используйте Set, если не нужен порядок.
- HashSet → быстрый доступ за O(1).
- TreeSet → доступ за O(log n), но с сортировкой элементов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17😁6🔥4❤3