Java Weekly Newsletter 2

Java Weekly Newsletter Issue 2

Hello and welcome to the  Java Weekly Newsletter Issue 2

 

1.  Blog Posts

In case you have missed any of my posts, here is the list of articles we published this week.

  1. Introduction to  Java Garbage Collector
  2. Java NIO Selector
  3. Collection Factory Methods in Java 9
  4. Java Directory Size

 

2. Spring & Java Community

  1. The Final Pieces of Java 9 and Project Jigsaw Are Coming Together
  2. A good article on introduction to Quartz Scheduler
  3. Top 10 Mistakes That Java Developers Make
  4. Java Time (JSR-310) enhancements in Java SE 9

 

3. JPA / Persistence

I do not work very closely in JPA or Hibernate but following few of the blogs for some of the interesting insight into Persistence 

  1. How to Find Redundant Indexes in SQL

4. Spring Releases

  1. Spring Session 2.0.0 M2 Released
  2. Spring Boot 2.0.0.M2 Available Now
  3. Spring Security 5.0.0 M2 Released

 

5. Presentations and Videos

  1. It’s a kind of magic: under the covers of Spring Boot
  2. 10 Ways to Get Super Productive with Spring BootIt’s a kind of magic: under the covers of Spring Boot

 

6. General

  1. What Are the Top 10 Causes for Unhappiness Among Developers

We will be back with our next weekly newsletter with some more insight details about Java and Spring community.

Happy Coding !!!!

 

If you haven’t Signup to our weekly newsletter, Signup Now

Java Garbage Collector

Introduction to  Java Garbage Collector

In this post, we will explore what is Java Garbage Collector, How Java Garbage Collector Work? We will also cover what are the different Garbage collector available in Java and what are the new enhancement/improvement available in Java 8.

This post covers basic of the Java Garbage Collector API and does not provide inside view of the API.

 

1. What is the garbage collector in Java

In very simple terms, garbage collection is an automatic memory management programme in Java which removes the unused object in a Java programme. It process heap memory and will identify the object which are in use and which are not.It looks for objects which are not in use and simply get rid of those unused objects.

for (String name : nameList) {
String s = name.getName();
}

In above code, We are creating String object in each iteration and if you pay attention, the object created in the previous iteration is no longer in use, if we will keep running this loop (say 1000 time), we will create these objects which are no longer in reference and us simply call these objects are Garbage. Each object creation takes some memory and if we keep on going (say 100000 times) at some point JVM will run of memory.

In order for better memory management, JVM comes with Garbage Collector which perform automatic memory management (i.e. JVM will pull it whenever required to clean up some memory).

 

2. How Java Garbage Collection Really Works

One of the main misunderstandings about the Java Garbage Collector is that it remove dead objects (not in reference) which it works in opposite way ( 🙂 ). Garbage collector keeps trek of all the live objects and everything else is marked as garbage.

In theory, Java Garbage collector work in a very simple fashion

  1. When an object is no longer in use, Garbage collector will claim memory used by this unused object and will use it for future object creation.
  2. There will not be any explicit object deletion and head memory will remain with JVM.

In order to determine which object is alive and which is garbage, JVM uses a special object also known as GC root (garbage collection root). JVM will treat the object as alive if the programme can reach to root object.

I will skip this discussion as to how JVM marked an object as GC root, this topic needs a separate blog post.

2.1 Mark and Sweep Algorithm

JVM uses the mark and sweep algorithm to determine/mark which object is in use and which is no longer in use. This algorithm work in 2 steps

  1. In the first step, it will process all references and will mark all those objects which are alive.
  2. As a second step, it will reclaim all the heap memory for all the objects which are not marked as alive.

While it seems simple, keep in mind that Garbage collector mark object alive based on the reference, in case you created an object which is not in use but still referred by some instance, it will be treated as alive object (even it is not in use).

 

3. Java Garbage Collector Types

One of another major misunderstanding about Java Garbage collector is that JVM has only 1 Garbage collector but the truth is there are around 5 garbage collectors (as per JDK7).

We will be covering these different garbage collector in the next segment. All these GC algorithms work on a very fundamental assumption that “Objects in Heap are short lived and should be recycled as quickly as possible.

 

3.1 Serial GC

It’s the simplest and least usable one. It was mainly designed for a single threaded environment. Do not use Serial GC. One of the main issue with Serial GC is its ability to freeze all threads whenever it’s active (one of the reasons why it is called as Serial GC), this can cause serious application performance issue.

In order to enable Serial GC, you need to pass following parameters to the JVM 

-XX:+UseSerialGC 

 

3.2 Parallel GC

This is the default GC in Java 7 and Java 8. Parallel GC use multiple threads to scan heap for the GC process. Having the ability to use multiple threads makes this GC much faster, however, it will stop all application thread whenever it’s performing GC operation (full or partial GC operation). Parallel GC is also known as Throughput collector.

This is the default GC for the JVM, in case you want to change some other GC collector to Parallel GC, you need to specify following JVM parameter

-XX:+UseParallelGC

 

3.3 CMS GC

Concurrent-Mark-Sweep also known as CMS GC use multiple threads to scan through the head for possible GC process. It works as follows

  1. It used multiple threads to scan through the heap and will recycle unused object 

Multiple threads denote concurrency, scanning head denotes marking (where it marks alive object in heap) and recycles unused objects is marked as sweep hence Concurrent-Mark-Sweep. One of the main advantages of this algorithm is having a very slow pause time of application threads as it works in parallel to application threads (without stopping them ).

This GC is best suitable for application where application response time is a critical aspect. CMS GC has some disadvantages.

  1. Since it works in concurrency mode, it usually requires more memory and CPU usage.
  2. In case running application have done some changes to the heap state when GC was running, it will be forced to redo some final steps to make sure it has the updated reference information.
  3.  One of the main disadvantages of the CMS GC is encountering Promotion Failure (Long Pauses) which happens due to the race conditions.

