Difference between Setter vs Constructor Injection in Spring

Spring Setter vs Constructor Injection

Spring supports two types of dependency Injection, using setter method e.g. setXXX() where XXX is a dependency or via a constructor argument. The first way of dependency injection is known as setter injection while later is known as constructor injection. Both approaches of Injecting dependency on Spring bean has there pros and cons, which we will see in this Spring framework article. The difference between Setter Injection and Constructor Injection in Spring is also a popular Spring framework interview question.Some time interviewer also asks as When do you use Setter Injection over Constructor injection in Spring or simply benefits of using setter vs constructor injection in Spring framework. Points discussed in this article not only help you to understand Setter vs Constructor Injection but also Spring’s dependency Injection process.

By the way, if you are new in Spring framework and learning it, you may want to take a look at my list of 5 good books to learn Spring framework. That will certainly help in  your learning process. Since Spring is now a must have skill for Java programmers, it worth putting time and effort to learn this powerful framework

Difference between Setter and Constructor Injection in Spring framework

As I said earlier Spring supports both setter and constructor Injection which are two standard way of injecting dependency on beans managed by IOC constructor. Spring framework doesn’t support Interface Injection on which dependency is injected by implementing a particular interface. In this section we will see a couple of difference between setter and constructor Injection, which will help you decide when to use setter Injection over constructor Injection in Spring and vice-versa.

1) The fundamental difference between setter and constructor injection, as their name implies is How dependency is injected.  Setter injection in Spring uses setter methods like setDependency() to inject dependency on any bean managed by Spring’s IOC container. On the other hand constructor injection uses constructor to inject dependency on any Spring-managed bean.
2) Because of using setter method, setter Injection in more readable than constructor injection in Spring configuration file usually applicationContext.xml . Since setter method has name e.g. setReporotService() by reading Spring XML config file you know which dependency you are setting. While in constructor injection, since it uses an index to inject the dependency, it’s not as readable as setter injection and you need to refer either Java documentation or code to find which index corresponds to which property.
3) Another difference between setter vs constructor injection in Spring and one of the drawback of  setter injection is that it does not ensures dependency Injection. You can not guarantee that certain dependency is injected or not, which means you may have an object with incomplete dependency. On other hand constructor Injection does not allow you to construct object, until your dependencies are ready.
4) One more drawback of setter Injection is Security. By using setter injection, you can override certain dependency which is not possible which is not possible with constructor injection because every time you call the constructor, a new object is gets created.

5) One of our reader Murali Mohan Reddy pointed out one more difference between Setter and Constructor injection in Spring, where later can help if there is a circular dependency between two object A and B.
If Object A and B are dependent each other i.e A is depends ob B and vice-versa. Spring throws ObjectCurrentlyInCreationException while creating objects of A and B bcz A object cannot be created until B is created and vice-versa. So spring can resolve circular dependencies through setter-injection. Objects constructed before setter methods invoked.
See comment section for more inputs from other readers.

When to use Setter Injection over Constructor Injection in Spring

Setter Injection has upper hand over Constructor Injection in terms of readability. Since for configuring Spring we use XML files, readability is much bigger concern. Also drawback of setter Injection around ensuring mandatory dependency injected or not can be handled by configuring Spring to check dependency using “dependency-check” attribute of  tag or tag. Another worth noting point to remember while comparing Setter Injection vs Constructor Injection is that, once number of dependency crossed a threshold e.g. 5 or 6 its handy manageable to passing dependency via constructor. Setter Injection is preferred choice when number of dependency to be injected is lot more than normal, if some of those arguments is optional than using Builder design pattern is also a good option.
In Summary, both Setter Injection and Constructor Injection has there own advantage and disadvantage. The good thing about Spring is that it doesn’t restrict you to use either Setter Injection or Constructor Injection and you are free to use both of them in one Spring configuration file. Use Setter injection when a number of dependencies are more or you need readability. Use Constructor Injection when Object must be created with all of its dependency.

 

Spring Security Example Tutorial – How to limit number of User Session in Java

