When Kafka Needs to Be Synchronous Kafka is designed for asynchronous event streaming. But some flows genuinely need a response: a payment validation service that must confirm before the order proceeds, or a pricing engine that must return the current price before checkout completes. ReplyingKafkaTemplate gives you a blocking send-and-receive call over Kafka without leaving the Kafka ecosystem. How Request-Reply Works sequenceDiagram participant Requester as "Order Service\n(ReplyingKafkaTemplate)" participant Broker participant Replier as "
Continue reading »Java
223 posts in this section
Retryable vs Non-Retryable Exceptions: Custom Exception Classification
Transient vs Permanent Failures Not every exception is worth retrying. Retrying a NullPointerException or a schema validation error wastes time and delays other records. Retrying a database timeout or a downstream HTTP 503 is exactly right — the error is temporary and will likely resolve. flowchart TD Ex["Exception in listener"] Q{"Transient?\n(DB timeout, HTTP 503,\nnetwork blip)"} Q -->|Yes| Retry["Retry with BackOff"] Q -->|No| Skip["Call recoverer immediately\n(no retries wasted)"] Retry -->|"still failing after\nmax retries"
Continue reading »Role-Based Access Control: Roles, Authorities, and Hierarchies
Roles vs. Authorities: The Distinction That Matters Spring Security uses one interface for both roles and authorities: GrantedAuthority. Both are just strings. The difference is convention. Authority: a fine-grained permission string — user:read, report:export, order:cancel Role: a coarse-grained label that groups authorities — ROLE_ADMIN, ROLE_MANAGER, ROLE_USER The ROLE_ prefix is the only mechanical difference. When you call hasRole("ADMIN"), Spring Security prepends ROLE_ automatically and checks for ROLE_ADMIN. When you call hasAuthority("ROLE_ADMIN") you must include the prefix yourself.
Continue reading »Scheduling Batch Jobs: @Scheduled, Quartz, and Clustered Scheduling
Introduction A batch job that only runs manually is barely useful. Production jobs run on a schedule — nightly, hourly, after a file arrives. Spring Boot provides three scheduling options: Option Persistence Clustered Use when @Scheduled No No Simple cron on a single node Quartz Scheduler Yes (DB) Yes HA scheduling, persistent triggers External scheduler (Kubernetes CronJob, Airflow) Varies Yes Complex pipelines, dependency management @Scheduled — Simple Cron Trigger The simplest approach: annotate a method with @Scheduled and run the job from it.
Continue reading »Scoped Values (JEP 446): Thread-Safe Context Without ThreadLocal
Preview Feature — Requires --enable-preview at compile and runtime. The ThreadLocal Problem at Scale ThreadLocal has been the standard way to pass context (request ID, user session, database transaction) implicitly through a call stack without threading it through every method signature. It works well with a few hundred platform threads. With virtual threads, it breaks down. Problem 1 — Memory overhead with inheritance When you create a child thread with InheritableThreadLocal, Java copies the thread-local map from parent to child:
Continue reading »Sealed Classes (JEP 409): Controlled, Exhaustive Class Hierarchies
Finalized in Java 17 (JEP 409). This is the headline language feature of the Java 17 LTS release. Previous previews: Java 15 (JEP 360) and Java 16 (JEP 397). The Problem: Open Hierarchies Are Hard to Reason About In Java, any class can be extended by default. This openness is flexible but has costs. Consider a Shape interface used in a drawing application: // Java 11 — anyone can implement Shape public interface Shape { double area(); } At runtime, a Shape instance could be a Circle, a Rectangle, a Triangle, or anything else in the classpath.
Continue reading »Second-Level Cache and Query Cache with Hibernate
Cache Layers in Hibernate Hibernate has two cache levels: Level Scope Lifetime Shared? First-level cache One Session (one transaction) Transaction No — per session Second-level cache SessionFactory Application lifetime Yes — across sessions The first-level cache (Article 24) prevents repeated reads within one transaction. The second-level cache prevents repeated reads across transactions — once an entity is loaded, it stays in the shared cache until evicted. When to Use the Second-Level Cache Good candidates:
Continue reading »Security Headers: CSP, HSTS, Clickjacking Protection
Why Security Headers Matter Security headers tell browsers how to behave when handling your content. They stop entire classes of attacks — XSS, clickjacking, protocol downgrade, information leakage — with a few lines of configuration. They cost nothing at runtime and are one of the highest-value-per-effort security improvements available. Spring Security’s Default Headers Spring Security adds a set of secure headers by default. You do not need any explicit configuration to get them:
Continue reading »Security: TLS 1.3, ChaCha20-Poly1305, and Curve25519 (JEP 329, 332, 324)
Security Improvements Across Java 9–11 JEP Release Feature JEP 287 Java 9 SHA-3 hash algorithms JEP 273 Java 9 DRBG-based SecureRandom JEP 288 Java 9 Disable SHA-1 certificates JEP 324 Java 11 Key Agreement with Curve25519 and Curve448 JEP 329 Java 11 ChaCha20 and Poly1305 cryptographic algorithms JEP 332 Java 11 Transport Layer Security (TLS) 1.3 JEP 181 Java 11 Nest-Based Access Control TLS 1.3 (JEP 332) TLS 1.3 is the current version of the Transport Layer Security protocol, finalised in RFC 8446 (August 2018).
Continue reading »SecurityContext and Authentication Object
The SecurityContext Is the Source of Truth Every security decision in Spring Security ultimately comes down to one question: “What Authentication object is stored in the SecurityContext?” Does the user have ROLE_ADMIN? → check Authentication.getAuthorities() What is the user’s ID? → cast Authentication.getPrincipal() to UserDetails Is the user logged in at all? → check Authentication.isAuthenticated() Understanding the SecurityContext and Authentication is not optional — it underlies everything. The Object Hierarchy classDiagram class SecurityContextHolder { -strategy: SecurityContextHolderStrategy +getContext() SecurityContext +setContext(SecurityContext context) +clearContext() +getContextHolderStrategy() SecurityContextHolderStrategy } class SecurityContext { <> +getAuthentication() Authentication +setAuthentication(Authentication authentication) } class Authentication { <> +getPrincipal() Object +getCredentials() Object +getAuthorities() Collection~GrantedAuthority~ +getDetails() Object +isAuthenticated() boolean +getName() String } class UsernamePasswordAuthenticationToken { +UsernamePasswordAuthenticationToken(principal, credentials) +UsernamePasswordAuthenticationToken(principal, credentials, authorities) } class GrantedAuthority { <> +getAuthority() String } class SimpleGrantedAuthority { -role: String +getAuthority() String } SecurityContextHolder --> SecurityContext SecurityContext --> Authentication Authentication <|.
Continue reading »