This does not default GC in JVM, use the following command to enable it for the underlying JVM

XX:+USeParNewGC

 

3.3 G1 GC

JDK 7 introduced a new GC known as The Garbage-First (G1), collector. One of the fundamental difference between G1 Collector and other collector is a division of the Heap into multiple regions.The JVM generally targets around 2000 regions varying in size from 1 to 32Mb. 

G1 collector normally uses multiple background threads to scan these regions and will pick the region with most garbage objects (that’s why we call it Garbage First). 

In order to enable this GC, you need to pass the following parameter to JVM. 

 XX:+USeG1GC

There are couple of advantages of over other GC 

  1. It’s fast as compare of other GC since it will target region with most garbage objects.
  2. G1 GC will compact heap on the go which other GC lacks.
  3. Since G1 split Heap into multiple regions, a common “stop the world (pausing all running application threads )” is avoided by this GC (In place of scanning entire heap, it will scan on region basis).
  4. G1 GC is really a performance boost in the current scenarios where big heap size and multiple JMV per machines is common architectures

 

3.4 G1 GC and Java 8

Java 8 added a new feature called String Deduplication , String takes a lot of heap size and this new feature will ensure if a given String is duplicated across the heap, it will be automatically pointed to same internal char[], thus avoiding multiple copies of the same content. 

Use following JVM argument to enable this feature

-XX:+UseStringDeduplication

It tries to Reduce the Java heap live-data set by enhancing the G1 garbage collector so that duplicate instances of String are automatically and continuously deduplicated.

When G1 GC come into picture, it will perform following operations

  1. It scans objects in the heap and check is applied to see if the object is a candidate for string deduplication.
  2. All such items are added to a queue and deduplication thread will process this queue to make sure all duplicate instances are pointing to the same internal char[].

Another significant change happened in Java8 memory management is the removal of PermGen. It indicates that this memory management will also be performed by JVM and it’s a step to handle those OutOfMemoryError.

Please read Will Java 8 Solve PermGen OutOfMemoryError? to get more details and reasons for removing it in Java 8.

 

I hope that it will give you a high-level overview of different Garbage Collector available in Java along with how they work and how we can be configured in the JVM. We also get a high-level overview of the new enhancement and changes introduced in the Java 8 for the G1 collector.

Java NIO Selector

Java NIO Selector

In this post, we will explore feature and the basic understanding of Java NIO Selector API. The selector is an NIO component with an ability to monitor or examine multiple channels and determines which is ready for the IO operation (read or write).

One of the benefits of this is to use single thread to manage multiple channels which in simple terms is “multiple network connections”

1.  Use of  NIO Selector 

If you are familiar with threads, you must be aware that switching between thread is an expensive process as it involves underlying operating system, also thread means a new process which eventually will consume some memory. (With new OS, switching threads is not a big issue)

With Java NIO Selector, you can use a single thread to manage multiple channels, in other words, you are not creating multiple threads to manage multiple channels.

Java NIO Selector
Java NIO Selector

2.  Selector Configurations

The selector is part of the java.nio package. We can register multiple channels with Selector, once registration is done, Selector API will inform us if any NIO activity happens with these registered channels.

3.  Creating Selector

A new selector can be created by using open method of Selector class.JDK internally call system-wide default SelectorProvider.

Selector selector = Selector.open();

 

3.  Register Channels with Selector

For Selector to monitor different channels, we need to register these channels with Selector.To register, use register method of the selectable channel.

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("https://www.javadevjournal.com",80));
socketChannel.configureBlocking(false);
SelectionKey key= socketChannel.register(selector, SelectionKey.OP_READ);

with configureBlocking(false), we are setting it in non-blocking mode. While registering the first parameter passed to register method is the selector.

The second parameter is called “interest set”, it indicates at what even selector should notify us. SelectionKey provides following 4 options as “interest set”

Operation NameDescription
OP_READWhen server is ready to read from Channel
OP_WRITEReady to write
OP_CONNECTWhen the client is trying to connect.
OP_ACCEPTWhen the server accepts client connection request

Register method will return SelectionKey represent channel register with the selector. 

 

4.  Selection Key

Channel registration with the selector return SelectionKey object SelectionKey is a representation of the SeletableChannel and contains few of the interesting elements, in order to utilise selector efficiently, a basic understanding of these elements is desired.

4.1  Interest Set

Interest set contains information about the event we are interested. It is an integer value. We can use interestOps() method to get set which is valid for current Channel.

We can use int value returned by interestOps method along with SelectionKey class to determine correct interest set.

int interestSet= key.interestOps();

 

4.2  Ready Set

Ready set defined a set of event that selected channel is ready for, the Ready set is also represented by an integer value.Use readyOps() method to get information about the Ready Set.

int readySet= key.readyOps();

Alternatively, you can use SelectionKey’s utility method to get these values.

key.isAcceptable();
key.isConnectable();

 

Keep in mind that these methods will return a boolean value and not an integer.

4.2  Channel and Selector

Use SelectionKey class to get information about the associated Channel and Selector 

key.channel();
key.selector();

 

5.  Channel Selection Process

As of now we have done following work 

  1. Create Selector.
  2. Create Desired Channel.
  3. Register channel with the selector.

Once we register multiple channels with the selector, use the select method to get the interested channel  (e.g If we want Channel ready for reading, we will get channel ready for reading).

selector.select();

Above method will work in blocking mode, It returns only after at least one channel is selected.Returned int value represents a number of channels ready for the operation.

As I said, select() the method will give us a hint as how many channels are ready for the operation, we can access all these ready channels by using selectedKeys() method.

Set<SelectionKey> readyToUseChannel= selector.selectedKeys();

You can iterate over the set to get information about the ready channels and can use the desired channel to perform required information (Read, Write operation etc.).

