Java 11 is out, and it’s an LTS (Long Term Support) release. Time to upgrade from Java 8?

Why Java 11 Matters

It’s the first LTS release since Java 8 (2014). Oracle will support it until 2026.

If you’re on Java 8, this is your upgrade path.

New Features

1. Local-Variable Syntax for Lambda

// Java 10
var list = List.of("a", "b", "c");

// Java 11 - var in lambda
list.forEach((var item) -> System.out.println(item));

// Why? For annotations
list.forEach((@Nonnull var item) -> System.out.println(item));

2. HTTP Client (Standard)

Finally, a modern HTTP client:

// Old way - HttpURLConnection (painful)
URL url = new URL("https://api.example.com/users");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// ... lots of boilerplate

// Java 11 - HttpClient
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/users"))
    .build();

HttpResponse<String> response = client.send(request, 
    HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

Async support:

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

3. String Methods

// isBlank()
"   ".isBlank();  // true

// lines()
"Line 1\nLine 2\nLine 3".lines()
    .forEach(System.out::println);

// strip() - Unicode-aware
" text ".strip();  // "text"

// repeat()
"ha".repeat(3);  // "hahaha"

4. Files Methods

// Read file to string
String content = Files.readString(Path.of("file.txt"));

// Write string to file
Files.writeString(Path.of("file.txt"), "content");

5. Collection.toArray()

// Before
List<String> list = List.of("a", "b", "c");
String[] array = list.toArray(new String[0]);

// Java 11
String[] array = list.toArray(String[]::new);

6. Not Predicate

// Before
list.stream()
    .filter(s -> !s.isBlank())
    .collect(Collectors.toList());

// Java 11
list.stream()
    .filter(Predicate.not(String::isBlank))
    .collect(Collectors.toList());

Removed Features

1. Java EE Modules

Removed:

  • JAXB
  • JAX-WS
  • CORBA
  • JavaFX

If you use these, add them as dependencies:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

2. Nashorn JavaScript Engine

Deprecated. Use GraalVM instead.

Performance Improvements

1. G1 GC Improvements

G1 is now the default GC. Better performance than Parallel GC.

2. Low-Latency GC

Two new experimental GCs:

  • ZGC: Sub-10ms pause times
  • Epsilon: No-op GC for testing

3. Faster Startup

Class-Data Sharing improvements. Faster startup times.

Our Migration Experience

We migrated 5 services from Java 8 to Java 11.

Issues We Hit

1. JAXB Missing

java.lang.ClassNotFoundException: javax.xml.bind.JAXBException

Fix: Add JAXB dependency.

2. Illegal Reflective Access

WARNING: Illegal reflective access by ...

Some libraries use reflection on internal APIs. They still work but show warnings.

Fix: Wait for library updates or use --illegal-access=permit.

3. Maven Compiler Plugin

Update to 3.8.0+:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>11</release>
    </configuration>
</plugin>

Migration Steps

  1. Update Maven/Gradle
  2. Update dependencies (especially Spring, Hibernate)
  3. Add JAXB if needed
  4. Run tests
  5. Fix warnings
  6. Deploy to staging
  7. Monitor performance
  8. Deploy to production

Took 1 week per service.

Performance Results

Before (Java 8):

  • Startup: 15 seconds
  • Memory: 512MB
  • Throughput: 1000 req/s

After (Java 11):

  • Startup: 12 seconds (20% faster)
  • Memory: 480MB (6% less)
  • Throughput: 1100 req/s (10% more)

Not huge, but noticeable.

Should You Upgrade?

Yes, if:

  • You’re on Java 8
  • You want LTS support
  • You want modern features
  • You have time to test

Wait, if:

  • You’re on Java 9/10 (wait for Java 12)
  • Your dependencies aren’t ready
  • You’re on a tight deadline

Our Plan

  • New services: Java 11
  • Existing services: Migrate gradually over 6 months
  • Legacy services: Stay on Java 8 for now

Java Release Cadence

New model:

  • LTS releases: Every 3 years (Java 11, 17, 21…)
  • Feature releases: Every 6 months (Java 12, 13, 14…)

Stick with LTS for production.

The Verdict

Java 11 is a solid upgrade. Modern features, better performance, LTS support.

If you’re on Java 8, plan your migration. The ecosystem is ready.

Questions? Ask away!