Spring security can limit number of session a user can have. If you are developing web application specially secure web application in Java J2EE then you must have come up with requirement similar to online banking portals have e.g. only one session per user at a time or no concurrent session per user. You can also implement this functionality without using spring security but with Spring security its just piece of cake with coffee :). Spring Security provides lots of Out of Box functionality a secure enterprise or web application needed like authentication, authorization, session management, password encoding, secure access, session timeout etc. In our spring security example we have seen how to do LDAP Authentication in Active directory using spring security and in this spring security example we will see how to limit number of session user can have in Java web application or restricting concurrent user session.

Spring Security Example: Limit Number of User Session

As I said it’s simple and easy when you use spring security framework or library. In fact is all declarative and no code is require to enable concurrent session disable functionality. You will need to include following xml snippet in your Spring Security Configuration file mostly named as applicaContext-security.xml. Here is sample spring security Example of limiting user session in Java web application:

<session-management invalid-session-url="/logout.html">
    <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>

As you see you can specify how many concurrent session per user is allowed, most secure system like online banking portals allow just one authenticate session per user. You can even specify a URL where user will be taken if they submit an invalid session identifier can be used to detect session timeout. Session-management element is used to capture session related stuff. Max-session specify how many concurrent authenticated session is allowed and if error-if-maximum-exceeded set to true it will flag error if user tries to login into another session.

Dependency

This code has dependency on spring-security framework. You need to download spring security jar like spring-security-web-3.1.0.jar and add into application classpath.

This simple example of spring security shows power of spring security, a small piece of xml snippet can add very useful and handy security feature in your Java web application. I recommend using spring security for your new or existing Java web application created using Servlet JSP.

That’s all on how to limit number of user session using spring security in Java web application. Let me know if you face any issue while implementing this security feature in your project.

 

10 Object Oriented Design Principles Java Programmer should know

Object Oriented Design Principles are core of OOP programming, but I have seen most of the Java programmers chasing design patterns like Singleton pattern, Decorator pattern or Observer pattern, and not putting enough attention on learning Object oriented analysis and design. It’s important to learn basics of Object oriented programming like Abstraction, Encapsulation, Polymorphism and Inheritance. But, at the same time, it’s equally important to know object oriented design principles, to create clean and modular design. I have regularly seen Java programmers and developers of various experience level, who either doesn’t heard about these OOP and SOLID design principle, or simply doesn’t know what benefits a particular design principle offers, or how to apply these design principle in coding.

Bottom line is, always strive for highly cohesive and loosely couple solution, code or design. Looking open source code from Apache and Sun are good examples of learning Java and OOPS design principles. They show us,  how design principles should be used in coding and Java programs. Java Development Kit follows several design principle like Factory Pattern in BorderFactory class,  Singleton pattern in Runtime class, Decorator pattern on various java.io classes. By the way if you really interested more on Java coding practices then read Effective Java by Joshua Bloch , a gem by the guy who wrote Java Collection API.

If you are interested in learning object oriented principles and patterns, then you can look at my another personal favorite Head First Object Oriented Analysis and Design. This an excellent book and probably the best material available in object oriented analysis and design, but it often shadowed by its more popular cousin Head First Design Pattern by Eric Freeman. Later is more about how these principle comes together to create pattern you can use directly to solve known problems. These books helps a lot to write better code, taking full advantage of various Object oriented and SOLID design principles.

Though best way of learning any design principle or pattern is real world example and understanding the consequences of violating that design principle, subject of this article is Introducing Object oriented design principles for Java Programmers, who are either not exposed to it or in learning phase. I personally think each of these OOPS and SOLID design principle need an article to explain them clearly, and I will definitely try to do that here, but for now just get yourself ready for quick bike ride on design principle town 🙂

DRY (Don’t repeat yourself)

Our first object oriented design principle is DRY, as name suggest DRY (don’t repeat yourself) means don’t write duplicate code, instead use Abstraction to abstract common things in one place. If you have block of code in more than two place consider making it a separate method, or if you use a hard-coded value more than one time make them public final constant. Benefit of this Object oriented design principle is in maintenance. It’s important  not to abuse it, duplication is not for code, but for functionality . It means, if you used common code to validate OrderID and SSN it doesn’t mean they are same or they will remain same in future. By using common code for two different functionality or thing you closely couple them forever and when your OrderID changes its format , your SSN validation code will break. So beware of such coupling and just don’t combine anything which uses similar code but are not related.

