The Future of Java

Finally, let’s turn to the future of the language, platform, and developer ecosystem. Increasingly, these have become interwoven, so it makes sense to treat them as a whole as we look into our crystal ball.

Java 9

The next major release of the platform is Java 9, scheduled for September 2016. As releases go, it’s expected to be a fairly major one, as it contains a number of large features (although how their impact will compare to the arrival of lambdas in Java 8 remains to be seen).

Modules

If lambda expressions were the "headline" feature for Java 8, in Java 9 it is anticipated to be modules. Up until now, the largest grouping construct for Java code was a package, but the release of Java 9 will see a new concept—the module. Modules are collections of code that are larger than packages, and are no longer delivered as JAR files (which are really just .zip files). Instead, modules have a new file format that has been designed to be more efficient.

Modules also add a major new feature to the language, which is the ability to enforce access control across modules. That is, modules are able to fully specify their public API, and prevent access to packages that are only for internal use.

The ability for modules to allow internals access only to trusted client code will have major repercussions for Java applications. This is most apparent in the removal of access to a class called sun.misc.Unsafe. This class is an internal class (as can be seen by the fact that it lives in a sun package, rather than a java or javax package) and should not be used directly by applications or libraries.

Unsafe contains functionality that enables low-level access to platform features that are normally inaccessible to ordinary Java code. It also contains code to directly access processor features, compare-and-swap hardware for example. These capabilities are not part of the Java standard, yet are extremely useful. The JDK class libraries make heavy use of Unsafe, especially in places such as the concurrency classes.

However, as the name itself suggests, there are some very powerful and potentially damaging methods contained within Unsafe, and it has never been standardized. So, from Java 9 onwards, this class will no longer be available to classes that do not form part of the JDK.

Unfortunately, these features are very widely used by many popular Java frameworks, for performance or flexibility reasons. So even if your Java application doesn’t directly call code from Unsafe, the chances are that somewhere in your stack, you use a library that does rely on Unsafe.

The platform needs to evolve, and the removal of access to internals is a huge step forward for writing maintainable and composable code. However, it’s no exaggeration to say that the removal of Unsafe has the potential to break every non-trivial Java application currently running.

To most developers, this seems like a backwards incompatible change. From Oracle’s point of view, however, the sun packages are internal code, and are not guaranteed to remain unchanged. In this view, libraries and frameworks that rely on implementation details rather than public APIs do so at their own risk. This leads to a tension between the needs of the core platform, and the libraries that users rely on.

To resolve this conflict, and given the scope and impact of these changes, the transition must be handled with care and clear communication. Oracle is consulting the wider community and at time of writing a reasonable consensus on how to proceed seems to be emerging.

Change Default Garbage Collector

The current default garbage collector is the parallel collector. The parallel collector is extremely efficient, designed for high-throughput operation and uses very small amounts of CPU time to collect memory. However, the collector must pause the JVM to run a garbage collection cycle (sometimes called a "Stop The World" (STW) operation). These pauses typically last for up to a few hundred milliseconds on heaps of 8 GB or less.

In Java 9, Oracle proposes to change the default collector to the new Garbage First (G1) collector. This uses a more modern GC algorithm that can do some of its work without pausing fully. The aim is to let users set "pause goals" that the JVM will try to adhere to. However, G1 has some drawbacks: it uses much more CPU time overall to collect memory, and still has the possibility of a significant pause. By default, G1 will try to pause for no more than 200ms, unless necessary, which isn’t necessarily a huge improvement over parallel.

G1 is also lacking in real-world testing. Despite being available since Java 7, relatively few Java shops have adopted it, so the true impact of changing the default collector is unknown. Applications that run without an explicit choice of collector will be affected by a change of default. Limited research has been done into the percentage of applications that would potentially be affected, but indications are that it could over 50%.

HTTP/2

