“Java is dead.”
When Oracle completed its $7.4 billion acquisition of Sun Microsystems in 2010, that phrase echoed through developer communities everywhere. JDK licensing worries, a drawn-out patent war with Google, an update cadence so slow it felt geological. There was no shortage of reasons to be anxious.
Fifteen years later, Java is not only alive — it’s stronger than ever. So what on earth happened in between?
Why Oracle Wanted Java
When the acquisition closed in January 2010, many onlookers scratched their heads. “Oracle is a database company. Why buy a hardware vendor?”
Because the target was never the hardware. It was the platform.
Java wasn’t merely a programming language. It was the JVM (Java Virtual Machine) — a runtime installed on billions of devices worldwide, powering a huge slice of the world’s enterprise servers. Oracle’s flagship products, Oracle DB and the WebLogic middleware, were already deeply entangled with the Java ecosystem. Owning Java meant controlling the water supply of enterprise computing.
“Oracle didn’t buy a language. It bought the world’s largest enterprise platform.”
Almost immediately after closing the deal, Oracle sued Google, alleging that Android had used Java APIs without a license. The case wound through the courts for a decade, ending in 2021 when the U.S. Supreme Court ruled in Google’s favor.
Fun fact
Oracle’s damages claim was roughly $8.8 billion — a figure that speaks volumes about just how much money Android had made for Google.
Then came the licensing controversy. Starting in 2018, Oracle tightened its commercial licensing terms: businesses using Oracle JDK for production workloads had to pay. “Oracle is killing Java,” critics roared. Companies scrambled toward free alternatives — OpenJDK, Amazon Corretto, Eclipse Temurin (Adoptium). The climate was tense. And into that tension stepped two new languages.
The Rise of Kotlin and Scala: JVM’s Rescuers
In the years immediately after the Oracle acquisition, Java experienced a painful stagnation. Three years between Java 7 (2011) and Java 8 (2014). Another three years before Java 9 (2017). Updates were slow, and the language was famously verbose.
// Java's infamous boilerplate
public class User {
private final String name;
private final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
@Override public boolean equals(Object o) { /* ... dozens of lines ... */ }
@Override public int hashCode() { /* ... */ }
@Override public String toString() { /* ... */ }
}
A simple data class required all of this. Developers were exhausted. Scala and Kotlin stepped into that exhaustion.
Scala: Raising the Functional Flag
Scala (short for “Scalable Language”) was designed by Professor Martin Odersky to run on the JVM while embracing functional programming and a powerful static type system.
Scala’s breakout moment came via Apache Spark. Introduced in 2014, Spark transformed big-data processing, and Spark itself was written in Scala. Suddenly, anyone doing serious data engineering needed to know Scala.
// Scala's elegance: a data class in one line
case class User(name: String, age: Int)
// Functional data pipelines, concisely expressed
val activeUserNames = users
.filter(_.age >= 18)
.map(_.name)
.sorted
Kotlin: A Full Rewrite of Java’s Pain Points
Kotlin was created by JetBrains, the studio behind IntelliJ IDEA — a team with a uniquely deep understanding of developer productivity. Their promise: 100% Java interoperability, with all of Java’s rough edges filed down.
The real turning point came in 2017 when Google declared Kotlin an official language for Android. The entire Android developer community began migrating, and Kotlin was suddenly everywhere.
// Kotlin: the same data class, one line
data class User(val name: String, val age: Int)
// Null safety, extension functions, coroutines included
val activeUserNames = users
.filter { it.age >= 18 }
.map { it.name }
.sorted()
Some predicted Kotlin would fully replace Java. That didn’t happen — instead, Kotlin broadened the JVM ecosystem rather than cannibalizing it.
While Java stood still, Kotlin and Scala became the JVM’s innovators. Oracle felt the pressure.
Oracle Strikes Back: A New Java Every Six Months
In 2018, Oracle announced a course correction. Starting with Java 10, they adopted a six-month release cadence (Fast-track). The language that had kept developers waiting for years would now ship every spring and autumn.
The pace of change was remarkable.
| Version | Release | Key Features |
|---|---|---|
| Java 10 | 2018.03 | var local variable type inference |
| Java 11 (LTS) | 2018.09 | New HTTP client, lambda improvements |
| Java 14 | 2020.03 | Record (preview) |
| Java 16 | 2021.03 | Record finalized, Pattern Matching |
| Java 17 (LTS) | 2021.09 | Sealed Classes, long-term stability |
| Java 21 (LTS) | 2023.09 | Virtual Threads — production-ready |
Java absorbed var from Kotlin’s influence. Pattern Matching and Sealed Classes answered Scala’s type-system advantages. Record was Java’s direct reply to data class and case class.
Project Loom: The Virtual Thread Revolution
Then came the knockout punch. One of Java’s chronic weaknesses was the cost of threads. Each OS thread consumes hundreds of kilobytes of memory, making it impractical to create thousands of them directly. The workaround — reactive programming (Reactive Programming) — worked but imposed enormous cognitive complexity.
// Pre-Java 21: reactive-style code (WebFlux)
Mono.fromCallable(() -> fetchUser(id))
.flatMap(user -> Mono.fromCallable(() -> fetchOrders(user)))
.map(orders -> process(orders))
.subscribe();
// Java 21+: write it like synchronous code, get reactive-level throughput
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
var user = executor.submit(() -> fetchUser(id)).get();
var orders = executor.submit(() -> fetchOrders(user)).get();
process(orders);
}
What virtual threads actually change
Virtual threads are scheduled by the JVM, not the OS. You can spawn millions of them concurrently. Existing blocking code works as-is — no reactive libraries, no callback chains — yet throughput rivals full reactive stacks.
High performance without the complexity of asynchronous programming. This became Java’s most powerful competitive advantage in the 2020s.
2026: Coexistence, Not Competition
The JVM ecosystem in 2026 is no longer a battle for supremacy. It’s a peaceful coexistence, with each language firmly established in its own domain.
Java: The Enterprise Backbone
The combination of Spring Boot 3 and virtual threads has become the de facto standard for large-scale enterprise systems. Decades of accumulated business logic, a mature library ecosystem, and proven reliability make Java’s territory extremely hard to displace.
Kotlin: From Mobile to Multiplatform
Android is already Kotlin’s home turf. But Kotlin has bigger ambitions. KMP (Kotlin Multiplatform) aims to cover iOS, web, desktop, and server from a single codebase. The Ktor backend framework continues to expand its reach in modern server-side development.
Scala: The Heart of Big Data and AI Pipelines
Apache Spark, Apache Flink — Scala dominates here. For the large-scale data pipelines that underpin AI infrastructure, Scala remains indispensable.
| Language | Core Domain | 2026 Keywords |
|---|---|---|
| Java | Large enterprise, finance, public sector | Spring Boot 3, Virtual Threads, GraalVM |
| Kotlin | Android, modern backend, cross-platform | KMP, Ktor, Compose Multiplatform |
| Scala | Big data, AI infrastructure, quant finance | Spark, Flink, ZIO |
The Road Ahead: Challenges and Evolution
Stability doesn’t mean stagnation. The JVM ecosystem still faces real pressure.
GraalVM: Solving the Cold Start Problem
Serverless and container environments expose JVM’s weak spots: slow startup (Cold Start) and high memory footprint. GraalVM’s AOT (Ahead-of-Time) compilation compiles Java applications into native binaries, achieving millisecond startup times and significantly reduced memory usage. Frameworks like Quarkus and Micronaut are leaning into GraalVM to build cloud-native Java, and adoption is accelerating.
The Go and Rust Challenge
In cloud infrastructure and the Kubernetes ecosystem, Go has already displaced JVM languages in many areas. Kubernetes, Docker, and Terraform are all written in Go — not coincidentally. Rust is growing fast in systems programming and high-performance tooling.
Keep this in perspective
Go and Rust dominate at the infrastructure and platform layer. For the application layer — where complex business logic lives — the JVM ecosystem’s library depth and tooling maturity remain overwhelming advantages.
WebAssembly: The Long-Game Wild Card
WebAssembly (Wasm) erases language boundaries: compile any language to Wasm and run it in the browser or on the server. If Wasm matures into a genuine universal runtime, it challenges the JVM’s “Write Once, Run Anywhere” philosophy at its core. We’re still in early days, but this is a trend worth watching over the coming decade.
Conclusion: Java Doesn’t Fall — It Evolves
Decades of accumulated enterprise business logic and library assets don’t get replaced overnight. More importantly, the JVM ecosystem has consistently chosen to absorb change rather than resist it.
AI infrastructure pipelines run on Scala. Mobile and cross-platform apps run on Kotlin. The beating heart of enterprise computing runs on Java. These three languages compete at the margins while collectively growing the ecosystem they share.
“Java is dead,” they said in 2010. In 2026, Java has never been healthier.