Java is widely used and heavily relied on, to put it mildly. It is a major part of our software infrastructure. Despite having a weighty obligation to stability, the Java platform has managed to remain responsive to changing circumstances. The creativity of the people who use Java is part of the reason. Java features an official process for incorporating changes into the platform while achieving a high degree of stability.
Let’s get an overview of how the Java platform is enhanced. We’ll also look at some of the most prominent new features on the horizon.
JCP: Java Community Process
Even a longtime Java developer may not have a good understanding of how the platform is developed and maintained. Before we jump into the upcoming big projects, let’s get a sense of how the Java process works. The main takeaway here is that it really is an open process. If you have a desire to contribute, it’s doable: Talk to a contributor, join a group, submit a proposal, fix a bug.
At the root of Java development is the Java Community Process (JCP). This is a kind of self-aware foundational document that defines how to shepherd modifications into the platform, and also allows for modifying the process itself. The latest version of the JCP is 2.11, which was adopted in 2019.
The JCP formalizes how new features and changes to Java (i.e., technical specifications) are proposed, reviewed, and approved, including defining various roles that people can inhabit. These roles help to offer a place for the Java user community to participate in the governance of the platform.
JSR: Java Specification Request
For proposing new features and changes, the JCP allows for the creation (“initiation”) of Java Specification Requests (JSR). This is done via a standardized form. To get to the form, you need to register for a free JCP account.
Unsurprisingly, the form is a substantial, imposing thing. After all, the Java SE spec currently weighs in at 852 pages—and that’s just the standard edition!
Nevertheless, this is where the process begins. From here many changes, modest or otherwise, find their way into the Java technologies we use every day.
When a JSR comes in, it enters the JSR review process. This is a multistage process wherein the changes proposed in the JSR are gradually considered more seriously, modified, anguished over, and ultimately adopted or shunted off into dormancy.
JEP: JDK Enhancement Proposal
The process of generating a promising JSR is non-trivial. There are a few avenues through which ideas are channeled into becoming JSRs. The most prominent of these is the JEP. Many of the most ambitious changes to Java (like lambdas) originate as JEPs. Here is the list of the non-defunct JEPs. It’s an interesting document to browse through during an idle moment.
The process of delivering a new JDK into the world is itself a JEP. It’s also a major community event; coverage starts here.
When an effort is broad enough, it is considered a JDK Project. This is an umbrella for a broad range of artifacts from docs to code, often including one or more JEPs. Projects involve one or more working groups. Groups are dedicated to various areas of the Java platform. A project usually has several active people in the author role.
Major JDK Projects in progress
Project Amber is a collection of smaller projects. It’s intended to help usher these projects through the process of becoming actual features. So it’s a kind of incubator.
Amber includes two active projects, nine delivered, three on hold, and one that has been withdrawn.
- 420: Pattern Matching for switch
- 409: Sealed Classes
- 406: Pattern Matching for switch
- 395: Records
- 394: Pattern Matching for instanceof
- 378: Text Blocks
- 361: Switch Expressions
- 323: Local-Variable Syntax for Lambda Parameters
- 286: Local-Variable Type Inference
You can see that many of the more interesting features in recent JDKs—like records and text blocks—were part of Amber. Watch Project Amber for upcoming syntactic enhancements like pattern matching for switch.
Project Loom is probably the most ambitious and far-reaching of the current projects. The goal of Loom is to rearchitect the entire threading model for the JVM. As I said, ambitious.
Loom is still very much in progress, with details that are morphing. The basic idea remains the same: replace the traditional Java thread model, which has been basically a wrapper around OS processes, with something more lightweight. What that means in practice is creating an abstraction layer between OS kernel threading and JVM threading. Within that new layer, Loom could provide various optimizations that only the JVM can negotiate.
Think about more intelligent ways to share resources across threads. Applying an optimization called “tail-call elimination” is on the roadmap for possible inclusion.
Loom is also looking at ways to more cleanly and explicitly control code flow, via continuations. This is where Java programmers will see syntax changes.
Project Panama is focused on improving the JVM’s ability to interact with non-Java APIs. This may remind you of JNI (Java Native Interface), which already allows for the ability to call out to “native” code like compiled C or C++. Project Panama aims to improve upon JNI’s approach (particularly the developer experience) to such an extent that JNI is superseded. Goals include eliminating boilerplate, providing a ByteBuffer alternative, and introducing some foundational components that can be used.
In general, Panama is targeted at making what’s known as FFI (foreign function interface) calls more idiomatic.
A kind of spin-off from Panama is the Vector API. This is the effort to improve Java’s ability to interact with the CPU’s vector support. (One imagines the opportunity for improvement here was discovered while mucking around in OS internals.)
Project Valhalla’s mission statement is to “augment the Java object model with value objects and user-defined primitives, combining the abstractions of object-oriented programming with the performance characteristics of simple primitives.”
In a sense, Valhalla is attempting to unify Java’s types, making it possible to address primitives and classes in a generic way. In fact, you will be able to use generics on primitives.
A value class is one that allows for references, like a normal class, but makes all member variables final. Put another way, it is “shallow immutable.” A value class will be declared with the
value modifier in front of the
class keyword. In contrast to the new user-defined primitive types, value classes can be null.
User-defined primitives can’t be null—this is what makes them primitive-like. Moreover, they can have no references. Essentially, they are a custom grouping of primitives. The
primitive class modifier will be introduced to declare them.
So we are seeing a kind of bridging between primitive and custom types. As part of this effort, Java programs will be able to apply generics to both classes and primitives, along with reaping their performance benefits.