Of every breaking change in the Spring Boot 2 β 3 era, the removal of WebSecurityConfigurerAdapter generated the most confused stack traces I’ve debugged β because security configuration is the one place where “it compiles and runs” tells you almost nothing about whether it still protects anything. This guide migrates Spring Security 5 configurations to the 6.x component model (Spring Boot 3.x), covers what tightens further in Spring Security 7 (Spring Boot 4), and flags the places where a mechanical conversion quietly changes your authorization behaviour.
Tag Archives: Java
RestTemplate to RestClient Migration Guide: Method Mapping, Error Handling, and the exchange() Trap
Spring Boot 4 finally forced the issue: RestTemplate, in maintenance mode since Spring 5, is out of the recommended path, and codebases full of getForObject() and exchange() calls need a plan. The good news is that RestClient (introduced in Spring 6.1 / Boot 3.2) was designed as the synchronous successor, so this migration is mostly mechanical β if you know the method-by-method mapping and the three places where behaviour quietly differs. This guide gives you both.
Hibernate 5 to 6 to 7 Migration Guide: The Breaking Changes and the Silent Ones
I have now taken three codebases through the Hibernate 5 β 6 β 7 path, and the same pattern repeated each time: the compile errors are the easy part, and the silent behaviour changes β query result types, ID generation, fetch semantics β are what reach production. This guide walks the migration in two deliberate hops (5β6, then 6β7), with the exact errors you will see at each stage and how to fix them. Do not attempt 5β7 in one jump; the diagnostics assume you pass through 6.
Continue reading Hibernate 5 to 6 to 7 Migration Guide: The Breaking Changes and the Silent Ones
Zuul to Spring Cloud Gateway Migration: Routes, Filters, and the Blocking-Call Traps
The first time I ported a Zuul gateway to Spring Cloud Gateway, the routes took an afternoon β and the filters took two weeks. That ratio surprises every team that attempts this migration, because the route configuration looks superficially similar while the filter model is a different universe: Zuul 1 is a blocking servlet filter chain, Spring Cloud Gateway runs on Netty with Project Reactor, and a single hidden blocking call in a ported filter can stall your entire gateway. This guide covers the route conversion, the filter-by-filter port, and the blocking-call traps, in that order.
Spring Cloud Netflix to Modern Alternatives: The Complete Migration Guide (2026)
In 2020 I published a dozen tutorials on this site covering Eureka, Hystrix, Zuul, Ribbon, and Feign β the Spring Cloud Netflix stack. They were accurate then. Today, most of that stack is dead: Netflix put Hystrix into maintenance mode back in 2018, Zuul 1 and Ribbon followed, and the Spring team removed them from the Spring Cloud release train entirely. If you are still running any of these libraries on Spring Boot 2.x, this guide maps every Netflix component to its modern replacement and shows you the actual migration steps β including the parts that break.
Continue reading Spring Cloud Netflix to Modern Alternatives: The Complete Migration Guide (2026)
java.util.Date and Calendar to java.time: The Complete Migration Guide (Java 8β21)
Every experienced Java developer has a date-related war story. Mine came from a batch financial-reconciliation job that silently skipped three months of records because Calendar.MONTH uses zero-based indexing β January is 0, not 1 β and the off-by-one was invisible in unit tests that only ran against the current month. The bug surfaced in a quarterly audit, not in CI. That afternoon I started migrating our entire codebase to java.time, and I have not looked back since.
The java.time package (JSR-310, shipped in Java 8) is not merely a cleaner calendar API β it is a complete redesign of how Java represents time. Every type is immutable and thread-safe, month numbers start at 1, year offsets are gone, and the API forces you to be explicit about whether a value carries a timezone. This guide covers every migration scenario you will encounter when moving a real codebase from java.util.Date, java.util.Calendar, java.sql.Date, and SimpleDateFormat to their modern equivalents. All code has been tested on Java 21.0.3 (Eclipse Temurin) and is fully backward-compatible to Java 8.
The guide is structured so you can jump to any section independently. If you only need to migrate SQL types for a Hibernate project, jump to Section 6. If you are fixing Jackson serialisation in a REST API, jump to Section 10. The pitfalls section at the end contains the five mistakes I see most often in code reviews β read it before you consider the migration done.
Continue reading java.util.Date and Calendar to java.time: The Complete Migration Guide (Java 8β21)JUnit 6
JUnit 6 represents the next evolution in Java testing, building on the solid foundation of JUnit 5 while introducing modern features, improved API design, and enhanced developer experience. Whether you’re upgrading from JUnit 5 or starting fresh, this comprehensive guide covers everything you need to know about JUnit 6βfrom core concepts to advanced patterns.
Why JUnit 6?
JUnit 6 continues the modular architecture introduced in JUnit 5, with refinements focused on reducing cognitive load, improving discoverability, and providing better integration with modern Java features like records, sealed classes, and virtual threads. The framework emphasizes backward compatibility while offering clear upgrade paths for existing projects.
Getting Started with JUnit 6
Before diving into advanced topics, get acquainted with the fundamentals of JUnit 6.
- Getting Started with JUnit 6: Installation, Setup & First Test β Set up your development environment and write your first JUnit 6 test
- Writing Your First Clean Test in JUnit 6 (Best Practices) β Learn the essential building blocks of every test
- JUnit 6 with Maven and Gradle: Complete Setup Guide β Configure your build tool for JUnit 6
- Refactoring Legacy Tests to JUnit 6 (Migration Playbook) β Upgrade your existing JUnit 4/5 projects to JUnit 6
Core Testing Patterns
Master the essential patterns that form the foundation of professional test suites.
- JUnit 6 Test Lifecycle Explained: @BeforeEach, @AfterEach, @BeforeAll, @AfterAll β Control test initialization and teardown
- JUnit 6 Assertions: All Methods Explained with Real Examples β Master every assertion method
- JUnit 6 Assumptions and Conditional Test Execution Guide β Skip or enable tests based on conditions
- JUnit 6 Parameterized Tests: All Sources Explained with Examples β Run the same test logic with multiple inputs
- JUnit 6 Dynamic Tests: @TestFactory for Runtime-Generated Tests β Generate test cases at runtime
- JUnit 6 Nested Tests: Organizing Complex Test Hierarchies β Structure tests hierarchically for better organization
- JUnit 6 Test Naming Conventions: @DisplayName and Best Practices β Make test names human-readable in reports
Mocking and Test Doubles
Integrate popular mocking frameworks with JUnit 6 for effective unit testing in isolation.
- JUnit 6 with Mockito: Mocking, Spying, and Best Practices β Use Mockito mocks seamlessly in tests
- JUnit 6 vs Mockito: Roles, Differences, and Integration β Understand the relationship between the two frameworks
Extensions and Customization
Extend JUnit 6 with custom extensions for specialized testing needs.
- JUnit 6 Extensions Model: Build Custom Extensions Step-by-Step β Build reusable test extensions
- Advanced Extensions in JUnit 6: Creating Custom Testing Frameworks β Deep dive into extension capabilities
- JUnit 6 Internals: How the Test Engine Works β Understand the platform internals
Integration Testing
Combine JUnit 6 with Spring and other frameworks for comprehensive integration tests.
- JUnit 6 with Spring Boot: Unit, Slice, and Integration Testing β Test Spring Boot applications end-to-end
- Database Testing in JUnit 6: H2 vs Real DB vs Containers β Manage databases for integration tests
- JUnit 6 with Testcontainers: Real Database Integration Testing β Spin up real databases in tests
- Testing REST APIs with JUnit 6: MockMvc vs WebTestClient β Test HTTP endpoints effectively
- Testing Microservices with JUnit 6: Integration, Contract & E2E β Test distributed systems
Performance and Best Practices
Optimize your tests for speed and maintainability.
- Parallel Test Execution in JUnit 6: Configuration and Pitfalls β Run tests in parallel for faster feedback
- Test Data Management Strategies in JUnit 6 Projects β Manage test data efficiently
- Writing Maintainable Tests in JUnit 6 (Clean Code Principles) β Follow conventions for professional test code
- Why Your JUnit Tests Are Slow (Performance Optimization Guide) β Diagnose and fix slow test suites
- Tags and Test Suites in JUnit 6: Organizing Large Test Bases β Filter and group tests strategically
Troubleshooting and Quality
Learn what to watch out for and how to solve common problems.
- Common JUnit Testing Mistakes and How to Avoid Them β Identify and eliminate bad practices
- Debugging JUnit 6 Tests: Fix Failures Like a Pro β Debug failing tests effectively
- How to Fix Flaky Tests in JUnit 6 (Root Causes + Solutions) β Eliminate non-deterministic test failures
- Mutation Testing with PIT and JUnit 6 (Improve Test Quality) β Measure the real effectiveness of your tests
Advanced Topics
Deep dives into specialized scenarios and cutting-edge patterns.
- Property-Based Testing in JUnit 6 with jqwik (Complete Guide) β Go beyond example-based tests
- Running JUnit 6 Tests in CI/CD Pipelines (GitHub Actions, Jenkins) β Automate your test runs
- Code Coverage with JaCoCo and JUnit 6: Complete Setup β Measure and enforce coverage thresholds
- Build Your Own JUnit 6 Test Engine (Advanced Guide) β Extend the platform at the deepest level
- JUnit 6 vs JUnit 5: Key Differences, Features, and Migration Guide β Side-by-side comparison for migrators
- JUnit 6 vs TestNG: Feature Comparison and When to Use What β Choose the right framework for your team
AI Prompts for JUnit 6
Use AI tools to accelerate your JUnit 6 testing workflow.
- 10 AI Prompts to Generate JUnit 6 Tests for New Projects
- 10 AI Prompts to Optimise and Update Existing JUnit 6 Tests
- 10 AI Prompts to Debug and Fix JUnit 6 Test Failures
Quick Reference
Key Annotations: @Test, @DisplayName, @BeforeEach, @AfterEach, @BeforeAll, @AfterAll, @ParameterizedTest, @RepeatedTest, @Nested, @Disabled, @EnabledOnJava, @EnabledOnOs
Common Assertions: assertEquals, assertNotEquals, assertTrue, assertFalse, assertNull, assertNotNull, assertSame, assertArrayEquals, assertIterableEquals, assertThrows, assertDoesNotThrow, assertAll
Extension Points: BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback, TestInstancePostProcessor, ParameterResolver, TestTemplateInvocationContextProvider
Next Steps
JUnit 6 provides a comprehensive, modular foundation for testing Java applications of any size. Whether you’re writing unit tests for a small utility, integration tests for a microservice, or full test suites for enterprise systems, JUnit 6’s flexible extension model and rich feature set help you write clear, maintainable tests that improve code quality and accelerate development.
Start with the fundamentals, master the core patterns, and progressively adopt advanced techniques as your testing needs grow. The investment in learning JUnit 6 thoroughly pays dividends in every project you build.