Set<SelectionKey> readyToUseChannel= selector.selectedKeys();
for(SelectionKey selectionKey : readyToUseChannel){
if(selectionKey.isAcceptable()){
// connection accepted
}
else if(selectionKey.isReadable()){
//channel ready to read
}
}

References

Selector

Java Directory Size

Java Directory Size

In this post, we will learn how to get the Java directory size or size of a folder in Java using Java 7, Java 8 and Apache Commons API.

 

1.  Get Size Using Java 7

We will be using Files.walkFileTree() method to recursively transverse through the files/directory to calculate the size.

public class DirectorySizeJava7 {
public static void main(String[] args) throws IOException {
Path rootDirectory= Paths.get("/Users/umesh/personal/tutorials/source/bootstrap");
AtomicLong size= new AtomicLong(0);
Files.walkFileTree(rootDirectory, new SimpleFileVisitor<Path>(){
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException{
size.addAndGet(attrs.size());
return  FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exception)
throws IOException
{
//log exception
throw exception;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exception) {
//log exception for error in reading file if exception is not null
return FileVisitResult.CONTINUE;
}
});
System.out.println("size of the folder is :: " + size);
}
}

Output

the size of the folder is:: 1650691

I have used AtomicLong in above example to store size, which guarantees that the value can be used in a concurrent environment.

 

2.  Get Size Using Java 8

We will be using  Stream API along with Lambda expression provided by Java 8 to calculate the size of the folder.

public class DirectorySizeJava8 {
public static void main(String[] args) throws IOException {
Path rootDirectory = Paths.get("/Users/umesh/personal/tutorials/source/bootstrap");
long directorySize = Files.walk(rootDirectory)
.map(f -> f.toFile())
.filter(f -> f.isFile())
.mapToLong(f -> f.length()).sum();
}
}

 

We used stream API and making sure to filter out all directories by using filter(f -> f.isFile()). Please be aware that length method is not guaranteed to be 0 for directories. 

We converted the result to LongStream by using mapToLong method and finally summed up the results to get the size.

Output

the size of the directory is::1650691

Note

Keep in mind following information while using  walkFileTree or walk method under Java 7 and Java 8

  1. Underlying Java Security Manager can throw an exception in case we do not have permission to access it.
  2. Symbolic links can lead to infinite loop issue.

 

3.  Get Size Using Apache Commons

Apache Commons IO’s FileUtils class provide a clean way to calculate the size of a given directory.

public class DirectorySizeApacheCommons {
public static void main(String[] args) {
File rootDirectory = new File("/Users/umesh/personal/tutorials/source/bootstrap");
long size= FileUtils.sizeOfDirectory(rootDirectory);
System.out.println("The Size of directory is:: "+size);
}
}

Output

The Size of directory is:: 1650691

You need to be aware of the following 

  1. You have to check if the file is directory else API will throw IllegalArgumentException.
  2. It might also throw IllegalArgumentException if the directory is being concurrently modified. Check IO-449.

 

4.  Get Size Readable format

Printing information in human readable format is always a preferred way. Here is a small programme to print size information obtained in this post in human readable format.

public class DirectorySizeApacheCommons {
public static void main(String[] args) {
File rootDirectory = new File("/Users/umesh/personal/tutorials/source/bootstrap");
long size= FileUtils.sizeOfDirectory(rootDirectory);
readableFileSize(size);
}
public static void readableFileSize(long size){
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int unitGroups = (int) (Math.log10(size)/Math.log10(1024));
System.out.println(new DecimalFormat("#,##0.#").format(size/Math.pow(1024, unitGroups)) + " " + units[unitGroups]);
}
}

All the code of this article is available Over on Github. This is a Maven-based project.

References

Apache Commons IO

DecimalFormat

AtomicLong

Java Weekly Newsletter 1

Java Weekly Newsletter Issue 1

Hello and welcome to the very first  Java Weekly Newsletter Issue 1

 

1.  Blog Posts

In case you have missed any of my posts, here is the list of articles we published this week.

  1. Introduction to Java 9 REPL and JShell
  2. Introduction to Java 8 Optional API

 

2. Spring & Java Community

  1. javap Usage Unfolds: What’s Hidden Inside Your Java Class Files?
  2. JSF Applications with Spring Session
  3. JVM’s Automatic Resource Management
  4. 11 Mistakes Java Developers make when Using Exceptions
  5. Java’s Observer and Observable Are Deprecated in JDK 9
  6. Bootstrap a Simple Application using Spring Boot 
  7. Using Kotlin’s Apply Function for Dynamic SQL with jOOQ
  8. 10 Tips on How to be a Great Programmer

 

3. JPA / Persistence

I do not work very closely in JPA or Hibernate but following few of the blogs for some of the interesting insight into Persistence 

  1. The best way to use entity inheritance with JPA and Hibernate

4. Spring Releases

  1. Spring Data Release Train Kay M4 Released 
  2. Spring Framework 5.0 RC2 available now
  3. Spring Boot 1.5.4 Available Now

 

5. Presentations and Videos

  1. Real-World Java 9
  2. Getting Started with Spring Boot
  3. Core Design Principles for Software Developers

We will be back with our next week newsletter with some more insight details about Java and Spring community.

Happy Coding !!!!

 

If you haven’t Signup to our weekly newsletter, Signup Now

Java 9 REPL

Introduction to Java 9 REPL

In this post, we will explore Java 9 REPL (Read-Evaluate-Print-Loop) feature or shortly called as JShell. Many modern languages provide a tool (Mostly called as REPL or scripting tool) for real-time statement interpretation.

One of the benefits of such tool is that you can easily test your code without creating a complete class or project.Java 9 will be introducing REPL or JShell which can be used to quickly run your code and compare results. 

This post assumes that you already have Java 9 installed on your machine, if this is not the case, install Java 9 on your machine before moving forward. 

REPL Concept is not new and some of the modern languages have provided this feature, here is the list

  1. Groovy Console
  2. Beanshell
  3. Scala

