Contact Info
London Office :
Denizli Office :
Pamukkale Üniversitesi Teknoloji Geliştirme Merkezi B Blok Oda:Z17, 20070 Denizli
info@cloudnesil.com
+88 (0) 101 0000 000
Certified Kubernetes Administrator Certified Developer on Apache Cassandra

Cloud Nesil

WHAT IS NEW IN JAVA 9

 Java 9 is a major release. It may seem to be a maintenance release that pushes forward project Jigsaw Project (Module System). But along with the new module system and a number of internal changes associated with it Java 9 brings also a number of cool new stuff to the developer’s toolbox.
 
1. New Features in Java Language
2. New Features in Java Compiler
3. New Features in Java Libraries
4. New Features in Java Tools
5. New Features in Java Runtime (JVM)
 
1. NEW FEATURES IN JAVA LANGUAGE
1. Private methods in Interfaces
2. Java 9 Module System
3. Enhanced @Deprecated annotation
4. Diamond Operator for Anonymous Inner Class
5. Try With Resources Improvement
6. Multi-release JARs
 
1.1. PRIVATE METHODS IN INTERFACES
‣ In Java 8, we can provide method implementation in Interfaces using default and static methods. However we cannot create private methods in interfaces.
‣ To avoid redundant code and more re-usability, Java 9 supports private methods in Java SE 9 Interfaces.
‣ These private methods are like other class private methods only, there is no difference between them.
‣ In Java 9 and later versions, an interface can have six kinds of things:
– Constant variables
– Abstract methods
– Default methods
– Static methods
– Private methods
– Private static methods
 
 
1.1. PRIVATE METHODS IN INTERFACES
        
        public interface DBLogging {
            String MONGO_DB_NAME = “ABC_Mongo_Datastore”;
            String NEO4J_DB_NAME = “ABC_Neo4J_Datastore”;
            String CASSANDRA_DB_NAME = “ABC_Cassandra_Datastore”;
            default void logInfo(String message) {
                log(message, “INFO”);
            }
            default void logWarn(String message) {
                log(message, “WARN”);
            }
            default void logError(String message) {
                log(message, “ERROR”);
            }
            private void log(String message, String msgPrefix) {
            // …
        }
        
    
 
1.1. PRIVATE METHODS IN INTERFACES
‣ Rules to define private methods in an Interface?
– We should use private modifier to define these methods.
– No private and abstract modifiers together, it will give compiler error. It is not a new rule. We cannot use the combination of private and abstract modifiers, because both have different meanings
– Private methods must contain body.
– No lesser accessibility than private modifier. These interface private methods are useful or accessible only within that interface only. We cannot access or inherit private methods from an interface to another interface or class
 
 
1.2. JAVA 9 MODULE SYSTEM
‣ One of the big changes or java 9 feature is the Module System.
‣ Before Java SE 9 versions, we are using monolithic jars to develop java-based applications. This architecture has lot of limitations and drawbacks. To avoid all these shortcomings, Java SE 9 is coming with Module System
‣ JDK 9 is coming with almost 100 modules. We can use JDK Modules and also we can create our own modules.
 
1.2. JAVA 9 MODULE SYSTEM
‣ Java SE 8 or earlier systems have following problems in developing or delivering Java Based application:
– As JDK is too big, it is a bit tough to scale down to small devices.
– JAR files like rt.jar etc are too big to use in small devices and applications.
– As JDK is too big, our applications or devices are not able to support
better performance.
– There is no strong encapsulation in the current Java System because
“public” access modifier is too open. Everyone can access it.
– As JDK, JRE is too big, it is hard to test and maintain applications.
– Its a bit tough to support less coupling between components
 
1.2. JAVA 9 MODULE SYSTEM
‣ Java SE 9 module system is going to provide the following benefits:
 
– As Java SE 9 is going to divide JDK, JRE, JARs etc, into smaller modules, we can use whatever modules we want. So it is very easy to scale down the java application to small devices.
– Ease of testing and maintainability.
– Supports better performance.
– As public is not just public, it supports very strong encapsulation. We cannot access internal non-critical APIs anymore.
– Modules can hide unwanted and internal details very safely, we can get better security.
– Application is too small because we can use only what ever modules we want.
– Its easy to support less coupling between components
– Its easy to support single responsibility principle (SRP).
 
‣ The main goal of Java 9 module system is to support Modular Programming in Java.
 
1.2. JAVA 9 MODULE SYSTEM
 
‣ We know what a JDK software contains. After installing JDK 8 software, we can see a couple of directories like bin, jre, lib etc in java home folder. Oracle has changed this folder structure a bit differently.
‣ JDK 9 does NOT contain jre directory in JDK 9 anymore.
‣ Instead of jre folder, JDK 9 software contains a new folder “ jmods ”. It contains a set of Java 9 modules.
‣ In JDK 9, No rt.jar and No tools.jar
‣ All JDK modules starts with “jdk.* ”
‣ All Java SE specifications modules starts with “ java.* ”
‣ Java 9 module system has a “ java.base ” module. It’s known as base module. It’s an independent module and does NOT dependent on any other modules. By default, all other modules dependent on this module. We can think of it like java.lang package.
 
1.2. JAVA 9 MODULE SYSTEM
 
1.2. JAVA 9 MODULE SYSTEM
‣ We have already developed many java applications using Java 8 or earlier version of java. We know how a Java 8 or earlier applications looks like and what it contains.
‣ In brief, A Java 8 applications in a diagram as shown below:
 
1.2. JAVA 9 MODULE SYSTEM
‣ Java 9 applications does not have much difference with this. It just introduced a new component called “Module”, which is used to group a set of related packages into a group. And one more new component that module descriptor (“module-info.java”).
‣ Rest of the application is same as earlier versions of applications
as shown below:
 
 
1.2. JAVA 9 MODULE SYSTEM
‣ Modular JAR files contain an additional module descriptor named
module-info.java
‣ In this module descriptor, dependencies on other modules are
expressed through ‘requires’ statements.
‣ Additionally, `exports` statements control which packages are
accessible to other modules.
 
        
        module com.bkn.demo {
            exports com.bkn.demo; requires java.sql; requires java.logging;
        }
        
    
 
1.2. JAVA 9 MODULE SYSTEM
‣ The exports keyword indicates that these packages are available to other modules. This means that public classes are, by default, only public within the module unless it is specified within the module info declaration. (module-info.java). All non- exported packages are encapsulated in the module by default
‣ The requires keyword indicates that this module depends on another module.
‣ The uses keyword indicates that this module uses a service.
‣ When starting a modular application, the JVM verifies whether all modules can be resolved based on the `requires` statements
 
 
1.2. JAVA 9 MODULE SYSTEM
‣ List modules: In order to see which modules are available within Java, we can enter the following command:
java –list-modules
 
A list is shown with the available modules. Below is an extract from the list:
 
java.activation@9
java.base@9
java.compiler@9
 
From the list, we can see that the modules are split into four categories: the ones starting with java (standard Java modules), the ones starting with javafx (JavaFX modules), the ones starting with jdk (JDK-specific modules) and the ones starting with oracle (Oracle-specific modules)
 
‣ Describe Module: Module properties are located in a module-info.java file. In order to see the description of the module defined in this file, the following command can be used:
java –describe-module java.sql
This will output the following:
java.sql@9
exports java.sql
exports javax.sql
requires java.logging transitive
uses java.sql.Drive
 
1.2. JAVA 9 MODULE SYSTEM
‣ Compilation: With the following command, we compile the application. The -d option specifies the destination directory for the compiled classes.
 
javac -d out module-dir/com/bkn/demo/Demo.java module-dir/module-info.java
 
‣ Execution: To execute the compiled classes, we need to set the module-path. This option sets the directories where the modules can be found
It is necessary to set the module and the package and the class where
the main class is located
java –module-path out —module com.bkn.demo.Demo
 
 
1.2. JAVA 9 MODULE SYSTEM
‣ Create a JAR file: We can create the JAR file with the command below.
The file option specifies the location and name of the JAR file. The main-class option specifies the entry point of the application. The C option specifies the location of the classes to include in the JAR file.
 
jar -c -f target/demo-module.jar -C out .
 
‣ Create your own JRE: The directory structure of the JDK has changed a bit. A directory, jmods, is added. This directory contains a jmod file for each module. A jmod file is like a JAR file, but for modules
 
The size of the whole jre is ~179 MB on my laptop. We can create our own JRE with only the modules we are using in our application with the following command:
 
jlink –module-path ../jmods –add-modules java.base –output path/jre
 
The size of newly created runtime is only 38 MB.
 
‣Let’s look into jdk directories & try to create, compile and execute a module…
 
1.3. ENHANCED @DEPRECATED ANNOTATION
‣ In Java SE 8 and earlier versions, @Deprecated annotation is just a Marker interface without any methods. It is used to mark a Java API that is a class, field, method, interface, constructor, enum etc.
‣ In Java SE 9, @Deprecated annotation provides more information about deprecated API.
‣ Two methods added to this Deprecated interface: forRemoval and
since to serve this information.
‣ A method forRemoval() returning a boolean. If true, it means that this API element is earmarked for removal in a future release. If false, the API element is deprecated, but there is currently no intention to remove it in a future release
‣ A method named since() returning String. This string should contain the release or version number at which this API became deprecated
 
 
1.4. DIAMOND OPERATOR FOR ANONYMOUS INNER CLASS
‣ Java SE 8 has a limitation in the use of Diamond operator with Anonymous Inner Class. Now diamond operator can be used with anonymous inner class.
 
1.5. TRY WITH RESOURCES IMPROVEMENT
‣ Try-with-resources was a great feature introduced in Java 7 to automatically manage resources using an AutoCloseable interface. This helps a lot, of course, as we have no need to close the resources explicitly in our code
‣ Java 7:
 
        
        Connection dbCon = DriverManager.getConnection(…);
        try (ResultSet resultSet = dbCon.createStatement().executeQuery(“…”)) {
            // …
        } catch (SQLException e) {
            //…
        } finally {
            if (null != dbCon)
                dbCon.close();
        }
        
    
 
‣ Java 9:
 
        
        Connection dbCon = DriverManager.getConnection(…);
        try (dbCon; ResultSet resultSet = dbCon.createStatement().executeQuery(…)) {
            // …
        } catch (SQLException e) {
            // …
        }
        
    
 
 
1.6. MULTI-RELEASE JARS
‣ When a new version of Java comes out, it takes years for all users of your library to switch to this new version
‣ That means the library has to be backward compatible with the oldest version of Java you want to support (e.g., Java 6 or
7 in many cases).
‣ That effectively means you won’t get to use the new features of Java 9 in your library for a long time.
‣ Fortunately, the multi-release JAR feature allows you to create alternate versions of classes that are only used when running the library on a specific Java version
 
 
‣ In this case, multirelease.jar can be used on Java 9, where instead of the top-level multirelease.Helper class, the one under `META-INF/versions/9` is used. This Java 9-specific version of the class can use Java 9 features and libraries. At the same time, using this JAR on earlier Java versions still works, since the older Java versions only see the top-level Helper class.
 
2. NEW FEATURES IN JAVA COMPILER
1. Ahead-of-Time Compilation (AoT)
 
2.1. AHEAD-OF-TIME COMPILATION (AOT)
‣ One of the main goals while designing the java language was to make application portability a reality.
 
Java was designed in such a way that the same .class files created in one operating system can run seamlessly in another operating system or another computer without fail as long as the target system has a working Java Runtime Environment installed in it.
 
Initially released Java runtimes had significantly slower performance when compared to other languages and their compilers such as C and C++.
 
‣ To give better performance at runtime, complex dynamic compilers called Just-In-Time (JIT) were introduced.
 
JIT compilers selectively takes bytecodes of most frequently used methods in the application and convert them to native code during runtime
 
When method is compiled, JVM directly calls compiled method’s executable machine code rather than interpreting bytecode line by line.
 
2.1. AHEAD-OF-TIME COMPILATION (AOT)
‣ But there are certain drawbacks with this approach (JIT). In case of a large and complex Java application, JIT compilers may take a long time to warm up
. Java applications may contain methods that are not frequently used and hence never compiled at all. These methods may have to be interpreted while invoked. Due to repeated interpreted invocations, there could be performance problems
‣ Graal is an Oracle project aimed at implementing a high performance dynamic Java compiler and interpreter so that JVM based languages can achieve performance of native languages during runtime. There is a Java Enhancement Proposal [JEP 295] which has been put forward to use Graal with Java for Ahead Of Time Compilation.
 
2.1. AHEAD-OF-TIME COMPILATION (AOT)
‣ It is not officially supported by Java 9 but is added as an experimental feature
. Furthermore, AOT is currently restricted to 64 bit Linux based systems.
Ahead Of Time compilation is done using a new tool jaotc
instead of javac.
‣ To use Ahead Of Time compilation, users need to use the same JDK for
compilation and execution.
 
Version information about jaotc used for compilation is added as a part of the libraries and are checked during load time.
 
If the Java runtime is updated, you need to recompile the AOT compiled
modules before executing them. Mismatch in jdk versions used for compilation and execution may result in application crashes.
 
2.1. AHEAD-OF-TIME COMPILATION (AOT)
‣ Lambda expressions and other complex concepts of Java, which uses dynamically generated classes at runtime are not currently supported by AOT compiler.
‣ To generate shared object (.so) files, the system needs libelf to be pre-installed
‣ Java AOT compiler can be invoked in same way as javac:
 
jaotc –output libTest.so Test.class
 
‣ To execute the above AOT compiled binaries, we can execute:
 
java –XX:AOTLibrary=./libTest.so Test
 
 
3. NEW FEATURES IN JAVA LIBRARIES
1. Process API Improvements
2. Optional Class Improvements
3. Stream API Improvements
4. Collection factory methods
5. HTTP 2 Client
6. Reactive Streams
7. Multi-Resolution Image API
 
3.1. PROCESS API IMPROVEMENTS
‣ Java SE 9 is coming with some improvements in Process API. Couple new classes and methods have been added to ease the controlling and managing of OS processes.
‣ Two new interfaces in Process API:
– java.lang.ProcessHandle: Helps to handle and control processes. We can monitor processes, list its children, get information etc.
– java.lang.ProcessHandle.Info: It is added to Java 9, and used to provide information about the process. It is nested interface of ProcessHandle:
 
        
            ProcessHandle self = ProcessHandle.current();
            System.out.println(“Process Id: “ + self.pid());
            System.out.println(“Direct children: “+ self.children());
            System.out.println(“Class name: “ + self.getClass());
            System.out.println(“All processes: “ + ProcessHandle.allProcesses());
            System.out.println(“Process info: “ + self.info());
            System.out.println(“Is process alive: “ + self.isAlive());
            System.out.println(“Process’s parent “ + self.parent());
            ProcessHandle.Info processInfo = self.info();
            Optional args = processInfo.arguments();
            Optional cmd =
            processInfo.commandLine();
            Optional startTime = processInfo.startInstant();
            Optional cpuUsage = processInfo.totalCpuDuration();
        
    
 
3.2. OPTIONAL CLASS IMPROVEMENTS
‣ In Java SE 9, Oracle Corp has introduced the following three methods
to improve Optional functionality.
– stream()
– ifPresentOrElse()
– or()
‣ stream(): if a value present in the given Optional object, this stream()
method returns a sequential Stream with that value. Otherwise, it
returns an Empty Stream.
 
        
            Stream employee = getEmployee(id);
            Stream employeeStream = emp.flatMap(Optional::stream);
        
    
 
3.2. OPTIONAL CLASS IMPROVEMENTS
‣ ifPresentOrElse(): In Java SE 8, we should use ifPresent(), isPresent(), orElse() etc. methods to check an Optional object and perform some functionality on it. ifPresentOrElse method combines all those methods.
‣ or(): If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function
 
3.3. STREAM API IMPROVEMENTS
‣ The Streams API is arguably one of the best improvements to the Java standard library in a long time. It allows you to create declarative pipelines of transformations on collections. With Java 9, this only gets better.
‣ In Java SE 9, Oracle Corp has added four useful new methods to java.util.Stream interface.
‣ As Stream is an interface, all those new implemented methods are default methods.
1. dropWhile
2. takeWhile
3. ofNullable
4. iterate (new overloaded method)
‣ These are very useful methods in writing some functional style code.
 
3.4. COLLECTION FACTORY METHODS
‣ Often you want to create a collection (e.g., a List or Set) in your code and
directly populate it with some elements. That leads to repetitive code where
you instantiate the collection, followed by several `add` calls.
‣ With Java 9, several so-called collection factory methods have been added
Set<Integer> ints = Set.of(1, 2, 3);
‣ The Set returned above is JVM internal class:java.util.ImmutableCollections.SetN, which extends public java.util.AbstractSet. It is immutable.
‣ if we try to add or remove elements, an UnsupportedOperationException
will be thrown.
‣ You can also convert an entire array into a Set with the same method.
 
 
3.5. HTTP 2 CLIENT
‣ A new way of performing HTTP calls arrives with Java 9.
‣ New HTTP 2 Client API supports HTTP/2 protocol and WebSocket features with performance that should be comparable with the Apache HttpClient, Netty and Jetty.
‣ As existing or Legacy HTTP Client API has numerous issues like supports HTTP/1.1 protocol and does not support HTTP/2 protocol and WebSocket, works only in Blocking mode and lot of performance issues.
‣ It supports both Synchronous (Blocking Mode) and Asynchronous Modes. It supports Asynchronous Mode using WebSocket API.
‣ HttpClient provides new APIs to deal with HTTP/2 features such as
streams and server push.
‣ One caveat: The new HttpClient API is delivered as a so-called _incubator module_in Java 9. This means the API isn’t guaranteed to be 100% final yet.
 
3.6. REACTIVE STREAMS
‣ Now-a-days, Reactive Programming has become very popular in developing applications to get some beautiful benefits. Scala, Play, Akka etc. Frameworks has already integrated Reactive Streams and getting many benefits.
‣ Reactive Streams allows us to implement non-blocking asynchronous stream processing. This is a major step towards applying reactive programming model to core java programming.
‣ If you are new to reactive programming, please read Reactive Manifesto.
‣ Oracle Corps is also introducing new Reactive Streams API in Java SE 9.
‣ Java SE 9 Reactive Streams API is a Publish/Subscribe Framework to
implement Asynchronous, Scalable and Parallel applications very easily using Java language.
 
 
3.6. REACTIVE STREAMS
‣ Java SE 9 has introduced the following API to develop Reactive Streams in Java-based applications
– java.util.concurrent.Flow
– java.util.concurrent.Flow.Publisher
– java.util.concurrent.Flow.Subscriber
– java.util.concurrent.Flow.Processor
‣ Reactive Streams is about asynchronous processing of stream, so there should be a Publisher and a Subscriber.
‣ The Publisher publishes the stream of data and the Subscriber consumes the data.
‣ Sometimes we have to transform the data between Publisher and Subscriber. Processor is the entity sitting between the end publisher and subscriber to transform the data received from publisher so that subscriber can understand it.
 
3.7. MULTI-RESOLUTION IMAGE API
‣ The interface java.awt.image.MultiResolutionImage encapsulates a set of images with different resolutions into a single object.
‣ We can retrieve a resolution-specific image variant based on a given DPI metric and set of image transformations or retrieve all of the variants in the image.
‣ The java.awt.Graphics class gets variant from a multi-resolution image based on the current display DPI metric and any applied transformations.
‣ The class java.awt.image.BaseMultiResolutionImage provides basic
implementation:
 
        
        BufferedImage[] resolutionVariants = ….
        MultiResolutionImage bmrImage = new BaseMultiResolutionImage(baseIndex,resolutionVariants);
        Image testRVImage = bmrImage.getResolutionVariant(16, 16);
        
    
 
 
4. NEW FEATURES IN JAVA TOOLS
1. JShell: The interactive Java REPL
2. Jlink: Linking
3. JCMD Improvements
 
4.1. JSHELL: THE INTERACTIVE JAVA REPL
‣ It’s an interactive tool to evaluate declarations, statements, and
expressions of Java, together with an API.
‣ It is very convenient for testing small code snippets, which
otherwise require creating a new class with the main method.
 
        
        jdk-9\bin>jshell.exe
        | Welcome to JShell — Version 9
        | For an introduction type: /help intro

        jshell> “This is my long string. I want a part of it”.substring(8,19);
        $5 ==> “my long string”
        
    
 
4.2. JLINK: LINKING
‣ When you have modules with explicit dependencies, and a
modularized JDK, new possibilities arise.
‣ Your application modules now state their dependencies on other
application modules and on the modules it uses from the JDK
‣ Why not use that information to create a minimal runtime environment, containing just those modules necessary to run your
application?
‣ That’s made possible with the new jlink tool in Java 9
‣ Instead of shipping your app with a fully loaded JDK installation, you
can create a minimal runtime image optimized for your application.
 
 
4.2. JCMD IMPROVEMENTS
‣ Let’s explore some of the new subcommands in jcmd command line utility. We will get a list of all classes loaded in the JVM and their inheritance structure.
‣ In the example below we can see the hierarchy of java.lang.Socket loaded in JVM running Eclipse Neon:
 
        
        jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s java.net.Socket
        14056:
        java.lang.Object/null
        |–java.net.Socket/null
        | implements java.io.Closeable/null (declared intf)
        | implements java.lang.AutoCloseable/null (inherited intf)
        | |–org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
        | | implements java.lang.AutoCloseable/null (inherited intf)
        | | implements java.io.Closeable/null (inherited intf)
        | |–javax.net.ssl.SSLSocket/null
        | | implements java.lang.AutoCloseable/null (inherited intf)
        | | implements java.io.Closeable/null (inherited intf)
        
    
 
The first parameter of jcmd command is the process id (PID) of the JVM on which we want to run the command.
Another interesting subcommand is set_vmflag. We can modify some JVM parameters online, without the need of restarting the JVM process and modifying its startup parameters
 
5. NEW FEATURES IN JAVA RUNTIME (JVM)
1. G1 as the default garbage collector
 
5.1. G1 AS THE DEFAULT GARBAGE COLLECTOR
‣ One of Java 9’s most contested changes, second only to Project Jigsaw, is that Garbage First (G1) is the new default garbage collector
‣ G1 limits pause times and is giving up some throughput to achieve that. Implementation-wise, it does not separate the heap into continuous spaces like Eden, young and old but into fixed-sized regions, where G1 assigns a role to a region when it starts using it and resets the role once it collected the region’s entire content. Talking about collections, those focus on the regions with the most garbage, hence the name, because that promises the least work.
‣ G1 will identify String instances that have equal value arrays and then make them share the same array instance. Apparently, duplicate strings are common and this optimization safes about 10% heap space.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Post a Comment

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code