The Ultimate Guide to Java 9
After some months of delays, Java 9 is coming ! Java 9 is attended for general availability On September, 2017. In that article, you’re going to discover the major new features of Java 9. Don’t hesitate to leave me some comments if I forgot some important things.
Main Features
- Java Platform Module System – JSR 376
- Process API Updates – JEP 102
- HTTP 2 Client – JEP 110
- JShell : The Java Shell – JEP 222
- Multi-Resolution Images API – JEP 251
- Stack-Walking API – JEP 259
- Platform Logging API and Service – JEP 264
- Reactive Streams – JEP 266
- Platform-Specific Desktop Features – JEP 272
- Deserialization Filter – JEP 290
- XML Catalogs – JEP 268
- Parser API for Nashorn – JEP 236
- Language Changes – JEP 213
- Extension to Existing APIs
- Some Low Level APIs
- Applet API deprecation – JEP 289
You can discover all the new features expected in Java 9 in video too :
Java Platform Module System – JSR 376
The Java Platform Module System (JPMS) is the biggest part of Java 9. Specific goals of the module system are :
- Reliable configuration
- Strong encapsulation
It will benefit application developers, library developers and implementors of the Java SE Platform. An awesome read to start with JPMS :
http://openjdk.java.net/projects/jigsaw/spec/sotms/
The JDK is now entirely modular. Great step forward ! Example of a module with dependencies (requires and exports) :
module com.foo.bar { requires org.baz.qux; exports com.foo.bar.alpha; exports com.foot.bar.beta; }
Process API Updates – JEP 102
Goal : Improve the API for controlling and managing OS processes
Motivation : The limitations of the current API often force developers to resort to native code.
The design of this API needs to accommodate possible deployment on smaller devices with different OS models. The new ProcessHandle class makes it more convenient to interact with processes and process trees. Get the PID of the current Process :
private static int getOwnProcessID() { return ProcessHandle.current().getPid(); }
List all processes on your OS :
ProcessHandle.allProcesses().forEach(h -> printInfo(h)); // ... public void printInfo(ProcessHandle pHandle){ System.out.println("PID : " + pHandle.info().getPid(); System.out.println("Path : " + pHandle.info().command().orElse("-"); // … }
The new ProcessBuilder class makes is very easy to build processes and pipelines. Call a ls command then pipe the results into a grep :
ProcessBuilder ls = new ProcessBuilder() .command("ls") .directory(Paths.get("/home/ssaurel/tmp").toFile()); ProcessBuilder grepPdf = new ProcessBuilder() .command("grep", "pdf") .redirectOutput(Redirect.INHERIT); List<Process> lsThenGrep = ProcessBuilder .startPipeline(asList(ls, grepPdf));
HTTP 2 Client – JEP 110
Define a new HTTP Client API implementing HTTP/2 and WebSocket, an can replace the legacy HttpURLConnection API that has numerous problems :
- Designed with multiple procotols in mind
- API target HTTP/1.1
- Too abstract
- Hard to use
- Works in blocking mode only
Create and handle a simple HTTP request :
HttpResponse response = HttpRequest .create(new URI("http://www.ssaurel.com")) .body(noBody()) .GET().send(); int responseCode = response.responseCode(); String responseBody = response.body(asString()); System.out.println(responseBody);
Make an asynchronous call with the new API :
HttpRequest req = HttpRequest .create(new URI("http://www.ssaurel.com")) .body(noBody()) .GET(); CompletableFuture<HttpResponse> aResp = req.sendAsync(); Thread.sleep(10); if (!aResp.isDone()) { aResp.cancel(true); System.out.println("Failed to reply in 10 seconds ..."); return; } HttpResponse response = aResp.get();
The Java Shell – JEP 222
Goal is to provide an interactive tool to evaluate declarations, statements, expressions of the Java language with and API letting other applications to leverage this functionality. With Java 9, the JDK will have its own Read-Eval-Print-Loop (REPL) tool !
Evaluate and print expressions :
-> 3 * (4 + 5) | Expression value is: 27 | assigned to temporary variable $1 of type int -> System.out.println($1); 27
Define some variables and list them :
-> String s = "Sylvain Saurel" | Added variable s of type String with initial value "Sylvain Saurel" -> /vars | int $1 = 27 | String s = "Sylvain Saurel"
You can even define classes :
-> class Pet {} | Added class Pet -> class Cat extends Pet {} | Added class Cat
Multi-Resolution Images API – JEP 251
Goal is to define a multi-resolution images API so that images with resolution variants can easily be manipulated and displayed by developers.
Basic operations on a multi-resolution image :
- Retrieve resolution-specific image variant based on a given DPI metric and set of image transformations
- Retrieve all the variants in the image
MultiResolutionImage interface with a BaseMultiResolutionImage implementation provided :
package java.awt.image; public interface MultiResolutionImage { Image getResolutionVariant(float destImageWidth, float destImageHeight); public List<Image> getResolutionVariants(); }
Stack-Walking API – JEP 259
Goal : Define an efficient standard API for stack walking that allows easy filtering of, and lazy access to, the information in stack traces
Motivation : Existing APIs require the VM to eagerly capture a snapshot of the entire stack and they return information representing the entire stack. It’s an heavy operation ! The Stack-Walking API wants to solve this problem.
Make a couple of calls and then walk the stack until we find the frame that belongs to a specific method :
public static void main(String[] args) { one(); } static void one() { two(); } static void two() { three(); } static void three() { String line = StackWalker.getInstance().walk(StackWalking::walk); System.out.println(line); } private static String walk(Stream<StackFrame> stackFrameStream) { return stackFrameStream .filter(frame -> frame.getMethodName().contains("one")) .findFirst() .map(frame -> "Line " + frame.getLineNumber()) .orElse("Unknown line"); }
Platform Logging API and Service – JEP 264
Define a minimal logging API which platform classes can use to log messages, together with a service interface for consumers of those messages.
The JDK classes now pipe messages through the new interface Logger (either directly or on a detour through sun.util.logging.PlatformLogger) – instances of which are provided by a single LoggerFinder.
Reactive Streams – JEP 266
JEP 266 aims to offer an interoperable Reactive Streams publish-subscribe framework, enhancements to the CompletableFuture API and various other improvements.
JDK will provide a minimal set of interfaces that capture the heart of asynchronous publication and subscription mechanism with Publisher, Subscriber and Subscription objects.
Platform-Specific Desktop Features – JEP 272
Define a new public API to access platform-specific desktop features such as interacting with a task bar or dock, or listening for system or application events. API based on the Desktop object.
Not all platforms will support all features. The call Taskbar::isSupported allows to check which are available.
Some of the available features :
- Login / Logout and screen lock handlers
- Request user attention
- Indicate task progress
- Action shortcuts
- etc …
Deserialization Filter – JEP 290
Allow incoming streams of object-serialization data to be filtered in order to improve both security and robustness. ObjectInputFilter that can be created :
interface ObjectInputFilter { Status checkInput(Class<?> clazz, long size, long nRefs, long depth, long streamBytes); enum Status { UNDECIDED, ALLOWED, REJECTED; } }
XML Catalogs – JEP 268
Develop a standard XML Catalog API that supports the OASIS XML Catalogs standard, v1.1 :
https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html
The API will define catalog and catalog-resolver abstractions which can be used with the JAXP processors that accept resolvers.
Parser API for Nashorn – JEP 236
Define a supported API for Nashorn’s ECMAScript abstract syntax tree.
- Provide interface classes to represent Nashorn syntax-tree nodes
- Provide a factory to create a configured parser instance, with configuration done by passing Nashorn command-line options via an API
- Provide a visitor-pattern API to visit AST nodes.
- Provide sample/test programs to use the API.
Language Changes – JEP 213
Small language changes continue with Java 9 inside the JEP 213 : Milling Project Coin. At the program :
- Private Interface Default Methods
- Diamond Operator for Anonymous Classes
<T> Box<T> createBox(T content) { // we have to put the `T` here return new Box<T>(content) { }; }
- Try-With-Resources on Effectively Final Variables
void doSomethingWith(Connection connection) throws Exception { try(connection) { connection.doSomething(); } }
- SafeVarargs on Private Methods
- No More Deprecation Warnings for Imports
Extension to Existing APIs
A lot of existing APIs are a little bit refined. To name a few :
- Optional, Stream, Collectors got a few new methods
- New stream returning methods are added with LocalDate::datesUntil, Scanner::tokens, …
- Many types of the DateTime API introduced in Java 8 can now transform themselves to epoch seconds, e.g. Chronology , LocalDate , and OffsetTime
- etc …
Some Low Level APIs
Java 9 brings a number of very interesting APIs that operate much closer to the JVM. Amongst them :
- Variable Handles aka VarHandles – JEP 193
- Enhanced Method Handles – JEP 274
- Dynamic Linking of Language-Defined Object Models – JEP 276
- Spin-Wait Hints – JEP 285
Applet API deprecation – JEP 289
Deprecate the Applet API, which is rapidly becoming irrelevant as web-browser vendors remove support for Java browser plug-ins. Guide developers to alternative technologies such as Java Web Start or installable applications. Applet API is just marked as deprecated but not for removal. So, Applet API will still be in JDK 10 at least …
Excited about Java 9 ? Which feature is the most expected for you ? Tell us in comments !
Leave a Reply
You must be logged in to post a comment.