If we want to run some programme in Java (Java 8 or lower version), We need to create a project and the main method to run that code and any change require a recompile and repeat this process.

1. What is Jshell

Jshell will be shipped as part of the Java 9 and will work as scripting shell to run your Java code without the need of creating project or class with the main method.

To run Jshell, run following command with -v to get information about the version


localhost:~ umesh$ jshell -v
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro
jshell> 

If you have Java 9 configured correctly, Jshell will greet you with a Unix style welcome message.

2. What is Jshell

Jshell comes with a certain set of default import. This indicates you don’t have you do explicit import for these to run you programme, to list default imports run /import command in Jshell


jshell> /import
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.nio.file.*
|    import java.util.*
|    import java.util.concurrent.*
|    import java.util.function.*
|    import java.util.prefs.*
|    import java.util.regex.*
|    import java.util.stream.*
jshell>

Jshell /import will give you a list of import for the current session, this means if you will add additional import and run this command again, those import will be added automatically by Jshell for the current session.

3. Simple Hello Word

Running and printing simple hello work using Jshell is quite simple and you don’t need to write a complete .java class for this.


jshell> System.out.println("Hello World from Jshell!!!");
Hello World from Jshell!!!
jshell>

Jshell is flexible in nature and you can even skip adding ; at the end of the statement and Jshell will handle it internally.


jshell> System.out.println("Hello World from Jshell!!!")
Hello World from Jshell!!!
jshell>

4. Creating and Running Method

Methods can be created and executed easily using Jshell


jshell> void helloWorld(){ System.out.println("Hello World!!");}
|  created method helloWorld()
jshell> helloWorld()
Hello World!!
jshell>

Jshell even allows you to modify your existing code, Let’s say we want to change “Hello World!!” to “Hello World from JShell”, you can easily change it.


jshell> void helloWorld(){ System.out.println("Hello World from JShell!!");}
|  modified method helloWorld()
|    update overwrote method helloWorld()
jshell> helloWorld()
Hello World from JShell!!
jshell>

5. Expressions

Jshell will accept any valid Java expression, Jshell will execute the expression, it will provide you information about the value, value type.


jshell> 3+7
$5 ==> 10
|  created scratch variable $5 : int
jshell> $5
$5 ==> 10
|  value of $5 : int
jshell>

Jshell provides you with a detailed information about the new variable ($5) it created and what is the value assigned to this new variable.You can even refer to this variable by just naming it $5

6. Variables

You can create variable and even name those variables using JShell, these variables will be visible in the current Jshell context and you can change/modify values as per your need.


jshell> int i=10
i ==> 10
|  created variable i : int
jshell> String blogName="Umesh Awasthi";
blogName ==> "Umesh Awasthi"
|  created variable blogName : String
jshell> blogName= blogName+" Java 9 REPL";
blogName ==> "Umesh Awasthi Java 9 REPL"
|  assigned to blogName : String
jshell> blogName
blogName ==> "Umesh Awasthi Java 9 REPL"
|  value of blogName : String
jshell>

7. Commands

Jshell provide number of build in command which can be used to get some insight on to the JShell, you can run these command on the JShell using forward slash (“\”) 


jshell> /vars
|    int $5 = 10
|    int i = 10
|    String blogName = "Umesh Awasthi Java 9 REPL"
jshell> /methods
|    void helloWorld()
jshell>

You can use /vars to list all variable in the current context, a similar way you can use /methods to list down all the method in the current context. Use /help to start Jshell help menu.

8. List

Jshell is quite powerful and it keeps trek of the activities happening in the current context, however, it’s not an IDE and you might want to get a list of all variables or methods or values being used in the context, Jshell provides /list method to give you all the information.


jshell> /list
2 : helloWorld()
3 : void helloWorld(){ System.out.println("Hello World from JShell!!");}
4 : helloWorld()
5 : 3+7
6 : $5
7 : int i=10;
8 : String blogName="Umesh Awasthi";
9 : blogName= blogName+" Java 9 REPL";
10 : blogName
jshell> 

9. Save and Reload

Use /save method to save expression history, it will save a file in the same directory from which we are running the Jshell. To open saved file, we can use /open a command.


jshell> /save jshell.java
jshell> /open jshell.java

10. Forward reference

JShell provides a very good support for forward reference, this means we can refer to variable or methods which we are planning to introduce later in our code.

code class="language-vim">
jshell> double totalPendingAmount(int customerNumber){ return getCustomerPendingAmount(customerNumber);}
|  created method totalPendingAmount(int), however, it cannot be invoked until method getCustomerPendingAmount(int) is declared
jshell>

The interesting part is the output of above command, JShell indicating that we will not be able to use this method until getCustomerPendingAmount(int) is defined.

11. JShell API

Jshell also provides API which can be used by external parties to use Jshell capabilities. 

12. Why use Jshell

We are going to have a very natural question “Why use Jshell ??” , I will try to come up with some use cases where it will really be handy to use Jshell 

  1. JShell API provides a way to have a network connection, We can use it to connect to our remote server and may change few things remotely.
  2. We can even connect to DB and perform some operations.
  3. API can be used to hook into live JVM’s to get an insight of it.
  4. We can use JShell to determine and verify return type (Check video for detail)
  5. Rapid prototyping, You can quickly modify and run your programme without waiting for multiple rebuilds or redeploy.

13. Video Tutorials

It is always interesting to see things in action. Please watch this video to see Jshell in action.

Conclusion

Jshell is really interesting and powerful tool for rapid prototyping. I believe that Jshell will become a friendly tool for developers on a day to day life. Jshell has a lot of use cases but the best one for me is the ability to quickly test your code without getting into long build cycles.

Read Collection Factory Methods in Java 9  to learn how to create immutable collection in Java 9.

java 8 optional

Java 8 Optional

In this post, we will be talking about  Optional class introduced in Java 8. As a Java developer, You must have faced NullPointerException at least (I have faced it countless time 🙂 ).

