Saturday, 14 October 2017

Java Platform Module System (Project JIGSAW) - Part-1 Introduction

Why Project Jigsaw

Project JIGSAW is a star project of Oracle corporation and is responsible for release of Java Platform Module system. Modularity means breaking coarse grained JDK/JARS into fine grained modules to reduce coupling, provide stronger encapsulation and move from monolithic code and data to self-describing collection of code and data.

According to Mark Reinhold following problems necessitated new module system and JAVA 9, will address all of them.

1.Classpath Limitations 
2. Bulky monolithic JDK 
3. Poor Encapsulation 

Limitations of Classpath

JAR Hell, a common term which defines ways in which classloading process can end up not working.Classpath causes following well-known problems:
  • If two jars has different names but same content, it will result in a conflict during classloading. What's worse is that it's hard to find conflict
  • Fundamental issue with jar files is that they are not components. Rather they are containers that will be searched linearly during classloading.Classpath is a way to look up for classes regardless of what components they're in, or what packages they intended to use

Bulky monolithic JDK

Big size of monolithic JDK causes following problems:
  • Doesn't fix on small devices. Even IoT type devices fall short of memory to hold all JDK.What's bad is that not all part of it is used by application
  • It causes issues with CLOUD. CLOUD is all about optimising use of hardware, but running thousand of images of whole JDK when only tiny part of is used in application, is only a waste

Poor Encapsulation

public is too public !
Consider the following classes (assume both are public):
com.school.StudentDao
com.school.impl.StudentDaoImpl
Suppose in a class my team should use only studentDao not and not studentDaoImpl directly. However there is no way to enforce that on classpath.

Given the above classes, someone could still do this in Java 8:
Class c = Class.forName("com.school.impl.StudentDaoImpl");
Object obj = c.getConstructor().newInstance();

Module System : Solution to problems

A module is a self describing collection of data and code.It comprises of set of packages, containing Java Classes, interfaces, resources and a module-info.java file which is called module descriptor. 
Every module has only one module-info.java which contains information of 
  -What other modules this particular module is dependent(requires)
 - Which of the packages present in this module is exposed to others modules(exports) 
Unlike the class-path mechanism , which look for all classes at classpath, module system ensures that, a module can only refer to types(data) in the module upon with it depends. This access-control mechanism of Java language and JVM prevents code from accessing types in packages that are not exported by their defining modules.
When code in a particular module refers to a type in a package, then that packages is guaranteed to be defined either in same module or in exactly one of the modules read by another module(which exports that package and current modules requires it). When looking for the definition of a specific type there is, therefore, no need to search for it in multiple modules, or worse, along the entire classpath.
This mechanism not only solves classical classpath conflict, but also makes classloading more reliable, modular, faster and improves running performance.
Moreover, breaking monolithic JDK into smaller chunks and exporting only those modules which are actually used, not only makes application smaller, it results in better utilisation of hardware and enhances system performance.

Java Enhancement Proposal(JEP) for Jigsaw

Project Jigsaw is an enormous and prestigious project and is ongoing for quite few years.Following JEP's were assigned to Jigsaw :

The Modular JDK (JEP 200): 
   -Break big monolithic JDK into several smaller modules

The Modular Source Code  (JEP 201): 
   -Reorganise JDK source code to modules and break fat jars like rt.jar into lightweight modules

The Modular Run Time Code  (JEP 220): 
   -Restructure JDK and JRE run-time images to accomodate modules and to improve performace,          security and maintainability

Encapsulate Most Internal APIs (JEP 260): 
   -Make most of JDK's most internal APIs inaccessible by default but leave a few critical,widely- used internal API's accessible until replacement exists for all

Modular System (JEP 261): 
   -Functionality to provide user to write their own modules