Encapsulate What Changes

Only one thing is constant in software field and that is “Change”, So encapsulate the code you expect or suspect to be changed in future. Benefit of this OOPS Design principle is that Its easy to test and maintain proper encapsulated code. If you are coding in Java then follow principle of making variable and methods private by default and increasing access step by step e.g. from private to protected and not public. Several of design pattern in Java uses Encapsulation, Factory design pattern is one example of Encapsulation which encapsulate object creation code and provides flexibility to introduce new product later with no impact on existing code.

Open Closed Design Principle

Classes, methods or functions should be Open for extension (new functionality) and Closed for modification. This is another beautiful SOLID design principle, which prevents some-one from changing already tried and tested code. Ideally if you are adding new functionality only than your code should be tested and that’s the goal of Open Closed Design principle. By the way, Open Closed principle is “O” from SOLID acronym.

Single Responsibility Principle (SRP)

Single Responsibility Principle is another SOLID design principle, and represent  “S” on SOLID acronym. As per SRP, there should not be more than one reason for a class to change, or a class should always handle single functionality. If you put more than one functionality in one Class in Java  it introduce coupling between two functionality and even if you change one functionality there is chance you broke coupled functionality,  which require another round of testing to avoid any surprise on production environment.

Dependency Injection or Inversion principle

Don’t ask for dependency it will be provided to you by framework. This has been very well implemented in Spring framework, beauty of this design principle is that any class which is injected by DI framework is easy to test with mock object and easier to maintain because object creation code is centralized in framework and client code is not littered with that.There are multiple ways to  implemented Dependency injection like using  byte code instrumentation which some AOP (Aspect Oriented programming) framework like AspectJ does or by using proxies just like used in Spring. See this example of IOC and DI design pattern to learn more about this SOLID design principle. It represent “D” on SOLID acronym.

Favor Composition over Inheritance

Always favor composition over inheritance ,if possible. Some of you may argue this, but I found that Composition is lot more flexible than Inheritance. Composition allows to change behavior of a class at run-time by setting property during run-time and by using Interfaces to compose a class we use polymorphism which provides flexibility of to replace with better implementation any time. Even Effective Java advise to favor composition over inheritance. See here to learn more about why you Composition is better than Inheritance for reusing code and functionality.

Liskov Substitution Principle (LSP)

According to Liskov Substitution Principle, Subtypes must be substitutable for super type i.e. methods or functions which uses super class type must be able to work with object of sub class without any issue”. LSP is closely related to Single responsibility principle and Interface Segregation Principle. If a class has more functionality than subclass might not support some of the functionality ,and does violated LSP. In order to follow LSP SOLID design principle, derived class or sub class must enhance functionality, but not reduce them. LSP represent  “L” on SOLID acronym.

Interface Segregation principle (ISP)

Interface Segregation Principle stats that, a client should not implement an interface, if it doesn’t use that. This happens mostly when one interface contains more than one functionality, and client only need one functionality and not other.Interface design is tricky job because once you release your interface you can not change it without breaking all implementation. Another benefit of this design principle in Java is, interface has disadvantage to implement all method before any class can use it so having single functionality means less method to implement.

 

Programming for Interface not implementation

Always program for interface and not for implementation this will lead to flexible code which can work with any new implementation of interface. So use interface type on variables, return types of method or argument type of methods in Java. This has been advised by many Java programmer including in Effective Java and Head First design pattern book.

Delegation principle

Don’t do all stuff  by yourself,  delegate it to respective class. Classical example of delegation design principle is equals() and hashCode() method in Java. In order to compare two object for equality we ask class itself to do comparison instead of Client class doing that check. Benefit of this design principle is no duplication of code and pretty easy to modify behavior.
Here is nice summary of all these OOP design principles :