NullPointerExceptions are a pain but the truth is you can not avoid it but can add certain checks to make sure we are ready for it when it happens.

A common (bad) practice is to return the null reference to indicate the absence of a given object and which can cause NullPointerException. The Optional class was introduced in Java8 to handle optional values instead of null reference.

1.  Introduction

To explain, Java 8 Optional feature, consider the following structure for a Car having a build in map (navigation) feature.

Car

public class Car {
private GoogleMaps map;
public GoogleMaps getMap() {
return map;
}
public void setMap(GoogleMaps map) {
this.map = map;
}
}

Map

public class GoogleMaps {
private String mapDetails;
public String getMapDetails() {
return mapDetails;
}
public void setMapDetails(String mapDetails) {
this.mapDetails = mapDetails;
}
}

Enable Map

Car car = new Car();
car.getMap().getMapDetails();

Above code looks good but as we know many cars (even new one) don’t have the build in map (navigation) system, so getMapDetails() will throw NullPointerException for all those cars which do not have a built-in navigation system.

As a standard practice is to return a null reference to indicate the absence of an object, for our case getMap() will return a null reference to indicate that Car does not have build in a navigation system. 

 

Let’s use Optional class to enrich the semantics of the above model

public class Car {
private Option<GoogleMaps> map;
public Option<GoogleMaps> getMap() {
return map;
}
public void setMap(Option<GoogleMaps> map) {
this.map = map;
}
}

Based on the above change, Car refers to Optional<GoogleMap> which clearly indicate that GoogleMap is an optional feature for a car. API user of your domain model can easily understand what to expect out from the API.

How to we handle this use case?

2. Use Defensive Check to Handle Null 

In order to handle null pointer reference and to avoid NullPointerException, we will use standard null reference check in our code

public class OptionalTest {
public static void main(String[] args) {
Car car = new Car();
car.getMap().getMapDetails();
}
public static String getMapDetails(final Car car) {
if (car != null) {
GoogleMaps map = car.getMap();
if (map != null) {
return map.getMapDetails();
}
}
return "Unavailable";
}
}

One of the major drawbacks of the above code is that it will become very unreadable due to nested check. All these checks are happening only to avoid NullPointerException and certainly not adding anything to the business logic.

I do not want to get into more details about the other drawbacks of the above code (what if you miss to check the null pointer for any other property).

To summarise, returning a null reference to indicate non-existence of an object or value is not a very good approach and definitely, need some other good alternate.

 

3. Java Optional Class

To handle the absence of object or value in a more graceful way than returning a null reference, java.util.Optional<T> was introduced as a new feature in Java 8.

Optional class provide a way to design better API in which consumer of the API has a better understanding as to what can be expected back from the API.

java.util.Optional<T> is like a container, either container have some object or it is empty (can not be null).In another term think of Optional as a wrapper, if the value is present, the Optional class will wrap that value else it will be empty.

 

4. How to Create Optional Class

There are multiple ways to create Optional objects. We can use empty() method to create empty Optional object

 

Optional With Empty Value
Optional<GoogleMaps> emptyOptional = Optional.empty();

Optional.empty() is a static factory method which returns Singleton object of the optional class (see java source for more details).

 

Optional With  Not Null Value
GoogleMaps googleMaps = new GoogleMaps();
Optional<GoogleMaps> optionalMap= Optional.of(googleMaps);

Keep in mind that argument passed to Optional.of() can not be null, above code will throw NullPointerException if GoogleMaps were null.If we use below code

Optional<GoogleMaps> optionalMap= Optional.of(null);

JRE will throw NPE

Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at com.umeshawasthi.tutorials.corejava.java8.optional.CreateOptionalObject.main(CreateOptionalObject.java:15)
 
Optional With  Not Null

To Create an Optional object for holding a null value, Optional class provide ofNullable() method.

Optional<GoogleMaps> nullGoogleMap = Optional.ofNullable(null);
System.out.println(nullGoogleMap.toString());

Output

Optional.empty

 

The difference between the null reference and empty Optional object is really significant, null reference will cause a NullPointerException whereas Optional.empty is a valid object and we can work on the object without worrying about NPE. 

 

5. Use Optional Value

Once We have an Optional object, we can work with methods provided by the optional object to handle presence or absence of given value.

We can use isPresent() method from Optional class to check if a value exists or not.

Optional<String> optional = Optional.of("umesh");
System.out.println(optional.isPresent());
Optional<String> nullValue= Optional.ofNullable(null);
System.out.println(nullValue.isPresent());

Output


true
false

6. Use get() method

The optional class provides get() method which can be used get value from the Optional object. Keep in mind that get() method will throw NoSuchElementException in case Optional is empty.

Optional<String> nullValue= Optional.ofNullable(null);
System.out.println(nullValue.get());

Output

Exception in thread "main" java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at com.umeshawasthi.tutorials.corejava.java8.optional.CreateOptionalObject.useGet(CreateOptionalObject.java:45)
at com.umeshawasthi.tutorials.corejava.java8.optional.CreateOptionalObject.main(CreateOptionalObject.java:18)

We can use isPresent() method with Optional.get() to handle above exception

Optional<String> nullValue= Optional.ofNullable(null);
if(nullValue.isPresent()) {
System.out.println(nullValue.get());
}

Of the main issue with Optional.get() method is that it violate the main principle of Optional class to avoid or handle such issue (Exceptions). It is not recommended to use get() method and should be avoided in favour of other alternates.

 

7. Use Optional Value

ifPresent() method from Optional API can be used to perform conditional logic.

Optional<String> optional = Optional.of("umesh");
optional.ifPresent(System.out::println);
Optional<String> nullValue= Optional.ofNullable(null);
nullValue.ifPresent(System.out::println);

Without optional, we need to perform a null check before executing our logic, Optional make it easy to handle such use cases and provide a more clean API.

8. Default Value with orElse or orElseGet

A standard way to return default value in case result is null is by using ternary operator similar to 