The Java Linker : jlink (JEP 282):
   -Create a tool to assemble and optimize a set of modules and their dependencies into a custom run-time images 

    Dive into Modular System

    Jdk-8 Vs Jdk-9

    Pre JDK-9 , JDK folder used to have jre folder and two fat jars (rt.jar and tools.jar)
    JDK-9 has removed jre folder along with tools.jar file and added a new folder jmods.
    This jmods folder has 97 modules(java 9 EA release) and can be found at ${JAVA_HOME}/jmods.
    More number of modules might get added in future release by Orcale corp.













    Java 9 Module System

    Oracle has divided all jars of JDK-9 into two parts :
    • All JDK jars has been moved to JDK modules and their names starts with "jdk."
    • All Java SE jars names starts with "java."
    • "java.base" is called as base module. This module isn't dependent on any other module.All other modules, by default, depends upon this base module.
    Difference between Java 8 packages and Java 9 modules

    Packages are top level components in java-8 and earlier versions.A package contains following items:
    • Code(Interfaces, Classes, Abstract classes etc.
    • Data
    • Resources
      1. XML
      2. Resources
      3. Static files
      4. Properties files etc.
    Module is a top level component in java-9 and contains one or more packages along with a descriptor file called "module-info.java", that is always placed at top level and it defines rules for exporting packages and reading other modules.

    In nutshell, module system is a superset of package system that was there pre-java 9, with an additional module descriptor file.


    Module Descriptors

    Each Java module has a single module descriptor , i.e. module-info.java file. This file defines which packages of current module will be exported and on what other modules it is dependent upon.
    Following are the options available for descriptors :

    • requires <module-name>
             Requires Comamnd is used to define on what modules this current module is dependent upon

    • requires transitive  <module-name>
            Transitive keyword is used when current module is dependent upon modules that are required   by the module it is dependent upon. E.g. if module A depends upon B, B depends upon C, then with transitive keyword, we mean A reads C as well. Even though A read B directly.
         
             Note : By default transitive dependencies aren't resolved.

    • requires static  <module-name>
            This dependency check is mandatory at compile time and is optional at runtime.

    • exports <package-name>
             This package is exported to all modules. If a package is not exported it cannot be used by any  other modules and can only be used by packages in the same module.
    • exports <package-name> to <module-name>
            This package is exported to this specific module and not to all modules. 
    • exports <package-name> to <module-name>
            This package is exported to this specific module and not to all modules.
    • opens <package-name>
            If a module doesn't export a package then it cannot be accessed by any module.With                         "opens"keyword, all modules can access this package through Reflection.Access of public type is present at compile type and private type at runtime.
    • Uses <service-interface> 
            Implementation of interfaces in this module can reside in this module or in some other module
    • Provides <service-interface> with <class1>,<class2>
            Implementation is mentioned for this interface.

    That's all for Part-1 Introduction. In part-2 i will discuss in depth, creation of custom modules and other concepts of Java Module system. 


    Happy Learning!!






    Thursday, 12 October 2017

    Jshell (JAVA + REPL)

    If I really want to figure out how a class or method works, I prefer to experiment directly with the code. Unlike documentation, code never lies. Also, programming is best learned by programming. The jshell is the ideal solution for this. I’ve always been annoyed by the overhead necessary to “briefly” run a few lines of code. With the jshell it’s so much simpler now — people should go try it for themselves right now!
                                                                                                         --Marcus Biel

    Brief Table of Content
    • Introduction to JShell
    • Running JShell
    • JShell Default imports
    • JShell configurations
    • JShell Expressions
    • JShell Methods
    • JShell Classes
    • JShell Commands
    • Exceptional Handling in JShell
    Introduction
    Read–Eval–Print Loop (REPL)  or language shell is a simple , interactive environment to execute code snippets and was there in scripting languages like python or Node. REPL is introduced as jshell in Java 9.

    Pre Java 9 , just to print classic "Hello, World" statement , we have been following below steps :
    1. Create a project
    2. Create a class with main method and a print statement with "Hello, World"
    3. Compile above class
    4. Run this class

    public class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello, World");
        }
    
    }
    Too many statements for a simple task!!

    With jshell println method can be executed instantly! That's a bliss when you are new to java.
    Further you don't need to recompile class whenever you introduce any changes. Jshell handles it
    smoothly for you.

    Running JShell
    JShell is present as an executable in JDK9. Just move to bin directory of jdk9 installation and execute jshell command to run jshell. You will get a welcome message from jshell.

    JShell Default Imports

    By default shell imports following packages.You can import other packages by import command.
    jshell> /imports
    |    import java.util.*
    |    import java.io.*
    |    import java.math.*
    |    import java.net.*
    |    import java.util.concurrent.*
    |    import java.util.prefs.*
    |    import java.util.regex.*

    JShell configurations
    Default jshell configurations are adequate when you start learning this tool. But sometimes you need more control over and above default configurations .

    Following configuration can be used to fine tune jshell.
    1. Setting modules options
    2. Setting classpath JARS
    3. Feedback mode
    4. JShell scripts
         a. Loading scripts
         b. Start-up scripts

    Adding Modules

    Executing commnad -add-modules and -module-path loads external classes from java modules.
    Once you add modules you can import packages present in an added module.

    jshell --add-modules jdk.httpserver


    Adding JARS

    External code can be accessed by jshell tool by setting classpath.Classpath can be set through following command :
    jshell --class-path junit-4.12.jar


    jshell --class-path junit-4.12.jar
     |  Welcome to JShell -- Version 9
     |  For an introduction type: /help intro
     jshell>  import org.junit.Testimport java.util.*

    Feedback Modes

    External To manage user interactions configuration , feedback mode can be used.
    There four built-in feedback modes, in descending order of verbosity:
    verbose, normal, concise, and silent.

    jshell --feedback verbose


    JShell Scripts

    A JShell script is a sequence of JShell commands in a file , one for each line.
    JShell script can be created externally in any editor or can be generated with any of the follwiing commnads.
    jshell> /save aScript.jsh
    
    jshell> /save -history historyScript.jsh
    
    jshell> /save -start  startupScript.jsh
    Name of script can be anything or anything like above or one of the predefined scripts given below.

    DEFAULT - This script loads default behaviour and runs if one of script is not set
    JAVASE - It imports all JAVA SE packages by default
    PRINTING - defines JShell methods for print, println and printf in PrintStream

    Loading JShell scripts
    JShell scripts can be loaded by following command line on shell tool  :

         jshell aScript.jsh
    
    
    or by opening script with /open command:
    jshell> /open PRINTING
    Start-up scripts

    Running command -startup with predefined scripts or with user created scripts will load scripts at start up.

           jshell --startup PRINTING
           jshell --startup aScript.jsh


     JShell Expressions

    In JShell you can fire any valid expression on a valid java type. JShell will evaluate that expression , assign it's result to a jshell variable.

    Expressions that can be expressed in java , can also be executed on jshell command line tool.



     JShell Variables

    Just like in class , you can declare a variable and it's type on jshell. Once declared you can access it , and modify to some other value.
    It's possible to define a variable as private , static and final, but since everything runs in a single scope , it has no effect on declared variable.
    Jshell issues a warning when you declare a variable as either static or final.



    NOTE : Since final variables are not final , we can resassign it to some other value.


    We can redefine variable on jshell tool and can assign it to some other type.

     JShell Methods

    You can create method in Jshell command tool just like we define static method in a class. We also don't need to use static keyword for creating a method.


    You can replace an existing method with a new method by changing it signature.







     JShell Classes

     Just like methods you can create a complete class on JShell tool.


    Just like we redefined a method, on jshell tool you can also redefine a class.
    Note : Redefining a class will automatically assign all variables of that type to null for safety reasons.


    You can access any class in Jshell like you do on JVM.


    If a class is present in any imported package, then you can use it there itself, else you can use import flag present on jshell.


    If you wish to import everything that's provided in JAVA SE , you can run JAVASE startup script as mentioned earlier.

    JShell Commands
    Jshell has provided several useful commands for displaying information.

    To display information following commands are used :
    /vars : current variables
    /methods : methods
    /list : all entered snippets
    /imports :  all imported packages
    /help : for all available commands


    Command : /vars


    Exception Handling

    Whenever an exception is throw on jshell , it prints the stack trace and also shows line number exactly like java.
    It also reveals the line number where exception is thrown.

    # Here exception is throw at line number 1.
    Conclusion

    JShell is extremely useful for testing java code snippets. A feature like this was missing in JAVA since very long and with it's introduction in JAVA 9, makes java stands on par with other modern languages.
    Testing a snippet now with jshell is faster and it was needed for making development faster with shorter feedback cycle.


    Happy Learning !!!