Java библиотека
31.6K subscribers
2.31K photos
78 videos
8 files
2.05K links
Книги, статьи, мемы и многое другое для Java программиста!

По сотрудничеству и рекламе: @NadikaKir

Канал в перечне РКН: https://vk.cc/cJrT4A

Мы на бирже: https://telega.in/c/javalib/

Сообщество VK https://vk.com/javatutorial
Download Telegram
🌐 JTS Topology Suite — мощная Java-библиотека для работы с геометрией. Проект предоставляет инструменты для создания и манипуляции векторной геометрией, включая пространственные операции. Входит в рабочую группу LocationTech Eclipse Foundation и служит основой для многих GIS-решений.

В комплекте идёт TestBuilder с GUI для визуализации геометрии и тестирования функций. Библиотека особенно полезна разработчикам GIS-приложений систем пространственного анализа. На базе JTS построены популярные порты для C++, .NET и JavaScript.

🖥 GitHub

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54🔥4
👩‍💻 Интеграция Redis в Spring Boot с AI

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

📝 Промпт:
Generate a Spring Boot service that integrates with Redis to handle [caching / rate limiting / distributed locks / task queues] for [описание бизнес-логики].  
Include configuration, connection pooling, and example use cases.
Ensure reliability with TTL management, error handling, and fallback mechanisms.
Use Spring Data Redis or Lettuce/Jedis client. Explain the trade-offs of chosen technologies and patterns (e.g., Cache Aside, Write-Through).


💡 Дополнительные возможности:

— Добавьте also include support for Redis Streams (or Pub/Sub) for event-driven processing with examples для включения Redis Streams или Pub/Sub.
— Добавьте use Lua scripts for atomic operations and provide sample use cases (e.g., rate limiting or locking) для Lua-скриптов.
— Добавьте integrate Spring Boot Actuator and Redis metrics for monitoring cache performance (hit/miss, TTL, etc.) для мониторинга кеша и статистики.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍5🔥3
🖥 Logback Access Reactor Netty — управление access-логами для реактивных веб-приложений на Java и Kotlin. Этот проект предоставляет интеграцию популярной Java библиотеки Logback-access с HTTP-сервером Reactor Netty, на которым построен реактивный стек Spring WebFlux.

Инструмент доступен для использования двумя способами: в виде Spring Boot стартера для Spring Boot приложений и в виде отдельной библиотеки для приложений, которые используют Reactor Netty HTTP Server напрямую. Настройка простая: достаточно подключить зависимость в проект и добавить файл logback-access.xml с Logback конфигурацией access-логов (appender, encoder, pattern).

🖥 GitHub

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43🔥3
👩‍💻 Как настроить JWT аутентификацию в Spring Boot

Для настройки JWT аутентификации в Spring Boot следуйте этим шагам:

1️⃣ Добавьте зависимости
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.11.5</version>
</dependency>


2️⃣ Создайте класс для генерации JWT
public class JwtTokenUtil {
private static final String SECRET_KEY = "secretKey";

public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

public static String getUsernameFromToken(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}

public static boolean isTokenExpired(String token) {
return getExpirationDateFromToken(token).before(new Date());
}

private static Date getExpirationDateFromToken(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
}

public static boolean validateToken(String token, String username) {
return (username.equals(getUsernameFromToken(token)) && !isTokenExpired(token));
}
}


3️⃣ Создайте фильтр для JWT токенов
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final String HEADER_STRING = "Authorization";
private static final String TOKEN_PREFIX = "Bearer ";

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String header = request.getHeader(HEADER_STRING);

if (header != null && header.startsWith(TOKEN_PREFIX)) {
String token = header.substring(TOKEN_PREFIX.length());

try {
if (JwtTokenUtil.validateToken(token, JwtTokenUtil.getUsernameFromToken(token))) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
JwtTokenUtil.getUsernameFromToken(token), null, new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (ExpiredJwtException e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}

filterChain.doFilter(request, response);
}
}


4️⃣ Настройте Spring Security
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter());
}
}