The HTTP/2 standard is a new version of the Web’s primary protocol, HTTP. The previous version, HTTP/1.1, dates from 1999 and has encountered significant problems (such as head-of-line blocking) as the Web has grown. The new standard was created by the Internet Engineering Task Force (IETF) HTTP Working Group, which comprised engineers from major Web companies and browser manufacturers.

Note

The basic semantics (including methods) of HTTP have not fundamentally changed in the new standard, but the transport mechanisms are new.

The group summarized some of the key properties of HTTP/2 as follows:

  • Same HTTP APIs

  • Cheaper requests

  • Network- and server-friendliness

  • Cache pushing

  • Being able to change your mind

  • More encryption

The new standard is pragmatic about the way the Web has come to be used; as a general purpose application protocol rather than purely for document retrieval and hypertext transfer. So, for example, in HTTP/2 responses can be interleaved, connections are not closed unless a browser actively navigates away, and HTTP headers are now represented in binary to avoid penalizing small requests and responses (which is the majority of traffic).

In the Java world, HTTP/2 is an opportunity to revisit Java’s ancient HTTP API. This dates to Java 1.0 and is designed around a relatively protocol-agnostic framework based on the URL class. This predates the massive dominance of the Web over all other Internet protocols. This API has not kept up with the reality of how the Web is used today.

The new Java API for HTTP/2 is a completely clean sheet, and abandons any pretense of protocol independence. Instead, it’s an API purely for HTTP, but is independent of HTTP version. It will provide support for the new framing and connection handling parts of HTTP/2, as well as HTTP/1.1 support for the transitional period.

In the current version of the new API (which may, of course, change before the release of Java 9), a simple HTTP request looks like this:

    HttpResponse resp = HttpRequest
        .create(new URI("http://www.oreilly.com"))
	.body(noBody())
        .GET().send();
    int responseCode = resp.responseCode();
    String body = resp.body(asString());

    System.out.println(body);

This style for the API feels much more modern than the existing legacy HTTP API, and reflects the trend in API design towards fluent (or builder) patterns.

JShell

In many other languages, an interactive environment for exploratory development is provided via a Read-Evaluate-Print-Loop (REPL) tool. In some cases (notably Clojure and other Lisps), the REPL is where developers spend most of their coding time. This is also seen in languages such as Scala or JRuby.

Java previously had the Beanshell scripting language, but it never achieved full standardization, and the project has essentially been abandoned. Java 8 introduced the Nashorn implementation of Javascript on top of the JVM, and included the jjs REPL. Due to Nashorn’s tight integration with Java, this could be a useful environment for playing with Java in an interactive manner. However, it still wasn’t Java.

As part of the development of Java 9, Project Kulla was started, to look at producing a Java REPL that would provide as close an experience to "full Java" as possible. The project had some strict goals, such as not to introduce new non-Java syntax. Instead, it disables some features of the language that are not useful for interactive development in order to provide a less awkward working environment.

In JShell, statements and expressions are evaluated immediately in the context of an execution state. This means that they do not have to be packaged into classes, and methods can also be free-standing. JShell uses "snippets" of code to provide this top-level execution environment.

In the environment, expressions can be freely entered and JShell will automatically create temporary variables to hold the resulting values and keep them in scope for later use:

-> 3 * (4 + 7)
|  Expression value is: 33
|    assigned to temporary variable $1 of type int

-> System.out.println($1);
33


New classes can easily be defined:

-> class Pet {}
|  Added class Pet

-> class Dog extends Pet {}
|  Added class Dog

JShell also has commands, which all start with / to access REPL features. For example:

-> /help
Type a Java language expression, statement, or declaration.
Or type one of the following commands:

/l  or /list [all]        -- list the source you have typed

[additional output]

/?  or /help              -- this help message
       /!                 -- re-run last snippet
       /<n>               -- re-run n-th snippet
       /-<n>              -- re-run n-th previous snippet