All these object oriented design principle helps you write flexible and better code by striving high cohesion and low coupling. Theory is first step, but what is most important is to develop ability to find out when to apply these design principle. Find out, whether we are violating any design principle and compromising flexibility of code, but again as nothing is perfect in this world, don’t always try to solve problem with design patterns and design principle they are mostly for large enterprise project which has longer maintenance cycle.

Stopping Your Class from Being Inherited in Java, the Official Way and the Unofficial Way

The Official Way

Officially, the Java language provides the keyword ‘final’ that is supposed to fulfill this task. Consider the following code sample:

//FinalDemo.java
public final class FinalDemo {

}

Let’s make another class that is supposed to be inherited from the above class. The Java language provides the ‘extends’ keyword that enables a class to be inherited from an existing class.

//FinalDemo2.java
public class FinalDemo2 extends FinalDemo {

}

After compiling the first class, if you compile the second class, the JDK compiler will complain and you will get following error message:

FinalDemo2.java:1: cannot inherit from final FinalDemo
public class FinalDemo2 extends FinalDemo{}
                                ^
1 error

You have stopped your first class from being inherited by another class, the official way.

The Unofficial Way

But, that’s not the only way to stop your class from being inherited by some other class. Consider the following code where I declare the constructor as private, and I declare a static method that returns an object of the class:

public class PrivateTest{
        private PrivateTest(){
                System.out.println("Private Default Constructor");
        }
        public static PrivateTest getInstance(){
                return new PrivateTest();
        }

}

A modified form of the above code is also known as the “Singleton Pattern,” where the getInstance method always returns only one instance of the class. But why does this code stop this class from being inherited? Consider the following code that is supposed to be inherited from the above class:

public class PrivateTest2 extends PrivateTest{


}

After compiling the first class, if you compile the second class, the JDK compiler will complain and you will get the following error message:

PrivateTest2.java:1: PrivateTest() has private access in PrivateTest
public class PrivateTest2 extends PrivateTest{
       ^
1 error

The second class is unable to inherit the first class. But what does this error mean? The Java language makes it compulsory to provide at least one constructor in your class. If you do not provide any constructor in your class, the JDK compiler will insert the so-called default constructor in your class; in other words, that constructor with no arguments, with an empty body, and with a public access modifier. But if you define a constructor by yourself, the JDK compiler will not insert a default constructor for you. What we did in class PrivateTest was that we declared the default constructor, but we changed the access modifier to private, which is legal by the rules of JDK compiler.

Now comes the second part. The Java language also makes it compulsory that you put the call to the super class constructor as the first call in your constructor. This is necessary to enable the inheritance features. We achieve this functionality by calling the appropriate super() method in Java, that should map to appropriate super class constructor. If you do not provide a default constructor, than JDK compiler will insert a default super constructor call in your constructor.

What I did in the first class that I make the constructor private. Now, when I inherit that class in the other class, the compiler tries to put in the default super constructor call. Because the scope of the super class constructor is set to private, the compiler complains that it is unable to call the super constructor. Hence, we stopped a class being inherited by some other class, the unofficial way.

11 Mistakes JAVA Developers make when using EXCEPTIONS

The problem: If you use Exceptions in the wrong way, bugs will be very difficult to find. If you always use generic Exceptions, how can other developers know what error has occurred? You have to understand why we use Exceptions and how to use them effectively!

See the 11 mistakes Java Developers make when using Exceptions.

First, let’s see the hierarchy of the Exception classes.

Checked Exceptions / Unchecked Exceptions

1 – Using only the Exception class

It’s a common mistake that developers specifically catch the Exception class for any error. It’s much more difficult to identify the error if you see only an Exception being caught. The solution to this problem is to create specific Exceptions – but watch out, not too specific!

2 – Creating lots of specific Exceptions

Don’t create Exceptions for everything. Your application will be full of classes, useless repetition and you will create unnecessary work. Instead, create Exceptions for really important business requirements. For example, if you are developing a bank system one possible Exception would be when trying to withdraw money and the balance is zero: BalanceNotAvailableException. Another Exception would be transferring money to another person and the account does not exist, you can create: BankAccountNotFoundException and show an understandable Exception message to the user.

RuntimeException could be used when the bank’s server is out of service. Here you can use, for example: ServerNotAvailableException. The system must crash for this kind of error. There is no recovery.

3 – Creating a log for every catch

Logging every Exception catch will pollute your code. To prevent this, just log once and throw your Exception in the last catch. You won’t lose your Stacktrace if you wrap the Exception. If you are working with web applications, you should create a catch on your controller layer and log the error.

4 – Not knowing the difference between Checked and Unchecked Exceptions

When should Checked Exceptions be used? Use Checked when there is a recoverable error or an important business requirement.

The most common Checked Exception is the Exception class. Two related classes from Exception are FileNotFoundException and SQLException.You are obligated to handle or declare these exceptions. You must throw or catch the Exception or else it won’t compile.

When should Unchecked Exceptions be used? Use Unchecked when there is no recovery. For example, when the memory of the server is overused.

RuntimeException is used for errors when your application can not recover. For example, NullPointerException and ArrayOutOfBoundsException. You can avoid a RuntimeException with an ‘if’ command. You should not handle or catch it.

There is also the class Error. It is an Unchecked Exception too. Never try to catch or handle this kind of Exception. They are errors from the JVM and are the most serious kind of Exception in Java. You must analyze the cause of Exceptions like this and change your code.

5 –  Silencing Exceptions

Never catch the Exception and do nothing, for example:

1
2
3
4
5
try {
    System.out.println("Never do that!");
} catch (AnyException exception) {
    // Do nothing
}

The catch will be useless. It’s impossible to know what happened and the Exception will be silenced. The developer will be obliged to debug the code and see what happened. If we create a good log, the time-consuming analysis won’t be necessary.

6 – Not following the principle “throw early, catch late”

If you have to handle Exception, for example, in your Service, you should do two things:

  1. Wrap your Exception
  2. Throw the Exception to the last catch and handle it.

7 – Not using clear messages on the Exceptions

Always use clear messages on your Exceptions. Doing this will help a lot when finding errors. Even better, create a Properties File with all Exception messages. You can use the file on your View layer and show users messages about the business requirements.

8- Not cleaning up after handling the Exception

After using resources like files and database connection, clean them and close them so that you won’t harm the system’s performance. You can use the finally block to do it.

9 – Not documenting Exceptions with javadoc

To avoid headaches, always Document why the Exception is being thrown in your method. Document your Exception and explain why you created it.

10 – Never lose the Stacktrace

When wrapping an Exception in another one, don’t just throw the other Exception, keep the Stacktrace.

Bad code:

1
2
3
4
5
try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException();
}

Good code:

1
2
3
4
5
try {
    // Do the logic
} catch (BankAccountNotFoundException exception) {
    throw new BusinessException(exception);
}

11 – Not organizing the hierarchy of specific Exceptions

If you don’t organize the hierarchy of your Exceptions, the relationship will be difficult between the parts of the system. You will have lots of problems.

You should use an hierarchy similar to this one:

Exception

BusinessException

AccountingException

HumanResourcesException
BillingCodeNotFoundException

  EmployeeNotFoundException

Different between session.get() and session.load()

Often times, you will notice Hibernate developers mix use of session.get() and session load(), do you wonder what’s the different and when you should use either of it?

Different between session.get() and session.load()

Drawing3

Actually, both functions are use to retrieve an object with different mechanism, of course.

1. session.load()

  • It will always return a “proxy” (Hibernate term) without hitting the database. In Hibernate, proxy is an object with the given identifier value, its properties are not initialized yet, it just look like a temporary fake object.
  • If no row found , it will throws an ObjectNotFoundException.

2. session.get()

  • It always hit the database and return the real object, an object that represent the database row, not proxy.
  • If no row found , it return null.

It’s about performance

Hibernate create anything for some reasons, when you do the association, it’s normal to obtain retrieve an object (persistent instance) from database and assign it as a reference to another object, just to maintain the relationship. Let’s go through some examples to understand in what situation you should use session.load().

1. session.get()

For example, in a Stock application , Stock and StockTransactions should have a “one-to-many” relationship, when you want to save a stock transaction, it’s common to declared something like below