5️⃣ Создайте контроллер для логин
@RestController
public class AuthController {

@PostMapping("/login")
public String login(@RequestBody AuthRequest authRequest) {
if ("admin".equals(authRequest.getUsername()) && "admin123".equals(authRequest.getPassword())) {
return JwtTokenUtil.generateToken(authRequest.getUsername());
}
return "Invalid credentials";
}
}


Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍10🔥5
⚠️ Чем опасен Scheduled(fixedRate) без Transactional в Spring?

Многие используют @Scheduled для запуска задач по таймеру, но забывают об одной критичной вещи — транзакциях. Особенно если указан fixedRate.

👎 Проблема:

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

Пример:

@Scheduled(fixedRate = 10_000)
public void cleanUp() {
List<Job> jobs = jobRepository.findAllByStatus(PENDING);
jobs.forEach(job -> {
job.setStatus(PROCESSING);
jobRepository.save(job);
});
}



💥 Через 10 секунд начнёт работать следующий вызов, даже если первый ещё не закончен.

Решение: обернуть в @Transactional и использовать блокировки:


@Transactional
@Scheduled(fixedRate = 10_000)
public void cleanUp() {
List<Job> jobs = jobRepository.findAllByStatusForUpdate(PENDING);
...
}



📌 Также можно:
— использовать fixedDelay вместо fixedRate — он ждёт окончания предыдущей задачи
— добавить флаг locked, чтобы явно помечать уже взятые задачи
— заменить @Scheduled на более надёжные инструменты:

🟢Spring Batch — для сложных задач
🟢Spring Integration / Camunda — если нужны гарантии и retry
🟢Quartz — если важны очередь и контроль запуска

🔧 Не упирайтесь в @Scheduled, если задача критична к повторной обработке.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍6🔥5😁1
🧑‍💻 Магия IntelliJ IDEA

Когда нужно аккуратно скопировать блок кода, метод, выражение или просто цепочку вызовов — забудьте про мышь. У IntelliJ есть инструмент поумнее.

Хоткей: Ctrl + W (или Cmd + W на macOS)

🟢Что делает

По нажатии IDEA «расширяет» выделение:
— сначала слово,
— потом выражение,
— затем строку целиком,
— потом блок кода,
— и так до всего метода или класса.

🟢Зачем это нужно

— Быстро выделить логически связанный фрагмент без лишней возни.
— Удобно вырезать или перемещать части кода.
— Работает даже внутри строк, SQL-запросов, JSON и XML.

🟢Как использовать

— Поставьте курсор в нужное место.
— Нажимайте Ctrl + W по очереди — и наблюдайте, как IDEA понимает структуру кода.
— Ctrl + Shift + W — отменяет шаг назад.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥154
🧱 Maven vs. ⚡️Gradle — что выбрать разработчику?

Когда речь заходит о сборке Java-проектов, чаще всего выбор стоит между двумя фреймворками: Maven и Gradle. Оба стали стандартом в индустрии, но у каждого — свои сильные и слабые стороны. Разбираем, кому что подойдёт 👇

🟢Maven — стабильная классика:

Строгая структура: легко читать и сопровождать
Надёжность и предсказуемость сборки
Много плагинов и готовых решений
⚠️ XML-конфигурация громоздкая
⚠️ Медленнее по сравнению с Gradle

🟡Gradle — гибкость и скорость:

Поддержка Kotlin и Groovy DSL
Инкрементальные сборки и кэширование
Гибкий подход к конфигурации
⚠️ Порог входа выше
⚠️ Сложности с отладкой настроек

📌 Вывод:

🟢 Выбирай Maven, если важны стабильность, читаемость и простота
🟡 Выбирай Gradle, если хочешь максимум производительности и гибкости

💬 В крупных проектах Gradle становится всё популярнее, особенно с Kotlin.
Но в enterprise-среде Maven по-прежнему остаётся стандартом.

А ты чем пользуешься? Делись в комментариях👇

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
11👍3🔥3
👩‍💻 Генерация REST API на Spring Boot с AI

Нужно быстро развернуть REST API c валидацией, логированием, DTO, безопасностью и документацией?
AI справится с этим за один промпт — код будет готов к продакшну, с учетом архитектурных паттернов.

📝 Промпт:

Generate a Spring Boot REST API for managing [сущность или бизнес-логика, например: product catalog, user profiles, task assignments].
Include CRUD endpoints, validation (Hibernate Validator), exception handling, DTO mapping (MapStruct or ModelMapper), and OpenAPI documentation.
Ensure security with JWT-based authentication and role-based access control (Spring Security).
Use layered architecture (Controller → Service → Repository) and follow clean code principles. Add unit tests for controller and service layers.


💡 Расширения:

— Добавьте integrate with PostgreSQL using Spring Data JPA and specify indexes/constraints для подключения к БД.
— Добавьте support pagination and filtering with Pageable and Specification API для удобных выборок.
— Добавьте plug into CI/CD pipeline with Docker and GitHub Actions для продвинутого автодеплоя.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥97👍5😁1
🖥 Java‑задача для тех, кто не боится `Concurrency` и `Immutable`

Представьте, что вы пишете in-memory кеш конфигураций. У вас есть ConfigService, который должен:

🔘Загружать конфигурации из базы (эмулируется loadConfigFromDB())
🔘Раздавать *текущую* версию конфигурации многопоточным клиентам
🔘Давать 100% thread‑safety и 0 блокировок
🔘Позволять hot‑reload без блокировки клиентов
🔘Гарантировать, что ни один поток никогда не увидит "смешанную" конфигурацию

🔧 Что нужно сделать:
Реализуйте ConfigService, который использует AtomicReference<Config> и Immutable-объекты, чтобы:

1. Конфигурация всегда была консистентной
2. Потоки не блокировали друг друга
3. Обновления конфигурации были моментальными и безопасными

📦 Пример API:

class ConfigService {
public Config getCurrentConfig(); // read-only, вызывается часто
public void reload(); // обновить конфиг, редко
}



🧠 Хитрость: нельзя использовать synchronized, volatile массивы, CopyOnWrite, ReentrantLock, и т.п. — только атомарность и неизменяемость.

🚀 Challenge accepted?

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍65
Java Совет 🖥
Как понять, что Java‑код мог быть сгенерирован ИИ?

🟢Если вы видите в коде Collectors.toList(), а не Stream.toList() — это явный намёк 😉

Stream.toList() появился только в Java 16.
А Collectors.toList() — с нами ещё с Java 8, поэтому его до сих пор полно в туториалах, на Stack Overflow и во всех датасетах, на которых обучают ИИ.

📌 Документация

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
😁16👍65🔥4🎉1
📌 Сохраняйте шпаргалку по структурам данных

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1
👩‍💻 Генерация микросервиса на Spring Boot с Event Sourcing и CQRS

Ищете решение для построения масштабируемого микросервиса с использованием Event Sourcing и CQRS? AI поможет вам сгенерировать шаблон, который будет учитывать все архитектурные принципы и лучшие практики для сложных бизнес-логик.

📝 Промпт:
Generate a Spring Boot microservice that implements Event Sourcing and CQRS (Command Query Responsibility Segregation).

— Implement event storage (using EventStore or any other event-sourcing mechanism).
— Design the service layer using separate models for command and query operations.
— Use an event-driven approach with messaging (e.g., Kafka or RabbitMQ) to communicate between services.
— Secure the API with JWT authentication and role-based access control (Spring Security).
— Implement database persistence for event snapshots and projections (using Spring Data JPA).


💡 Расширения:

— Добавьте support asynchronous messaging with Kafka or RabbitMQ для обработки событий между микросервисами.
— Добавьте implement Command and Query models using CQRS для разделения логики записи и чтения данных.
— Добавьте integrate snapshotting mechanism for efficient aggregate recovery и управление состоянием событий.
— Добавьте enable monitoring and tracing with Spring Actuator and Zipkin для отслеживания производительности и запросов.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍74🔥3
🖥 Продвинутая задача JavaНевидимая утечка памяти в лямбдах

Задача:

Предположим, вы пишете сервис, в котором создаются задачи (например, отложенные действия):


public class TaskScheduler {
private final List<Runnable> tasks = new ArrayList<>();

public void scheduleTask(String name) {
String largeData = name.repeat(10_000); // имитируем большой объект

tasks.add(() -> {
System.out.println("Running task: " + name);
});
}

public void runAll() {
tasks.forEach(Runnable::run);
}
}


Теперь создайте 1_000_000 таких задач:


TaskScheduler scheduler = new TaskScheduler();
for (int i = 0; i < 1_000_000; i++) {
scheduler.scheduleTask("Task" + i);
}


Вопрос:
Почему String largeData не освобождается сборщиком мусора, хотя он нигде явно не используется?

Разбор:

На первый взгляд, largeData нигде не используется — его можно было бы освободить.
Но на самом деле лямбда-захват переменной name удерживает весь стек метода scheduleTask, включая largeData.

Это называется неявная утечка памяти через замыкания.

---

Как исправить?

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


public void scheduleTask(String name) {
String taskName = name; // только то, что действительно нужно
tasks.add(() -> {
System.out.println("Running task: " + taskName);
});
}


Или даже:


tasks.add(() -> System.out.println("Running task: " + name));


НО! Убедитесь, что переменные вне лямбды не держат в памяти тяжёлые объекты, которые не нужны после исполнения.

💡 Вывод:
- Java лямбды могут неявно захватывать контекст, включая большие объекты
- Это может привести к утечкам памяти, особенно в long-lived объектах (пулы задач, слушатели и т.п.)
- Профилируйте и проверяйте, что захватывает ваша лямбда

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥156👍6
👩‍💻 Как настроить фильтрацию запросов с помощью Spring Security и IP-блокировки

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

1️⃣ Добавление зависимостей

В файл pom.xml добавьте следующие зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


2️⃣ Создание фильтра для блокировки IP-адресов

Создайте фильтр, который будет проверять IP-адрес пользователя и блокировать его, если он находится в списке запрещённых:
@Component
public class IpFilter extends OncePerRequestFilter {

private static final Set<String> blockedIps = new HashSet<>(Arrays.asList("192.168.1.100", "10.0.0.5"));

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String ipAddress = request.getRemoteAddr();

if (blockedIps.contains(ipAddress)) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write("Access Denied: Your IP is blocked.");
return;
}

filterChain.doFilter(request, response);
}
}


3️⃣ Настройка Spring Security для использования фильтра

