Java / Java 21 Interview Questions
What are the key steps and pitfalls when migrating an application to Java 21?
Migrating from Java 8/11/17 to Java 21 requires attention to removed APIs, module system access restrictions, and the opportunity to adopt new features incrementally.
// Step 1: Compile with Java 21 — fix deprecation warnings
// javac --release 21 -Xlint:deprecation src/**/*.java
// Step 2: Run with Java 21 — look for startup warnings
// WARNING: Illegal reflective access ... (module access)
// Fix: add --add-opens flags until migrated properly
// Step 3: Scan for removed APIs
// - SecurityManager: remove System.setSecurityManager() calls
// - Thread.stop() / suspend() / resume(): use interrupt/flags
// - sun.* / com.sun.* internal APIs: use public replacements
// - Applet: remove entirely
// Step 4: Update dependencies
// Many libraries had Java 9+ compatibility issues that are now fixed
// Spring Boot 3.x requires Java 17+ and supports Java 21 natively
// Hibernate 6.x is Jakarta EE and Java 17+ compatible
// Jackson 2.15+ has module-info.java
// Step 5: Enable virtual threads (Spring Boot 3.2)
// spring.threads.virtual.enabled=true
// Then: remove thread pool sizing, increase load test concurrency
// Step 6: Replace synchronized with ReentrantLock in hot paths
// Use: jcmd Thread.print to see pinned virtual threads
// Step 7: Adopt new language features incrementally
// Records -> DTO classes first
// Pattern matching instanceof -> existing instanceof+cast
// Text blocks -> multi-line strings (SQL, JSON, HTML)
// Switch expressions -> switch statements returning a value
// Step 8: Update GC selection
// G1 is still default and excellent
// Consider ZGC if latency percentiles matter and heap > 4 GB | Pitfall | Symptom | Fix |
|---|---|---|
| sun.misc.Unsafe usage | InaccessibleObjectException | Use VarHandle or Cleaner API |
| Reflective access to internals | InaccessibleObjectException | --add-opens or update library |
| Split packages across modules | Module resolution failure | Merge JARs or use classpath |
| Thread.stop() removal | NoSuchMethodError | Cooperative interrupt flag |
| synchronized + virtual threads | Carrier thread pinning | Replace with ReentrantLock |
| High ThreadLocal usage | Memory pressure at high VT count | Switch to ScopedValue |
More Related questions...