Stock stock = (Stock)session.get(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

Output

Hibernate:
    select ... from mkyong.stock stock0_
    where stock0_.STOCK_ID=?
Hibernate:
    insert into mkyong.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)

In session.get(), Hibernate will hit the database to retrieve the Stock object and put it as a reference to StockTransaction. However, this save process is extremely high demand, there may be thousand or million transactions per hour, do you think is this necessary to hit the database to retrieve the Stock object everything save a stock transaction record? After all you just need the Stock’s Id as a reference to StockTransaction.

2. session.load()

In above scenario, session.load() will be your good solution, let’s see the example,

Stock stock = (Stock)session.load(Stock.class, new Integer(2));
           StockTransaction stockTransactions = new StockTransaction();
           //set stockTransactions detail
           stockTransactions.setStock(stock);
           session.save(stockTransactions);

Output

Hibernate:
    insert into mkyong.stock_transaction (...)
    values (?, ?, ?, ?, ?, ?)

In session.load(), Hibernate will not hit the database (no select statement in output) to retrieve the Stock object, it will return a Stock proxy object – a fake object with given identify value. In this scenario, a proxy object is enough for to save a stock transaction record.

Exception

In exception case, see the examples

session.load()

Stock stock = (Stock)session.load(Stock.class, new Integer(100)); //proxy

 //initialize proxy, no row for id 100, throw ObjectNotFoundException
System.out.println(stock.getStockCode());

It will always return a proxy object with the given identity value, even the identity value is not exists in database. However, when you try to initialize a proxy by retrieve it’s properties from database, it will hit the database with select statement. If no row is found, a ObjectNotFoundException will throw.

org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.mkyong.common.Stock#100]

session.get()

//return null if not found
Stock stock = (Stock)session.get(Stock.class, new Integer(100));
System.out.println(stock.getStockCode()); //java.lang.NullPointerException

It will always return null , if the identity value is not found in database.

Conclusion

There are no always correct solution, you have to understand the differential in between, and decide which method is best fix in your application.

Java NIO vs. IO

When should I use IO and when should I use NIO?

In this text I will try to shed some light on the differences between Java NIO and IO, their use cases, and how they affect the design of your code

Main Differences Betwen Java NIO and IO

The table below summarizes the main differences between Java NIO and IO. I will get into more detail about each difference in the sections following the table.

IO NIO
Stream oriented Buffer oriented
Blocking IO Non blocking IO
Selectors

Stream Oriented vs. Buffer Oriented

The first big difference between Java NIO and IO is that IO is stream oriented, where NIO is buffer oriented. So, what does that mean?

Java IO being stream oriented means that you read one or more bytes at a time, from a stream. What you do with the read bytes is up to you. They are not cached anywhere. Furthermore, you cannot move forth and back in the data in a stream. If you need to move forth and back in the data read from a stream, you will need to cache it in a buffer first.

Java NIO’s buffer oriented approach is slightly different. Data is read into a buffer from which it is later processed. You can move forth and back in the buffer as you need to. This gives you a bit more flexibility during processing. However, you also need to check if the buffer contains all the data you need in order to fully process it. And, you need to make sure that when reading more data into the buffer, you do not overwrite data in the buffer you have not yet processed.

Blocking vs. Non-blocking IO

Java IO’s various streams are blocking. That means, that when a thread invokes a read() or write(), that thread is blocked until there is some data to read, or the data is fully written. The thread can do nothing else in the meantime.

Java NIO’s non-blocking mode enables a thread to request reading data from a channel, and only get what is currently available, or nothing at all, if no data is currently available. Rather than remain blocked until data becomes available for reading, the thread can go on with something else.

The same is true for non-blocking writing. A thread can request that some data be written to a channel, but not wait for it to be fully written. The thread can then go on and do something else in the mean time.

What threads spend their idle time on when not blocked in IO calls, is usually performing IO on other channels in the meantime. That is, a single thread can now manage multiple channels of input and output.

Selectors

Java NIO’s selectors allow a single thread to monitor multiple channels of input. You can register multiple channels with a selector, then use a single thread to “select” the channels that have input available for processing, or select the channels that are ready for writing. This selector mechanism makes it easy for a single thread to manage multiple channels.