Теперь настроим Spring Security, чтобы наш фильтр IP-блокировки применялся ко всем входящим запросам:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private IpFilter ipFilter;

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/public/**").permitAll() // Доступ для публичных ресурсов
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
.and()
.addFilterBefore(ipFilter, UsernamePasswordAuthenticationFilter.class); // Вставляем фильтр IP
}
}


4️⃣ Создание контроллера для тестирования

Создадим простой контроллер с двумя маршрутами: один доступен всем пользователям, а другой требует аутентификации:
@RestController
public class TestController {

@GetMapping("/public/hello")
public String publicHello() {
return "Hello from public endpoint!";
}

@GetMapping("/private/hello")
public String privateHello() {
return "Hello from private endpoint, you are authenticated!";
}
}


5️⃣ Важно

Этот подход не является универсальной защитой от всех типов атак. Он помогает ограничить доступ для определённых IP-адресов, но не защищает от более сложных угроз, таких как атаки с подменой IP (например, через прокси-серверы).

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

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥53
🖥 Java‑задача для тех, кто не боится `Concurrency` и `Immutable`

Представьте, что вы пишете in-memory кеш конфигураций. У вас есть ConfigService, который должен:

🟢 Загружать конфигурации из базы (эмулируется loadConfigFromDB())
🟢Раздавать *текущую* версию конфигурации многопоточным клиентам
🟢Давать 100% thread‑safety и 0 блокировок
🟢Позволять hot‑reload без блокировки клиентов
🟢Гарантировать, что ни один поток никогда не увидит "смешанную" конфигурацию

🔧 Что нужно сделать:
Реализуйте ConfigService, который использует AtomicReference<Config> и Immutable-объекты, чтобы:

1. Конфигурация всегда была консистентной
2. Потоки не блокировали друг друга
3. Обновления конфигурации были моментальными и безопасными

📦 Пример API:

class ConfigService {
public Config getCurrentConfig(); // read-only, вызывается часто
public void reload(); // обновить конфиг, редко
}


🧠 Хитрость: нельзя использовать synchronized, volatile массивы, CopyOnWrite, ReentrantLock, и т.п. — только атомарность и неизменяемость.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍43🔥3
🧑‍💻 Магия IntelliJ IDEA

Если обычный поиск по проекту вам тесен — попробуйте Structural Search and Replace (SSR). Это инструмент, который ищет и меняет код не по тексту, а по его структуре — как настоящий парсер.

🟢Что делает

Находит шаблоны кода в проекте с учётом синтаксиса языка. Можно искать любые конструкции — например, все System.out.println или пустые catch блоки — и сразу массово их переписывать.

🟢Зачем это нужно

— Автоматически находить антипаттерны.
— Глобально рефакторить одинаковые места.
— Быстро готовить проект к миграции или внедрению новых стандартов кодирования.

🟢Как использовать

— Откройте Edit → Find → Search Structurally или нажмите Shift + Shift и введите Structural Search.
— Задайте шаблон — например, System.out.println($arg$);.
— IDEA выделит все совпадения по всей кодовой базе.
— Для массовой замены найдите в поиске Replace Structurally — можно указать новый шаблон, и IDEA всё подставит сама.
— Шаблоны можно сохранять и делиться ими с командой.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥13👍75
🌐 dnsjava — DNS-клиент и сервер на Java. Эта библиотека предлагает полную реализацию DNS-протокола с поддержкой современных стандартов — от DNSSEC и EDNS0 до TSIG-аутентификации. Проект позволяет не только выполнять запросы, но и организовывать трансфер зон, динамические обновления и даже разворачивать авторитативный сервер.

Инструмент имеет встроенный механизм валидации DNSSEC через ValidatingResolver и гибкая система конфигурации через системные свойства. Поддерживает Java 8+ и может заменять стандартный DNS-резолвер JVM.

🖥 GitHub

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2🔥2
👩‍💻 Генерация инфраструктуры для Contract Testing с Spring Cloud Contract и Testcontainers

Работаете с микросервисной архитектурой? Тогда знаете, как сложно обеспечить стабильные API-контракты между сервисами. Contract Testing решает эту проблему. А AI поможет быстро сгенерировать заготовку всей инфраструктуры для автоматизированной валидации контрактов.

📝 Промпт:
Generate a Java Spring Boot setup for contract testing using Spring Cloud Contract and Testcontainers.
— Configure a provider service and a consumer service.
— Use Spring Cloud Contract to define and verify contracts.
— Integrate with Testcontainers to run provider stubs in isolated environments.
— Add Gradle or Maven setup for running contract tests in CI.
— Provide examples for both producer and consumer side tests.


💡 Расширения:

— Добавьте integration with GitLab CI/CD or GitHub Actions для автоматической валидации контрактов при push'ах и pull request'ах.
— Добавьте generate stub JARs using Spring Cloud Contract Verifier для повторного использования контрактов на стороне потребителя.
— Добавьте handle contract mismatches gracefully with test reports and logs для быстрого выявления расхождений между сервисами и прозрачной отладки в CI.
— Добавьте include real-world example: REST endpoint for user profile with request validation and response structure как шаблон, который можно адаптировать под любую бизнес-логику.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥2
🧑‍💻 Магия IntelliJ IDEA

Если вы часто просматриваете стек вызовов или трассируете поведение методов — попробуйте «Call Hierarchy» (Ctrl + Alt + H). Этот инструмент показывает, кто вызывает ваш метод — и кто вызывает вызывающего, до самого верхнего уровня.

🟢Что делает

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

🟢Зачем это нужно

— Находит неочевидные связи между частями кода.
— Упрощает работу с легаси: видно, какие методы безопасно менять.
— Быстро определяет, как ошибка «долетела» до нужного места.

🟢 Как использовать

— Поставьте курсор на метод → нажмите Ctrl + Alt + H.
— IDEA откроет дерево вызовов (Call Hierarchy).
— Вы можете «разворачивать» цепочку вверх по стеку или вниз.

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍15🔥32
🖥 jclasslib — мощный инструмент для глубокого анализа и модификации Java-байткода. Это полноценный редактор, позволяющий напрямую изменять констант-пул и инструкции байткода через удобный графический интерфейс.

Проект сочетает desktop-приложение для визуальной работы и Kotlin Multiplatform библиотеку для программного взаимодействия с class-файлами. Поддерживает работу с JAR-архивами, предлагает темную тему и локализации на несколько языков.

🖥 GitHub

Java библиотека #java
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥62👍1