-
Notifications
You must be signed in to change notification settings - Fork 0
Java 17
Release Date: September 14, 2021 | Type: LTS | Status: ✅ Active — widely adopted (Spring Boot 3+ requires this as minimum)
Java 17 is the LTS that modern frameworks standardized on — Spring Boot 3.x and Spring Framework 6.x require Java 17+ as a minimum. It finalizes sealed classes, strongly enforces JDK internal encapsulation (no more escape hatches by default), and previews pattern matching for switch.
flowchart TD
J11["Java 11 LTS (2018)"] -->|3 years| J17["Java 17 LTS (2021)"]
J17 --> A["Sealed Classes STANDARD"]
J17 --> B["Pattern Matching switch Preview"]
J17 --> C["Strong encapsulation ENFORCED"]
J17 --> D["Spring Boot 3 / Jakarta EE 10 baseline"]
public sealed interface PaymentResult
permits Success, Declined, Pending {}
public record Success(String transactionId) implements PaymentResult {}
public record Declined(String reason) implements PaymentResult {}
public record Pending(String referenceId) implements PaymentResult {}
// Exhaustive handling — the compiler enforces every case is covered
static String describe(PaymentResult result) {
if (result instanceof Success s) return "Paid: " + s.transactionId();
if (result instanceof Declined d) return "Declined: " + d.reason();
if (result instanceof Pending p) return "Pending: " + p.referenceId();
throw new IllegalStateException(); // unreachable, but compiler doesn't know that yet in 17
}classDiagram
class PaymentResult {
<<sealed interface>>
}
class Success {
<<record>>
String transactionId
}
class Declined {
<<record>>
String reason
}
class Pending {
<<record>>
String referenceId
}
PaymentResult <|.. Success
PaymentResult <|.. Declined
PaymentResult <|.. Pending
This is a textbook algebraic data type, and it's exactly the pattern that becomes fully exhaustive with switch pattern matching in Java 21.
// Preview only in 17 — requires --enable-preview
static String formatShape(Object shape) {
return switch (shape) {
case Circle c -> "Circle with radius " + c.radius();
case Square s -> "Square with side " + s.side();
case null -> "No shape provided";
default -> "Unknown shape";
};
}What: --illegal-access is removed. Reflective access to internal JDK APIs (sun.*, jdk.internal.*) now fails hard unless explicitly opened.
# This used to just print a warning on Java 8/11. On Java 17, it throws.
java -jar legacy-app.jar
# Exception: InaccessibleObjectException: Unable to make field
# private final char[] java.lang.String.value accessible
# Fix: explicitly open the module (only if you genuinely need it)
java --add-opens java.base/java.lang=ALL-UNNAMED -jar legacy-app.jarflowchart LR
A[Java 9: modules introduced] --> B[Java 9-15: --illegal-access=permit default]
B --> C[Java 16: default flips to deny]
C --> D[Java 17: --illegal-access removed entirely]
D --> E["Reflection into JDK internals\nrequires explicit --add-opens"]
Why it matters: This breaks old libraries doing deep reflection (some ORM/mocking frameworks, old Lombok versions, legacy serialization libraries). Test thoroughly before upgrading production from 8/11 straight to 17.
// New unified interface for all RNG algorithms
RandomGenerator rng = RandomGeneratorFactory.of("L64X128MixRandom").create();
System.out.println(rng.nextInt(100));
// Jumpable generators — great for parallel simulations needing independent streams
var factory = RandomGeneratorFactory.of("Xoshiro256PlusPlus");
RandomGenerator r1 = factory.create();
RandomGenerator r2 = r1; // conceptually — use .jumps() for real parallel streams
factory.jumpableGenerator(); // returns an implementation supporting jump()
// Stream of independent generators for parallel processing
RandomGenerator.of("L64X128MixRandom").ints(1000).forEach(System.out::println);Early preview of what becomes the standard way to call native code and manage off-heap memory — replacing JNI. Fully covered in the Java 22 guide where it's standardized.
// Incubator API — syntax evolved significantly by the time it's standardized in Java 22- Applet API deprecated for removal (browsers dropped Java applet support years earlier anyway)
- Security Manager deprecated for removal (fully removed in Java 24)
-
-XX:+AlwaysActAsServerClassMachineand other legacy flags cleaned up
✅ Treat Java 17 as your new minimum baseline for greenfield projects — it's what Spring Boot 3, Quarkus, and Micronaut target
✅ Model closed result/state hierarchies with sealed + record combinations
✅ Run a full regression pass with --illegal-access removed before upgrading production from Java 8/11
❌ Don't add blanket --add-opens/--add-exports flags without knowing exactly which library needs them — audit first
| Change | Impact |
|---|---|
--illegal-access removed |
Reflective libraries may throw InaccessibleObjectException
|
| Security Manager deprecated | If you use System.setSecurityManager(), plan to remove it |
| Applet API deprecated | No impact for server-side apps |
| Sealed classes / records available | Opportunity to refactor DTOs and closed hierarchies |
| macOS/AArch64 (Apple Silicon) support | Native M1/M2/M3 builds available |
flowchart TD
A["Java 11 App"] --> B{"Uses deep reflection\ninto JDK internals?"}
B -->|Yes| C["Identify --add-opens needed\nor find alternative library version"]
B -->|No| D["Likely a smooth upgrade"]
C --> E["Test on Java 17"]
D --> E
E --> F["Upgrade Spring Boot to 3.x\nif using Spring"]
F --> G["Deploy on Java 17"]