Java 9 is here and at Simtlix we started using it! – Second Part
by Mariano Bonatti
Java 9 has arrived and it brought a set of new features and improvements that aim to help to the programmers in their business. Java 8 presented lambda expressions as one of its main features, and Java 9 has four features/improvements that stand out from the rest:
- Java Shell (jshell),
- Milling Project Coin which refers to small improvements over existing features,
- the Java Module System and
- support for HTTP 2 Clients.
At Simtlix, we were trying out the new features and we would like to share our experience. We divided it in two articles. The second part includes an overview of the HTTP 2 client support, JDK Module System, Process API improvement and more. Let’s begin…!
HTTP 2 Client
HTTP/2 is the newest version of the HTTP Protocol. Problems with the existing version’s (HTTP 1.1) are eliminated in this newer version. The improvements that HTTP/2 included focus on how data is framed and transported between server and client.
This is one of the most relevant features included in Java 9, supporting HTTP 2 will fix a lot of performance issues we had with the previous version but, this is exactly what is solved with this feature:
- HTTP 1.1 cannot have more than six connections open at the same time
- Every request sent to the server will contain additional data in the header that demands more bandwidth.
- Text is replaced by binary in HTTP 2.0
Java 9, provides better alternatives to the HttpURLConnection class which is hard to use and maintain. In this new version, separate classes were defined for the HTTP client, requests, and responses. The new API makes HTTP connections more easily maintained. It’s faster and allows for a more responsive application without the need for third-party libraries.
The new API handles HTTP connections through three classes.
- HttpClient handles the creation and sending of requests.
- HttpRequest is used to construct a request to be sent via the HttpClient.
- HttpResponse holds the response from the request that has been sent.
The following code snippet shows how to create an HttpClient, send a request to a specific URL and receive the response:
//Creates an HTTPClient object
HttpClient httpClient = HttpClient.newHttpClient();
//Build a HTTPRequest
HttpRequest httpRequest = HttpRequest.newBuilder().uri(new URI("https://www.simtlix.com/")).GET().build(); //Create a GET request for the given URI
Map<String,List<String>> headers = httpRequest.headers().map();
headers.forEach((k, v) -> System.out.println(k + "-" + v));
//Send the request.
HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandler.asString());
//Output the body of the response
System.out.println("Response: " + httpResponse.body());
The new APIs are delivered as incubator modules, which means that a non-final version of the API is released under jdk.incubator.http package. The API specifications may be finalized completely or removed entirely from the development kit in future releases. Expectation from developer community is that this will be achieved by the time JDK 10 is released and the incubator APIs, if successful, will be having final versions available under java.httpclient package.
In the java project that accompanies this article, we applied these features in the class com.simtlix.java9.experience.http2.HTTP2Java.java.
Java 9 Module System
Modular programming is a software design technique to separate the functionality into independent modules that work together to construct the executable application program. Every module performs just a specific aspect of a desired functionality.
Although a modular system will demand much more effort in the design tasks than a monolithic system, choosing a modular system will reduces the maintenance effort since every module tends to be small and specific, which makes it easier to understand.
Oracle finally decided to include the modularity feature in Java 9 after postponing the delivery of this feature in previous versions of the language. The Jigsaw project, included in Java 9, is meant to solve all these issues. The modules will consist of usual classes and a new module declaration file. This module descriptor explicitly defines what dependencies our module requires and what modules are exposed for outside usage. All packages that are not mentioned in the exports clause will be encapsulated in the module by default.
You can find more details in: http://openjdk.java.net/projects/jigsaw/quick-start
Process API Improvements
So far, there were not APIs for managing or controlling the operating system processes. If you wanted to get the PID, you needed to write around 20 lines of code.
Java 9 implemented new APIs for controlling and managing operating system processes. Even if it only offers a limited support for native operative system processes, for sure it will save us from writing so many lines of code.
The java.lang.Process class is improved to provide information about the specific process id. java.lang.ProcessHandle can be used for destroying processes and monitoring liveness of a specific process. The code snippet is an example on how to use this API to get information of an specific project:
ProcessHandle processHandle = ProcessHandle.current();
ProcessHandle.Info processInfo = processHandle.info();
System.out.println("PID: " + processHandle.pid());
System.out.println("User: " + processHandle.info().user());
System.out.println("Name: " + processInfo.command().get());
The risk is the same as we had in the previous versions, which is that the differences between operating systems could demand more abstract API and increase the design effort.
In the java project shared with this article, you will find several examples about Process in the following class: com.simtlix.java9.experience.process.JavaProcess. As you will see in these examples, Java 9 gives us a lot of possibilities for managing and controlling system processes.
In short, benchmarking is the practice of measuring the performance of a system and comparing it with others in the same conditions. Microbenchmarking is about small code fragments. Think about it a little bit, every programmer has had the necessity to investigate which part of his code takes more time by including the System.currentTimeMillis() before and after a piece of code and then calculating the elapsed time. There is nothing wrong with this procedure but the Java Microbenchmark Harness (JMH) included in Java 9 adds a basic suite of microbenchmarks to the JDK source code, which makes it easier for developers to run existing microbenchmarks and create new ones while avoiding adding extra processes in our code.
You can run JMH as a separate project independent from the actual project you are measuring or you can just store the measurement code in a separate directory. The harness will compile against the production class files and will execute the benchmark.
You can read more details of this feature in: http://openjdk.java.net/jeps/230
Factory Methods for Immutable List, Set, Map and Map.Entry:
Immutability is often presented as a key concept of functional programming in which an object cannot be modified once created. It has some benefits like thread-safe operations and they can be cached as they are not going to change. A simple example of the usage of immutable list that comes to my mind is passing an immutable list of objects to the view layer to prevent it from being modified.
In Java SE 8 and earlier versions, we can use Collections class utility methods like unmodifiableXXX to create Immutable Collection objects. For instance, if we want to create an Immutable List, then we can use Collections.unmodifiableList method. However these Collections.unmodifiableXXX methods are very tedious. To overcome those shortcomings, Oracle corp has added a couple of utility methods to List, Set and Map interfaces.
In Java 8, we needed to do something like:
List<String> list = new ArrayList<String>(Arrays.asList("first","second"));
List<String> unmodifiableList = Collections.unmodifiableList(list);
unmodifiableList.add("four"); //It won't work. It results in an UnsupportedOperationException
List and Set interfaces have “of()” methods to create an empty or non-empty Immutable List or Set object as shown below:
List immutableList = List.of();
List immutableList = List.of("first","second");
immutableList.add("third"); //it won't work. It results in an UnsupportedOperationException
Those who are aware of the features of Java 8, will find it familiar since it is the same approach used for LocalDate and LocalTime implemented in that version.
LocalDate.of(2017, Month.MARCH, 8);
Using less code as possible avoids introducing errors so, it is a very good news as well.
In the attached project, you can find different examples of immutable objects in class com.simtlix.java9.experience.immutable.ImmutableFactory.
Miscellaneous Java 9 Features
This is not all, Java 9 added more features and all of them are listed in the following link: http://openjdk.java.net/projects/jdk9/. In this web page you will find more information on what we talked about and also about these other features/enhancements:
- GC (Garbage Collector) Improvements
- Stack-Walking API
- Filter Incoming Serialization Data
- Deprecate the Applet API
- Indify String Concatenation
- Enhanced Method Handles
- Java Platform Logging API and Service
- Compact Strings
- Parser API for Nashorn
- Javadoc Search
- HTML5 Javadoc
Everytime we know that a new version of Java is close to being released, we are looking forward to see some features included and sometimes they are in the new version and sometimes they are not. In this case, I would like to give a special mention to a feature that we will need to keep waiting for. I am talking about providing a standardized lightweight JSON API. JSON has become the lingua franca for web services and it is time for Java SE to adopt some functionality for interacting with and utilizing JSON documents and data streams and taking advantage of library’s features. Well, it seems that Oracle has considered other features more important than this one.
This article attempted to give you a quick overview of the most relevant features included in Java 9. As you can see, there are a lot of good news, so are you ready to get started? You will find all code mentioned in this article and more in our github.
This article was written with the collaboration of Guillermo Ojeda, Leonardo Marzo, Heraldo Valenti, Facundo Rossi and Denis Reinoso.