Supported shortcuts include:
<tab>       -- show possible completions for the current text

Just like REPL environments in other languages, JShell lets you use the REPL to demonstrate Java language features very simply and quickly. In turn, this makes JShell a great learning tool, similar in experience to Scala’s REPL.

Further Out

Oracle does not release firm plans more than one release ahead, relying instead on a roadmap of features for future releases. As a result, the features and possible developments discussed in this section cannot be definitively tied to any specific release.

Project Panama

Oracle has already announced Project Panama, a new effort to define a Foreign Function Interface (FFI) for the JVM. The name evokes the Panama canal, an infrastructure project designed to link the Pacific to the Atlantic. Similarly, Project Panama is about bridging between the managed world of Java and the unmanaged world of C and other runtimes.

If non-Java programmers find some library useful and easy to access, it should be similarly accessible to Java programmers.

John Rose

The ultimate goal is to be able to directly bind native functions (such as the contents of shared libraries or operating-system calls) to Java methods. This has always been possible using Java’s Java Native Interface (JNI), but the interface is inconvenient and rather limited. This has led to a significant barrier to entry for mixing native code into a Java project.

Project Panama has a difficult task ahead of it, not least because Java’s culture has always been about safe programming, as a departure from the pitfalls found in languages such as C and C++. To evolve Java’s access to native code without sacrificing that safety is a major undertaking, but would be of huge benefit to millions of Java developers worldwide.

Project Valhalla

Another area of major work beyond Java 9 is Project Valhalla. This is an experimental project focused on new features for the Java language. Currently, the features that are under discussion are enhanced generics and value types.

Enhanced generics are a proposed feature that would let Java developers write code that uses primitive types as type parameters for collections, such as List<int>. This is problematic in the current language and JVM because there is no type in Java that is a supertype of both Object and int. That is, Java’s type system does not have a single root.

Currently, the prototyping uses an approach called "any" type variables, to mean that the type variable can range over both reference types and primitives. However, this design contains some subtleties that have to be approached carefully. For example, List<int> and List<String> could not have a supertype more specific than Object in Java’s existing type system.

One possibility is that List<Integer> and List<String> could continue to be represented at runtime by List.class, but with List<int> being represented by a different runtime type and class file.

The Internet of Things

Software is not a static field, and new areas of interest continue to emerge. One of the most eagerly anticipated and hyped is the so-called Internet of Things (IoT). This is the idea that devices with very limited compute capability compared to a laptop or phone will nevertheless become Internet-enabled and able to provide useful and valuable data streams to their owners.

Java has inspired a lot of hatred, but it’s been incredibly influential in building modern enterprise software, along with the tools we use to develop, maintain, and deploy that software.

Mike Loukides

Over the years, a lot of the criticism (both justified and not) that has been flung in Java’s direction has abated, replaced by something closer to grudging, involuntary respect.

It is therefore not surprising that, given Java’s influence in the enterprise, application teams working towards IoT have developed stacks that leverage Java’s strengths and robustness for use with a world of devices possessed of limited capability.

It’s still unclear whether the much-discussed revolution of IoT will actually take place. While the raw technology is now in place, major issues such as security, bandwidth, and data handling remain. For that matter, the industry has yet to decide whether a device’s "owner" and beneficiary of the device’s data value is the purchaser or the supplier.

In any event, if the IoT does become mainstream, then Java is extremely well-placed to become a major part of the architecture of the systems that will be needed to deliver it.

Conclusion

The road from Java’s first public alpha of 1.0 to today has been long and full of technical advances and interesting adventures. Along the way, Java has flourished, and has become one of the world’s most important and widely-used programming environments.

How long will Java continue to be as ubiquitous as it is today? No-one knows, but the ecosystem today is flourishing and the immediate course that has been set seems fair. Which means, of course, that it’s time to raise a toast and wish Java a very Happy Birthday.

Article image: (source: O'Reilly).