GoogleMaps map = googleMap !=null ? googleMap : defaultMap;

Using Optional, we can use it’s orElse() method to return the default value in case the Optional object is null.

String name=null;
String value= Optional.ofNullable(name).orElse("Hello");
System.out.println(value);

 

Default value with orElseGet

orElseGet() is almost similar to the orElse() , orElseGet() method takes a Supplier functional interface. It Returns the value if present otherwise invokes other and return the result of that invocation. 

9. Difference Between orElse and orElseGet

To understand the difference, we will run following example.

public class OptionalElseGetExample {
public static void main(String[] args) {
Optional<String> testingOrElse = Optional.of("Testing orElse method");
String finalOutput = testingOrElse.orElse(printHelloWorld());
System.out.println("optional result:: " + finalOutput);
Optional<String> testingOrElseGet = Optional.of("Testing orElse method");
String finalOrElseOutput = testingOrElseGet.orElseGet(() -> printHelloWorld());
System.out.println("optional result:: " + finalOrElseOutput);
}
public static String printHelloWorld() {
System.out.println("Hello World");
return "Say Hello";
}
}

Output


Hello World
orElse Test:: Testing orElse method
orElseGet Test:: Testing orElse method
public class OptionalElseGetExample {
public static void main(String[] args) {
checkOrElseGet();
}
public static void checkOrElseGet() {
Optional<String> testingOrElse = Optional.ofNullable(null);
String finalOutput = testingOrElse.orElse(printHelloWorld());
System.out.println("optional result:: " + finalOutput);
Optional<String> testingOrElseGet = Optional.ofNullable(null);
String finalOrElseOutput = testingOrElseGet.orElseGet(() -> printHelloWorld());
System.out.println("optional result:: " + finalOrElseOutput);
}
public static String printHelloWorld() {
System.out.println("Hello World");
return "Say Hello";
}
}

Output


Hello World
optional result:: Say Hello
Hello World
optional result:: Say Hello

So orElseGet() will execute the function if Optional is empty, while for orElse() will execute function even if Optional is empty.Optional.orElse() can be used to assigning a literal value but we shouldn’t expect a control flow with it.

In above example, this difference might not be very visible but let’s say you are making an expensive DB call or connecting to an external web service, these small differences will make a lot of impacts.

Similarly, you can use the orElseThrow() method, which instead of providing a default value if Optional is empty, throws an exception.

 

10. Filtering Optional using filter method 

Most of the time, we need to call a method on an object and check some property, filter method provided by the Optional object can be used filter out values.

filter method takes a predicate as an argument if the Optional object is present and it matched the predicate, filter method will return the value else empty Optional object will be returned. 

Let’s take at following example, Let’s say we will give 10% off on a product to a customer if the product price is greater than $20 but not more than $50. 

public class Product {
private Double productPrice;
public Product(Double productPrice) {
this.productPrice = productPrice;
}
public Double getProductPrice() {
return productPrice;
}
public void setProductPrice(Double productPrice) {
this.productPrice = productPrice;
}
}
public boolean checkIfEligibleForPromotion(Product product) {
if (product != null && product.getProductPrice() != null
&& product.getProductPrice().doubleValue() > 20.00
&& product.getProductPrice().doubleValue() <= 50) {
return true;
}
return false;
}

We need to write so much of code to accomplish this task, checking price range is part of the business workflow but other conditions are there just to avoid NullPointerException.

We will use Optional.filter() to handle above use case with more clean and better approach.

public boolean checkIfEligibleForPromotionByFilter(Product product) {
return Optional.ofNullable(product).map(Product::getProductPrice)
.filter(productPrice->productPrice >20)
.filter(productPrice->productPrice <=50)
.isPresent();
}

Map method of the Optional class transformed the value inside the Optional Object by the function passed as an argument.

Note following points in the map and filter method

  1. Even if we pass null object is passed, it will not throw any exception.
  2. Above code is cleaner as we just apply a filter to check if the product is eligible for promotion or not.
  3. API is cleaner and do not need an additional null check before executing business logic.

 

11. Transforming values using flatMap method 

Similar to map API, Optional also provides flatMap as another alternate for transforming values. map transforms values only when they are unwrapped whereas flatMap takes a wrapped value and unwraps it before transforming it.

Let’s go back to our original example of Car having Navigation System, in order to get Map from the navigation system, we will do something like

car.getMap().getMapDetails() 

To Summarise, above code extract one object from another object and map method is perfect candidate for it

myCar.map(Car::getMap)
.map(GoogleMaps::getMapDetails)
.orElse("Navigation Not Available");

 

Above code will not work, since map can only transform value when they are unwrapped, here are the details why above code will fail

  1. myCar is of type Optional<Car> and calling map on it will work, however, getMap will return an object of Optional<GoogleMap>.
  2. The result of above process will be of Optional<Optional<GoogleMap>> and getMapDetails() will not work (getMapDetails() is not valid for the outer Optional object)

In order to handle such use cases, Optional supports flatMap() which can take a wrapped value and unwraps it before transforming it.

myCar.flatMap(Car::getMap)
.flatMap(GoogleMaps::getMapDetails)
.orElse("Navigation Not Available");

 

12. Exceptions Vs Optional

Throwing an exception is a common pattern in Java API to return null in case a value is not present. Integet.parseInt(String) will throw NumberFormatException in case supplied argument is invalid. We can use Optional class to handle it in more interesting way (We no longer need to try catch block at each location where we need to parse String to Integer)

public static Optional<Integer> parseInt(String value) {
try {
return Optional.of(Integer.parseInt(value));
} catch (NumberFormatException nfe) {
return Optional.empty();
}
}

Conclusion

In this post, we cover Java 8 Optional API in details along with some of the reasons as to why we should use it and how we can adapt it to our data model for the better API design. We learned how to use Optional class static factory methods like Optional.empty(), Optional.of() to create optional objects.

