Java

223 posts in this section

Setting Up Java 25: Install, Tooling & IDE Configuration

Installing Java 25 Option 1: SDKMAN! (Recommended) SDKMAN! is the easiest way to install and switch between Java versions on macOS and Linux. # Install SDKMAN! if you don't have it curl -s "https://get.sdkman.io" | bash source "$HOME/.sdkman/bin/sdkman-init.sh" # List available Java 25 distributions sdk list java | grep "25" # Install Eclipse Temurin 25 (open-source, most common) sdk install java 25-tem # Set as default globally sdk default java 25-tem # Verify java -version # openjdk version "25" 2025-09-16 Switch between versions per project:

Continue reading »

Structured Concurrency (JEP 505): Preview 5 — What Changed?

Note: JEP 505 is a preview feature in Java 25 (5th preview). Enable with --enable-preview. The API has been stable for several rounds and is expected to finalize in Java 26. The Problem with Unstructured Concurrency Classic Java concurrency with ExecutorService is unstructured: you submit tasks, and those tasks have no formal relationship with the code that submitted them. This causes three recurring problems: Problem 1: Partial failure leaves orphaned tasks ExecutorService exec = Executors.

Continue reading »

@MappedSuperclass: Sharing Fields Without Inheritance Tables

Introduction Almost every entity in a real application shares a few common fields: id, createdAt, updatedAt, and perhaps version. Writing these in every entity class is repetitive and error-prone. @MappedSuperclass lets you define them once in a base class that all entities extend — without creating a parent table or any inheritance mapping in the database. What Is @MappedSuperclass? @MappedSuperclass marks a class whose field mappings are inherited by subclass entities.

Continue reading »

@SendTo and @KafkaHandler: Chaining Consumers and Multi-Type Dispatch

@SendTo — Chaining Listeners @SendTo on a @KafkaListener method automatically sends the return value to another Kafka topic. This is how you build event pipelines without manually calling KafkaTemplate.send() in your listener. flowchart LR T1["orders\n(OrderPlacedEvent)"] T2["orders-confirmed\n(OrderConfirmedEvent)"] T3["inventory-events\n(StockReservedEvent)"] T1 -->|"@KafkaListener\n@SendTo"| L1["confirmOrder()"] L1 --> T2 T2 -->|"@KafkaListener\n@SendTo"| L2["reserveStock()"] L2 --> T3 Basic @SendTo @KafkaListener(topics = "orders", groupId = "confirmation-service") @SendTo("orders-confirmed") public OrderConfirmedEvent onOrder(OrderPlacedEvent event) { // Return value is automatically sent to "orders-confirmed" return new OrderConfirmedEvent( event.

Continue reading »

@Transactional in Depth: Propagation, Isolation, and Rollback

What @Transactional Does @Transactional tells Spring to wrap the annotated method in a database transaction. Spring opens the transaction before the method starts and commits (or rolls back) when it ends. The annotation works via an AOP proxy — understanding this proxy model is essential for avoiding the most common @Transactional bugs. The AOP Proxy Model Spring creates a proxy around your bean. When code outside the bean calls a @Transactional method, the call goes through the proxy, which manages the transaction:

Continue reading »

Actuator Security and Production Hardening

The Actuator Security Problem Spring Boot Actuator exposes endpoints that reveal sensitive information about your application — environment variables, configuration properties, heap dumps, thread dumps, and the ability to shut down the application remotely. An exposed /actuator/env endpoint can leak database passwords, API keys, and JWT signing secrets. An exposed /actuator/shutdown is a denial-of-service button. Actuator security is not optional in production. Actuator Endpoints and Their Risk Level Endpoint Exposes Risk /actuator/health Application health Low — often public /actuator/info App metadata Low /actuator/metrics JVM/HTTP metrics Medium — business data /actuator/env All configuration properties (including secrets) Critical /actuator/configprops All @ConfigurationProperties values Critical /actuator/loggers Log levels (writable) High /actuator/heapdump Full JVM heap as a file Critical /actuator/threaddump Thread state Medium /actuator/mappings All URL mappings Medium — reveals API surface /actuator/shutdown Kills the JVM Critical /actuator/auditevents Security events High Step 1: Expose Only What You Need By default, only health is exposed over HTTP.

Continue reading »

Advanced Streams: flatMap, Collectors, Grouping, and Partitioning

flatMap in Depth The Collectors API covers perhaps 90% of real-world aggregation needs, but the moment you need something beyond grouping, partitioning, or joining, the custom Collector is there. Understanding flatMap and the full Collectors toolkit — including when to write your own — separates competent Java 8 developers from those who still reach for a for loop whenever a problem gets slightly unusual. flatMap is the most powerful transformation in the Streams API.

Continue reading »

Auditing: @CreatedDate, @LastModifiedBy, and Hibernate Envers

Why Auditing Matters Production systems must answer: “Who changed this? When? What did it look like before?” Without auditing infrastructure, you add created_at, updated_at, created_by, updated_by columns manually to every entity — dozens of lines of boilerplate repeated everywhere. Spring Data JPA auditing fills these fields automatically. Hibernate Envers goes further: it captures every revision of every entity in separate audit tables. Spring Data JPA Auditing Enable Auditing @Configuration @EnableJpaAuditing(auditorAwareRef = "auditorProvider") public class JpaAuditingConfig { @Bean public AuditorAware<String> auditorProvider() { return () -> Optional.

Continue reading »

AuthenticationManager, AuthenticationProvider, and UserDetailsService

The Authentication Delegation Chain Spring Security separates requesting authentication from performing authentication. A filter receives a username and password — but it does not check them itself. It passes the request to AuthenticationManager, which delegates to one or more AuthenticationProvider instances: flowchart LR F[Authentication Filter\nForm Login / Basic / JWT] -->|UsernamePasswordToken| AM[AuthenticationManager\nProviderManager] AM -->|try each provider| AP1[DaoAuthenticationProvider\nfor DB users] AM -->|try each provider| AP2[LdapAuthenticationProvider\nfor LDAP users] AM -->|try each provider| AP3[Custom Provider\nfor API key] AP1 -->|if supported| UDS[UserDetailsService\nloadUserByUsername] UDS --> DB[(Database)] AP1 -->|verify password| PE[PasswordEncoder] AP1 -->|success| Token[Authenticated Token] Token --> F This chain is the core of Spring Security’s extensibility — you can plug in any number of authentication mechanisms without touching the filter or the rest of the framework.

Continue reading »

Avro Serialization with Confluent Schema Registry

Why Avro and Schema Registry? JSON has no schema enforcement — a producer can change a field name and silently break every consumer. Avro + Schema Registry solves this: Avro gives you a compact binary format with a schema definition Schema Registry stores and versions schemas, enforces compatibility rules, and prevents breaking changes from reaching consumers flowchart LR subgraph Producer["Order Service"] E["OrderPlacedEvent"] -->|"KafkaAvroSerializer"| SR["Schema Registry\n(register/lookup schema)"] SR --> Bytes["[schema_id (4 bytes)] + [avro payload]"

Continue reading »