Engineering With Java: Digest #89
Events, Brokers, and Other Things That Keep You Up at Night
👋 Java Devs! Welcome to this week’s addition! I hope you’re all doing great.
This week, we cover essential insights on:
Build Reliable AI Agents with Java and LangChain4J
Led by Susanne Pieterse, Contributor to LangChain4J, International Speaker, and iSAQB Software Architect.
This hands-on workshop is designed for Java developers, backend engineers, architects, and technical leads who want to understand how production-ready AI systems are actually built within enterprise Java environments.
Use code JAVA50 for an exclusive 50% discount for being Engineering With Java subscriber.
How We Secured Our Spring Boot REST APIs in Production (Lessons Learned the Hard Way) : Securing a Spring Boot API goes far beyond adding JWT authentication. Production systems require layered security. Teams often discover vulnerabilities only after incidents, making security a continuous process rather than a one-time setup..
Use OAuth2/OIDC providers instead of building authentication yourself.
Enforce least-privilege authorization with roles and claims.
Protect sensitive Actuator and admin endpoints in production.
Add rate limiting, input validation, and security headers.
Store secrets outside source code and rotate them regularly.
Continuously scan dependencies and monitor security events.
Async Request Processing in Spring Boot with CompletableFuture : Use CompletableFuture to process long-running requests asynchronously, freeing servlet threads while waiting on downstream services and improving scalability for aggregation-style APIs.
Return
CompletableFuturefrom controllers for async request handling.Use a dedicated
ThreadPoolTaskExecutorinstead of the common pool.Parallelize independent service calls with
allOf()andthenCombine().Add timeouts (
orTimeout,completeOnTimeout) to prevent slow dependencies from blocking requests.Keep controllers thin; place async orchestration in the service layer.
Best suited for aggregating multiple downstream API calls into a single response.
Rethinking Java CRUDs With Event Sourcing and CQRS Patterns : CQRS (Command Query Responsibility Segregation) and Event Sourcing help microservices avoid shared databases and distributed transaction challenges. Instead of storing only current state, systems store a sequence of immutable events and build optimized read models from them.
Separate write (commands) and read (queries) models for scalability.
Store business events as an immutable history, not just current state.
Use event streams to rebuild state, audit changes, and support analytics.
Build denormalized read models optimized for query performance.
Expect eventual consistency and additional operational complexity.
Best suited for complex domains, not simple CRUD applications.
Introducing bx-jwt: Enterprise-Grade JSON Web Tokens for BoxLang : BX-JWT, a BoxLang module for creating, validating, signing, and managing JSON Web Tokens (JWTs) in enterprise applications. It provides built-in support for secure authentication workflows, token signing, validation, and integration with BoxLang applications.
Simplifies JWT creation, validation, and signing
Supports secure stateless authentication workflows
Centralizes token handling in a reusable module
Designed for enterprise-grade security and scalability
Reduces custom JWT implementation code and maintenance
Fits well for API authentication and service-to-service communication
Agentic AI Workflows for OpenJDK Development : Java is exploring agentic AI workflows inside OpenJDK development, where AI agents help with tasks like code analysis, testing, and engineering workflows across the JVM ecosystem.
OpenJDK is exploring AI agents for JVM development workflows
Focus on assisting testing, code analysis, and automation (not replacing developers)
Emphasis on human + AI collaboration in Java engineering
Part of broader push to make Java AI-ready for enterprise systems
Positions Java as an infrastructure layer for future agent-based applications
How to parse configuration files in a type-safe way : Focuses on how to parse configuration files in a type-safe way by mapping config data into structured models instead of relying on raw strings or manual parsing. It focuses on improving safety, maintainability, and developer experience by shifting configuration handling to compile-time checks.
Replace string-based configs with strongly typed models
Parse config files into structured objects instead of manual reads
Catch configuration errors at compile time instead of runtime
Reduce boilerplate parsing and casting logic
Improve maintainability and refactoring safety
Best suited for complex or hierarchical configuration setups
Zero-Downtime Deployments for Java Apps on Kubernetes : Spring Boot achieves zero-downtime deployments on Kubernetes by combining rolling updates with proper readiness checks and graceful shutdown to avoid dropping in-flight requests during pod replacement.
Rolling updates enable gradual pod replacement
Readiness probes control traffic flow
Graceful shutdown prevents request loss
Probes + load balancer ensure safe routing
Blue-green/canary improve rollout safety
Most issues come from timing misconfigurations
Why I Banned ThreadLocal from the Exeris Kernel (And What Replaced It) : Scoped Values are a safer replacement for ThreadLocal in modern Java, designed for virtual threads to pass immutable context without leaks, manual cleanup, or shared-state issues.
Scoped Values replace ThreadLocal for safer context propagation
Designed for virtual threads and structured concurrency
Avoids memory leaks and manual cleanup issues
Provides immutable, request-scoped context sharing
Better fit for modern high-concurrency Java applications
📢 Get actionable Java and Spring Boot insights every week, including practical code tips and real-world, use-case-based interview questions, to help you level up your backend skills—join 7300+ subscribers for hand-crafted, no-fluff content.
First 100 paid subscribers will get the annual membership at $50/year forever that is ~ $4/mo ( 89 already converted to paid, 11 remaining)
Testimonials
Java *is* Memory Efficient : Modern Java memory management intentionally trades higher RAM usage for lower CPU cost using moving garbage collectors. This makes allocation extremely fast and GC work less frequent. Performance today depends heavily on system-wide behavior (CPU, caches, allocation patterns), not isolated code paths or microbenchmarks.
Java GC trades RAM usage for CPU efficiency (intentional design)
Allocation is cheap (pointer bump), freeing is deferred via GC compaction
More heap ⇒ fewer GC cycles ⇒ lower overall CPU usage
“Memory vs CPU” must be evaluated together, not separately
Always rely on profiling real applications, not synthetic benchmarks
Top 10 Event-Driven Architecture Pitfalls by Victor Rentea : Talks about common production issues in Kafka/Spring Boot systems around async processing, ordering, backpressure, and reliability.
CompletableFuture queues → hidden memory pressure
No backpressure → OOM + pod crashes
Async consumers must throttle processing
Ordering breaks with batching + concurrency
Callbacks often return stale data
DB + event mismatch causes data loss bugs
Use outbox + CDC for reliable events
Consumers must be idempotent (duplicates expected)
Poison messages can break partitions
Event vs command design matters a lot
From Chaos to Cohesion: Building Modular Monoliths in the Real World : Talks about why production systems using Spring Boot + Kafka fail in real-world event-driven architectures, and how to design safer, more structured systems.
Monoliths decay due to missing structure, not because they are monoliths
Microservices introduce heavy operational + distributed system complexity
The real solution is modular monoliths with strong internal boundaries
Organize code by business domains (vertical slicing), not layers
Each module should expose a clear public API and hide internals
Most failures come from cross-boundary leaks and hidden coupling
Use tools like Spring Modulith / ArchUnit to enforce boundaries in CI
Gradual refactoring is safer than rewriting or splitting into services early
How to Externalize Events in Spring Modulith with Kafka : Talks about how Spring Modulith integrates internal events with external brokers (Kafka/RabbitMQ) using a clean modular monolith approach.
Domain events are the primary communication mechanism between modules
Internal events use Spring ApplicationEventPublisher + @ApplicationModuleListener
External events are enabled via @Externalized annotation
Same domain event can be consumed internally AND published to Kafka
No direct module-to-module dependencies, only event contracts
Java Interview Question - Find Minimum Version in Rotated Release History
Spring Boot Interview Question — Your API Went Viral Overnight
Java Interview Question - The Hidden Object Construction Bug in Java
Thats all for this week friends! Thanks for reading this far. If you liked it please share with your network.
Happy Coding 🚀
Suraj
Subscribe | Sponsor us | LinkedIn | Twitter