Do not try to replace every single null reference in your code with Optional as it might lead to other issues, I will use Optional to create better API which can clearly communicate to its user as what to expect from the API.

All the code of this article is available Over on Github. This is a Maven-based project.

References

Optional

Zipping and Unzipping in Java

Zipping and Unzipping in Java

In this post, we will learn Zipping and Unzipping in Java using java.util.zip API. We will also discuss some third party API to perform these tasks. 

1.  Zip a File

We will be performing a simple operation to zip a single file into an archive.

public class ZipSingleFile {
public static void main(String[] args) throws IOException {
String sourceFile = "/Users/umesh/personal/tutorials/source/index.html";
String zipName="/Users/umesh/personal/tutorials/source/testzip.zip";
File targetFile = new File(sourceFile);
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipName));
zipOutputStream.putNextEntry(new ZipEntry(targetFile.getName()));
FileInputStream inputStream = new FileInputStream(targetFile);
final byte[] buffer = new byte[1024];
int length;
while((length = inputStream.read(buffer)) >= 0) {
zipOutputStream.write(buffer, 0, length);
}
zipOutputStream.close();
inputStream.close();
}
}

2.  Zip Multiple Files / Directories Java8

Creating zip for a single file is not very interesting or real life solution, we will be improving our program with an option to zip entire directory using Files.walk method.

public class ZipDirectory {
public static void main(String[] args) throws IOException {
String sourceDirectoryPath = "/Users/umesh/personal/tutorials/source";
String zipFilePath = "/Users/umesh/personal/tutorials/source.zip";
zipDirectory(sourceDirectoryPath, zipFilePath);
}
public static void zipDirectory(String sourceDirectoryPath, String zipPath) throws IOException {
Path zipFilePath = Files.createFile(Paths.get(zipPath));
try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(zipFilePath))) {
Path sourceDirPath = Paths.get(sourceDirectoryPath);
Files.walk(sourceDirPath).filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(sourceDirPath.relativize(path).toString());
try {
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(Files.readAllBytes(path));
zipOutputStream.closeEntry();
} catch (Exception e) {
System.err.println(e);
}
});
}
}
}

 

2.  Zip Multiple Files / Directories Java7

public class ZipDirectoryFilesWalk {
public static void main(String[] args) throws IOException {
Path sourceDirectoryPath = Paths.get("/Users/umesh/personal/tutorials/source");
Path zipFilePath = Paths.get("/Users/umesh/personal/tutorials/source.zip");
zipDirectory(sourceDirectoryPath, zipFilePath);
}
public static void zipDirectory(Path sourceDirectory, Path zipFilePath) throws IOException {
try (FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath.toFile());
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream)
) {
Files.walkFileTree(sourceDirectory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
zipOutputStream.putNextEntry(new ZipEntry(sourceDirectory.relativize(file).toString()));
Files.copy(file, zipOutputStream);
zipOutputStream.closeEntry();
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
zipOutputStream.putNextEntry(new ZipEntry(sourceDirectory.relativize(dir).toString() + "/"));
zipOutputStream.closeEntry();
return FileVisitResult.CONTINUE;
}
});
}
}
}

In the above examples, we saw different options to Zipping Files and Directories in Java using Java7 and Java8.

3. Unzip  Directory

public class UnZipDirectory {
public static void main(String[] args) throws IOException {
String unzipLocation = "/Users/umesh/personal/tutorials/unzip";
String zipFilePath = "/Users/umesh/personal/tutorials/source.zip";
unzip(zipFilePath, unzipLocation);
}
public static void unzip(final String zipFilePath, final String unzipLocation) throws IOException {
if (!(Files.exists(Paths.get(unzipLocation)))) {
Files.createDirectories(Paths.get(unzipLocation));
}
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
ZipEntry entry = zipInputStream.getNextEntry();
while (entry != null) {
Path filePath = Paths.get(unzipLocation, entry.getName());
if (!entry.isDirectory()) {
unzipFiles(zipInputStream, filePath);
} else {
Files.createDirectories(filePath);
}
zipInputStream.closeEntry();
entry = zipInputStream.getNextEntry();
}
}
}
public static void unzipFiles(final ZipInputStream zipInputStream, final Path unzipFilePath) throws IOException {
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(unzipFilePath.toAbsolutePath().toString()))) {
byte[] bytesIn = new byte[1024];
int read = 0;
while ((read = zipInputStream.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
}
}
}

In this post, we learned as to how to zip and unzip files or directory using core Java features. Read our articles List all files from a directory in Java to learn how to recursively transverse folders to zip multiple files.

If you want more sophisticated API to perform other operation on the zip files, you can check following open source libraries

  1. zt-zip
  2. zip4j

All the code of this article is available Over on Github. This is a Maven-based project.

Collection Factory Methods in Java 9

Collection Factory Methods in Java 9

In this post, we will explore Collection Factory Methods in Java 9. Java 9 introduced a new Convenience Factory Methods for Collections.

 

Introduction

Creating a new unmodifiable list in Java (before Java 9) is not very clean. Creating a small immutable collection in Java involves following steps

  1. Create collection.
  2. Add objects to Collection (e.g Map)
  3. Wrap it using unmodifiableXXX()  method provided under java.util.Collections class.

To create a unmodifiable map in Java8 

 

public class ImmutableCollection {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("one");
set.add("two");
set.add("three");
Set<String> immutableSet = Collections.unmodifiableSet(set);
}
}

Above code is definitely not very clean and concise, another option to create unmodifiable set are

public class ImmutableMap {
public static void main(String[] args) {
Set<String> immutableSet = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("one", "two","three")));
}
}

Above code is a little cleaner but have following issues

  1. We need to create List before creating Set (extra Overhead).

 

Double Brace Initialization

We have the option to use double brace initialization for creating unmodifiable collection (Set in our example)

public class ImmutableCollectionDoubleBrace {
public static void main(String[] args) {
Set<String> immutableSet = Collections.unmodifiableSet(new HashSet<>() {{
add("one");
add("two");
add("three");
}});
}
}