How NIO and IO Influences Application Design

Whether you choose NIO or IO as your IO toolkit may impact the following aspects of your application design:

  1. The API calls to the NIO or IO classes.
  2. The processing of data.
  3. The number of thread used to process the data.

 

The API Calls

Of course the API calls when using NIO look different than when using IO. This is no surprise. Rather than just read the data byte for byte from e.g. an InputStream, the data must first be read into a buffer, and then be processed from there.

The Processing of Data

The processing of the data is also affected when using a pure NIO design, vs. an IO design.

In an IO design you read the data byte for byte from an InputStream or a Reader. Imagine you were processing a stream of line based textual data. For instance:

Name: Anna
Age: 25
Email: anna@mailserver.com
Phone: 1234567890

This stream of text lines could be processed like this:

InputStream input = ... ; // get the InputStream from the client socket

BufferedReader reader = new BufferedReader(new InputStreamReader(input));

String nameLine   = reader.readLine();
String ageLine    = reader.readLine();
String emailLine  = reader.readLine();
String phoneLine  = reader.readLine();

Notice how the processing state is determined by how far the program has executed. In other words, once the first reader.readLine() method returns, you know for sure that a full line of text has been read. The readLine() blocks until a full line is read, that’s why. You also know that this line contains the name. Similarly, when the second readLine() call returns, you know that this line contains the age etc.

As you can see, the program progresses only when there is new data to read, and for each step you know what that data is. Once the executing thread have progressed past reading a certain piece of data in the code, the thread is not going backwards in the data (mostly not). This principle is also illustrated in this diagram:

nio-vs-io-1
Java IO: Reading data from a blocking stream.

A NIO implementation would look different. Here is a simplified example:

ByteBuffer buffer = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buffer);

Notice the second line which reads bytes from the channel into the ByteBuffer. When that method call returns you don’t know if all the data you need is inside the buffer. All you know is that the buffer contains some bytes. This makes processing somewhat harder.

Imagine if, after the first read(buffer) call, that all what was read into the buffer was half a line. For instance, “Name: An”. Can you process that data? Not really. You need to wait until at leas a full line of data has been into the buffer, before it makes sense to process any of the data at all.

So how do you know if the buffer contains enough data for it to make sense to be processed? Well, you don’t. The only way to find out, is to look at the data in the buffer. The result is, that you may have to inspect the data in the buffer several times before you know if all the data is inthere. This is both inefficient, and can become messy in terms of program design. For instance:

ByteBuffer buffer = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buffer);

while(! bufferFull(bytesRead) ) {
    bytesRead = inChannel.read(buffer);
}

The bufferFull() method has to keep track of how much data is read into the buffer, and return either true or false, depending on whether the buffer is full. In other words, if the buffer is ready for processing, it is considered full.

The bufferFull() method scans through the buffer, but must leave the buffer in the same state as before the bufferFull() method was called. If not, the next data read into the buffer might not be read in at the correct location. This is not impossible, but it is yet another issue to watch out for.

If the buffer is full, it can be processed. If it is not full, you might be able to partially process whatever data is there, if that makes sense in your particular case. In many cases it doesn’t.

The is-data-in-buffer-ready loop is illustrated in this diagram:

nio-vs-io-2
Java NIO: Reading data from a channel until all needed data is in buffer.

 

Summary

NIO allows you to manage multiple channels (network connections or files) using only a single (or few) threads, but the cost is that parsing the data might be somewhat more complicated than when reading data from a blocking stream.

If you need to manage thousands of open connections simultanously, which each only send a little data, for instance a chat server, implementing the server in NIO is probably an advantage. Similarly, if you need to keep a lot of open connections to other computers, e.g. in a P2P network, using a single thread to manage all of your outbound connections might be an advantage. This one thread, multiple connections design is illustrated in this diagram:

nio-vs-io-3
Java NIO: A single thread managing multiple connections.

If you have fewer connections with very high bandwidth, sending a lot of data at a time, perhaps a classic IO server implementation might be the best fit. This diagram illustrates a classic IO server design:

nio-vs-io-4
Java IO: A classic IO server design – one connection handled by one thread.