Above option also have multiple issues

  1. It will create an extra class with each usage.
  2. It contains references to the enclosing instance.

 

Java8 Stream API

Java8 Stream API can also be used to create a unmodifiable collection.

public class ImmutableCollectionStream {
public static void main(String[] args) {
Set<String> unmodifiableSet= Collections.unmodifiableSet(Stream.of("one","two","three").collect(Collectors.toSet()));
}
}

Java 8 Stream API also have some issue and not a very clean solution to create a unmodifiable collection, additionally stream API involve unnecessary object creation along with some extra calculations.

 

Unmodifiable Collections in Java 9

Collection Factory Methods are introduced in Java 9 like Scala (not same 🙂 ). Static methods have been provided by Java 9 on List, Set and Map interfaces which can easily returned unmodifiable collections by calling of() method of the respective interface.

 

List

public class Java9ImmutableList {
public static void main(String[] args) {
List<String> immutableList= List.of("1","2","3");
}
}

Set

public class Java9ImmutableSet {
public static void main(String[] args) {
Set<String> immutableMap = Set.of("one","two","three");
}
}

Map

public class Java9ImmutableMap {
public static void main(String[] args) {
Map<String, Integer> immutableMap = Map.of("one",1, "two", 2);
}
}

Please note that Map.of() works with key and value pairs up to 10 entries. Beyond that, we need to use in a var-args of Entry instances and use Map.ofEntries()

public static void useMapEntries(){
Map<String, Integer> map = Map.ofEntries(
Map.entry("one", 1),
Map.entry("two", 2),
Map.entry("three", 3)
);
}

Since every var-args method implicitly creates an array and to avoid performance issue, Java language team included 12 overloaded implementations for of factory method for each collection type.

static <E> Set<E> of() 
static <E> Set<E> of(E e1) 
static <E> Set<E> of(E e1, E e2) 
static <E> Set<E> of(E e1, E e2, E e3) 
.....

 

Null Element in Collection

Both List and Set will not allow adding a null element, Map does not allow null either as a key or value. If you will try to add a null element, JDK will throw NullPointerException.

public class NPEExample {
public static void main(String[] args) {
List<String> immutableList = List.of("one", null);
}
}

 

Output

Exception in thread "main" java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at java.base/java.util.ImmutableCollections$List2.<init>(ImmutableCollections.java:185)
at java.base/java.util.List.of(List.java:822)
at java/com.umeshawasthi.java9.example.NPEExample.main(NPEExample.java:9)

The introduction of Collection Factory Methods in Java 9 is one of the useful features and will be useful in day to day programming. I have covered feature of Collection Factory method along with some internal details. 

It is, of course, not nearly as convenient as Scala but I believe It’s a very welcome change in Java 9.

 

All the code of this article is available Over on Github. This is a Maven-based project.

References

JEP 269

Java nio2

Introduction to Java NIO2

This post is aiming to provide a high-level overview of the Java NIO2 API features. Java7 introduced a rich set of features to operators on the Files using Java NIO2 package.

In this post, we will learn about some of the basic features introduced by Java Nio2. The java.nio.file package provides a comprehensive support to work on the file IO. Files class is one of the main utility class provided by NIO package which provides a rich set of functionality to work on the underlying filesystem with help of Path class.

 

1.  Basics

In order to use Files or Path class, all we need to import java.io.file.* in our program, all major classes are defined within the java.io.file package.

Please read Java NIO Path to get understanding how Path class work in the new Java NIO2 package.

 

2. Checking a File or Directory

Java NIO package’s Files and Path API can be used to easily determine if a given path exists or not by utilising exists and notExists method provided by Files class.

public static void checkIfFileDirExist(final Path location){
System.out.println(Files.exists(location));
}
public static void checkIfFileDirNotExist(final Path location){
System.out.println(Files.notExists(location));
}

 

Please be aware Files.notExists work for both Files and Directories, so refer to both files and directory when I am talking about files in this post.  

 

3. Checking  File Accessibility

Java NIO2 package also provide way to check if given programme can access a file needed or do we have required permission to perform given file operation. Files utility class provide following method to check accessibility.

  1. isReadable(Path)
  2. isWritable(Path)
  3. isRegularFile (Path)
  4. isExecutable (Path)

 

   public static void checkIfReadable(final Path location)
{
System.out.println(Files.isReadable(location));
}
public static void checkIfWritable(final Path location)
{
System.out.println(Files.isWritable(location));
}

 

A regular file is a file which is not special, in case file contains any symbolic links to similar properties, this will not be treated a regular file.

If you want to check if both Path objects are same or pointing to the same location, we can use isSameFile(Path path1, Path path2).

 

4. Creating Files

Files class provide an easy way to create the file using NIO. Please read How to write to file in Java for more details.

 

5. Creating Directory

Read How to create directory in Java to learn various options available under Java 7 NIO.

 

6.  Delete directory in Java

You can delete files, directories or links, please read Deleting Directory in Java to understand how we can use walkFileTree to recursively delete directories and files using Files NIO.

 

7.  Move Directory / Files  in Java

Java NIO provides an easy way to move files or directories using API’s move method. You can also copy files and directories recursively using the fileWalker method. Please read  How to Move a File in Java.

 

8. Copying a File or Directory

Copy a file or directory in Java is a common operation. Java NIO Files class provide a convenient copy method to copy file or directory. If you want to copy files from one directory to another in Java including subdirectories, you have to use Files.walkFileTree from NIO Java7 approach to recursively copy directory and all files to another location.

Please read Copy a File or Directory in Java to see how to use FileVisitor to recursively copy files and directories. 

 

In this post, we saw of the core features introduced as part of the Java NIO2 introduced with JDK7 along with some of the important operation being supported by NIO2 API.

 

All the code of this article is available Over on Github. This is a Maven-based project.