Showing posts with label Java Tutorials. Show all posts
Showing posts with label Java Tutorials. Show all posts

Thursday, 12 November 2015

Understanding p-namespace and c-namespace in Spring


Background

 In one of the previous post on Spring Dependency Injection we saw how beans are created. We also saw c namespace and how to use it.

  1. For values as dependency (like simple String) you can do <property name="brand" value="MRF"/> or <property name="bat" ref="myBat"/>
  2. Instead of using property tag you can also use p namespace - <bean id="cricket" class="Cricket" p:brand="MRF" p:bat-ref="myBat" />  (don't forget to add the namespace)
  3. Also note p namespace does not have any schema reference. 

Entire Spring configuration bean looks like -

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:p="http://www.springframework.org/schema/p"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="cricket" class="com.osfg.Cricket" p:brand="MRF" p:bat-ref="myBat" />

</beans>


In this post we will see what c name space is and how to use it.

Spring 3.1 Constructor Namespace  

As you already know by now you can do dependency injection by setters or by constructor - setter injection and constructor injection.

Let's see a simple  example of constructor based dependency injection.

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="cricket" class="com.osfg.Cricket">
    <constructor-arg value="MRF"/>
    <constructor-arg ref="myBat"/>
  </bean>

</beans>

NOTE : The <constructor-arg> tag could take type and index to reduce ambiguity, but not name.

You can simplify above xml using c namespace

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:c="http://www.springframework.org/schema/c"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="cricket" class="com.osfg.Cricket"
    c:brand="MRF"
    c:ref-bat="myBat"/>

</beans>

NOTE : Both the “p” ad “c” namespaces do not have a schema reference in the XML header.

Related Links

Sunday, 1 November 2015

Spring dependency injection using annotation based Autowiring

Background



In last post you would have seen what dependency injection is and how is it generally achieved in Spring. It is done using beans that you define in you xml file using tags bean , constructor-arg and property.

But as your project size grows it becomes difficult to keep adding bean in your XML files with its dependencies as the size of xml file continues to grow. So Spring has provided a feature called autowiring where bean dependencies are automatically injected based on various criteria like name, type etc (you can find all types in the previous post). Going a step forward Spring also provides annotations based injection in which case you don't event have to define beans. Spring will scan annotations and inject dependencies on it's own Ofcourse there are rules by which this is governed. We will see this autowiring feature in this post with and without annotations.

Lets continue with the Cricket example we saw in Last post.

Models

Lets rewrite our model classes - 

Bat.java

package models;



public class Bat {    

    private String name;

    public Bat() {}

    

    public Bat(String name) {
        this.name= name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    
    public void play() {
        System.out.println("Bat is swung");
    }

}


Ball.java

package models;

public class Ball {
    

    private String name;


    public Ball() {} 
    

    public Ball(String name) {
        this.name= name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    

    public void play() {
        System.out.println("Ball is bowled");
    }

}

And finally Cricket.java

package models;



public class Cricket {

    private Bat bat;
    private Ball ball;

    public Bat getBat() {
        return bat;
    }

    public void setBat(Bat bat) {
        this.bat = bat;
    }

    public Ball getBall() {
        return ball;]
    }

    public void setBall(Ball ball) {
        this.ball = ball;
    }

    

    public void play() {
        ball.play();
        bat.play();
    }

    

}

now lets configure Spring for these models. 

Spring configuration

Under src folder create a file called beans.xml and add following beans to it

beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    

   <bean id="bat" class="models.Bat" />
   <bean id="ball" class="models.Ball" /> 
   <bean id="cricket" class="models.Cricket" autowire="byType"/>

</beans>

Note :  Notice the attribute autowire of tag bean which is set to byType. This means Cricket has dependency on Bat instance so find a bean of type Bat and inject into cricket. You can also set it as byName in which case it will match bean name and inject dependency, However be careful in using this - if spring finds two beans of type Bat it will throw exception.

Now lets run this setup

Main.java

import models.Cricket;



import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {

    
    public static void main(String args[]) {
       
        ApplicationContext context =  new ClassPathXmlApplicationContext("beans.xml");
        Cricket cricket = (Cricket) context.getBean("cricket");
        cricket.play();
    }
    
}
Output :
Ball is bowled
Bat is swung
Now lets see the same thing with annotations.

Note : Note that spring first created beans that are dependencies and then injects in into objects that need them. Also all beans by default are singleton.

Spring dependency injection using annotation based Autowiring

Changes needed
  1. In your beans.xml file remove autowire="byType" from the cricket tag.
  2. In your Cricket class use @Autowired annotation over your Bat and Ball instance variables.
 beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config/>
    
   <bean id="bat" class="models.Bat" />
   <bean id="ball" class="models.Ball" /> 
   <bean id="cricket" class="models.Cricket" />

</beans>


Cricket.java

public class Cricket {
    
    @Autowired
    private Bat bat;
    @Autowired
    private Ball ball;
    //more code 
} 



Now run the same program as above and you should again get the same output. Few point to note -
  1.  Using @Autowired annotation is same as saying find the bean by type.If Spring finds no bean of injected type for auto-wiring, then it will throw NoSuchBeanDef Exception. If you think that this dependency is not a must than you can use @Autowired(required=false).
  2. As mentioned before @Autowired annotation is similar to autowiting by type. If there are two beans of same type you land in trouble. In such cases you can use resolve by name. For this you can use @Qualifier(value="beanName")
  3. Combination of using @Autowired(required=false) with @Qualifier(value="beanName") is very flexible as you can use this to specify you dependency is not a mandate and you can also specify bean name to resolve with.

To use Qualifier annotation Change your beans.xml as follows

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config/>

    
   <bean id="myBat" class="models.Bat" />
   <bean id="myBall" class="models.Ball" /> 
   <bean id="cricket" class="models.Cricket" />

</beans>


and your cricket class as follows

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Cricket {

    
    @Autowired(required=false)
    @Qualifier(value="myBat") 
    private Bat bat

    @Autowired(required=false)
    @Qualifier(value="myBall") 
    private Ball ball;

     //more code 

}


and run the Main class again you should see same result.


Note : If you want to resolve by name then you can use @Resource annotation. Sample usage would be @Resource(name="myBat") . But note here that you loose the flexibility of marking it as non mandatory as you did with @Autowired annotation. All dependencies become mandatory.


Change the Cricket class as

public class Cricket {
    

    @Resource(name="myBat") 
    private Bat bat;

    @Resource(name="myBall") 
    private Ball ball;
   
    //More code
} 



and rerun Main methods. You should see same output.


Related Links

Saturday, 31 October 2015

Spring Dependency Injection

Background



Before we proceed with how dependency injection works in Spring lets see what dependency injection actually is and why is it so important.

Consider a simple example. Lets say we are designing a Cricket game. How will it's class look like?

You will have a Cricket class that will probably have Bat class and Ball class.

public class Cricket {
    private Bat bat;
    private Ball ball;
    
    public Cricket()
   {
        bat = new Bat("MyBat1") ;
        ball= new Ball("MyBall1") ;
   }


   public void play()
   {
         bat.play();
         ball.play(); 
   }
     
}


How would you play cricket? Probably something like

public class Main {
    
    public static void main(String args[]) {
        Cricket cricket1 = new Cricket();

         cricket1.play();       
    }
    
}


What do you think about above code -
  • It is tightly coupled. If you device to change your Bat or Ball you have to write a new Cricket instance. 
  • It will also be very difficult to test. There can be any type of Bat or Ball and each test your need new Cricket instance.

This is where dependency injection comes into picture. Now consider your cricket class as follows.

public class Cricket {
    private Bat bat;
    private Ball ball;
    
    public Cricket(Bat bat, Ball ball) {
        this.bat = bat;
        this.ball = ball;
    }
    
    public void play() {
        bat.play();
        ball.play();
    }
    
}

and you play like

    public static void main(String args[]) {
       
        Bat bat1 =  new Bat("MyBat");
        Ball ball1 =  new Ball("MyBall");
        Cricket cricket1 = new Cricket(bat1, ball1);
        cricket1.play();
       
        Bat bat2 =  new Bat("MyNewBat");
        Ball ball2 =  new Ball("MyNewBall");
        Cricket cricket2 = new Cricket(bat2, ball2);
        cricket2.play();

    }

If you notice you can create and use any type of bat and ball and play cricket with it. All of it is done at runtime. So essentially you are injecting Bat and Ball dependencies into your Cricket object.

Also notice the problems we faced with earlier code are vanished
  • Code is now decoupled. You can use any Bat and Ball to play cricket.
  • Testing has also becomes very easy as you can now mock your Bat and Ball objects and test your cricket.

There are two types of dependency injection
  1. Constructor based dependency injection
  2. Setters based dependency injection
What you saw in code above is constructor based dependency injection. Setter based dependency injection is when you use setters instead of constructor to inject dependency. See following example -


public class Cricket {
    private Bat bat;
    private Ball ball;
    
    public Bat getBat() {
        return bat;
    }

    public void setBat(Bat bat) {
        this.bat = bat;
    }

    public Ball getBall() {
        return ball;
    }

    public void setBall(Ball ball) {
        this.ball = ball;
    }
    
    public void play() {
        bat.play();
        ball.play();
    }
    
}


and you play like

     public static void main(String args[]) {
        
        Bat bat1 =  new Bat("MyBat");
        Ball ball1 =  new Ball("MyBall");
        Cricket cricket1 = new Cricket();
        cricket1.setBat(bat1);
        cricket1.setBall(ball1);
        cricket1.play();
        
        Bat bat2 =  new Bat("MyNewBat");
        Ball ball2 =  new Ball("MyNewBall");
        Cricket cricket2 = new Cricket();
        cricket2.setBat(bat2);
        cricket2.setBall(ball2);
        cricket2.play();

    }


Simply putting

"Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing, since it allows dependencies to be mocked or stubbed out."

That's the dependency injection in general. Now lets come to Spring dependency injection.

Spring Dependency Injection 

In Spring dependency injection Spring container instantiates and injects dependencies in your instance (also called beans) based on the dependency type or name (more on this later) rather that you instantiating and injecting it yourself.


Lets see how spring DI works in case of our above code.

  • Setter DI

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="myBat" class="Bat">
    
    <bean id="myBall" class="Ball">
    
   <bean id="cricket" class="Cricket">
      <property name="bat" ref="myBat"/>
      <property name="ball" ref="myBall"/>
   </bean>

</beans>

Above bean definition uses setter DI. Spring container scans beans and automatically injects dependencies in it. You can also use 
  • Constructor based DI
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="myBat" class="Bat">
    
    <bean id="myBall" class="Ball">
    
   <bean id="cricket" class="Cricket">
      <constructor-arg ref="myBat"/> <!--  constructor argument order should be same-->
      <constructor-arg ref="myBall"/>
   </bean>

</beans>

Notes : 
  1. For values as dependency (like simple String) you can do <property name="brand" ref="MRF"/>
  2. Instead of using property tag you can also use p namespace - <bean id="cricket" class="Cricket" p:brand="MRF" p:bat-ref="myBat" />  (don't forget to add the namespace)
  3. Also note p namespace does not have any schema reference.

Aurowiring

Instead of explicitly providing dependencies to be injected you can autowire them. One simple example is autowiring by type. In this case Spring container will look for bean of dependency type among all beans and inject it. However note if more than one type of such bean exist this will fail.

  • autowire is an attribute in bean tag with following possible values.





Another interesting aspect is spring DI using annotations and component scan. Instead of specifying beans you can directly use annotations and ask spring framework to scan those and autowire. You can see the same in next post -


NOTE : Dependency injection and IoC (Inversion of control) are words used interchangeably. Both mean dependencies are injected rather that created itself by the object which needs the dependencies.

Related Links


Sunday, 27 September 2015

Context loading in Spring MVC

Background

Spring need no introduction. It is a well know Java framework that use DI (dependency Injection) or Ioc (Inversion of control). I have previously written couple of posts on Spring which you can read in the Related Links section at the bottom of this post. In this post I am specifically going to write about Spring context and how is it loaded.

Context loading in Spring MVC

We generally load spring context in deployment descriptor file called web.xml that is generally located under WEB-INF directory of the projects war file. There are two ways the context can be loaded

  1. You can load the context using ApplicationContext in which case the loaded context will be accessible to entire Application (including various configured endpoints like Dispacher Servlet, Webservice Servlet, REST servlet etc). OR
  2. you can load the context that is specific to an entry point (WebApplicationContext). For example loading context just for Dispacher Servlet. OR
  3.  Use combination of both. Use Application context to load your backend service, access or repository beans that will be used by entire application and your controller, view resolver beans in WEbApplicationContext.



Lets see each in detail

Application  Context

You can do this like follows - 

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

<listener>
   <listener-class>
        org.springframework.web.context.ContextLoaderListener
   </listener-class>
</listener> 


  • Default name of this file is applicationContext.xml. If you do not provide application context configuration file in web.xml using contextConfigLocation as mentioned in config above then file named applicationContext.xml is searched in under WEB-INF folder.
  • There can be only one application context per web application.

WebApplicationContext

You can do that as follows - 
  <servlet>
    <servlet-name>admin</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
                /WEB-INF/spring/*.xml
            </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>


  <servlet-mapping>
    <servlet-name>admin</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  • Default name of this file is xxx-servlet.xml where xxx is the DispatcherServlet name in web.xml
  • A web application can have multiple Dispacher servlets and thereby have multiple such webapplication contexts.




Note 
  1. Application Context is parent context of each WebApplication Contexts.
  2. If a bean is not found in a particular wevbapplication context it is then searched in the parent application context.
  3. Application context is basically to initialize beans that are singleton in nature and can be used throughout the application like your data access bean or your service beans.


Related Links

Saturday, 29 August 2015

Difference between StringBuilder and StringBuffer in Java

Background

In Java String class is immutable. So each concatenation or substring operation yields a new String.

Yes we all have heard String concatenation is bad to create long Strings. Concatenating large number of String literals will fill up the permgen area (where String pool resides) faster. One of the reason why SLF4J is preferred over LOG4J  . Incase you need to concatenate String literals you can use StringBuilder or StringBuffer instance instead. You can just keep appending your String literals to this instance and finally call toString() to get a single String instance. In this post we will see the difference between StringBuilder and StringBuffer.

StringBuilder and StringBuffer in Java

Their usages are quite simple.

        StringBuffer sBuffer = new StringBuffer("abc");
        sBuffer.append("pqr");
        System.out.println(sBuffer.toString());
        
        StringBuilder sBuilder = new StringBuilder("abc");
        sBuilder.append("pqr");
        System.out.println(sBuilder.toString());



As you can see the usage is similar but their difference is very important which we will see now. Just a note no new strings are created when append is called. Internally an array is maintained and String characters are appended to it.

Difference between StringBuilder and StringBuffer in Java

The most important difference between them is 
  • StringBuffer is synchronized, StringBuilder is not.
Hence unless you have a multithreaded scenario to deal with always go for  StringBuilder and not StringBuffer. Even if you have multithread situation you can use a synchronized block around StringBuilder.

 You can say - "StringBuilder is intended as a drop in replacement for StringBuffer where synchronisation is not required"

Quoting the API docs for StringBuilder -

"A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations."

A simple for performance would be -

public class HelloWorld {
    public static void main(String args[]) throws IOException
    {        
        int limit = 1000000;
        long currTime;
        long timeTaken;

        {
            StringBuffer sb = new StringBuffer();
            currTime = System.currentTimeMillis();
            for (int i = limit; i --> 0 ;) {
                sb.append("");
            }
            timeTaken = System.currentTimeMillis() - currTime;
            System.out.println("StringBuffer Time : " + timeTaken);
        }
        {
            StringBuilder sb = new StringBuilder();
            currTime = System.currentTimeMillis();
            for (int i = limit; i --> 0 ;) {
                sb.append("");
            }
            timeTaken = System.currentTimeMillis() - currTime;
            System.out.println("StringBuilder Time : " + timeTaken);
        }   
    }
}


and this prints (one execution) -

StringBuffer Time : 29
StringBuilder Time : 6



Summary

So to summarize always use StringBuilder and not StringBuffer.

Related Links


Wednesday, 26 August 2015

Java memory allocation

Background

If you are acquainted with Java then you must have heard that objects are created on heap and there is automatic garbage collection in Java. In this post we will see the java memory allocation. Not everything is created on heap. Let's start with the basics. Whenever you run a new java process a new JVM is created that takes care of running your Java program. Like any other process your operating System will provide this JVM instance some memory to run. You can also specify heap size of your Java program in your jvm arguments.


Java memory allocation

You can use following options to alter JVM memory
  1. -Xms<size>      set initial Java heap size (Eg. java -Xms1g TestProgram)
  2. -Xmx<size>      set maximum Java heap size (Eg. java -Xmx2g TestProgram)
  3. -Xss<size>        set java thread stack size (Eg. java -Xss4m TestProgram)
Java memory is of two types.
  1. Stack
  2. Heap

Stack

Stack is where local variables are stored and that includes primitive types and object references. Each thread will have it's own private stack (which you can define in Java with -Xss JVM parameter). Each method will create it's own section on this stack for maintaining scope. This is called stack frame. Whenever a local variable is in methods scope it is pushed to this stack frame and when it is out of the scope it is poped out. Note this is all scope based. There is no concept of garbage collection in stacks.

Heap

Heap is where your objects are created (memory is allocated for the object). Whenever you create a new instance of a class using new keyword it is created on this heap. This object will be garbage collected when it is no longer referenced from any of the GC roots.

Difference between Stack and Heap memory

  1. As mentioned earlier Stack stores local variables and object references where as heap stored the actual object instance.
  2. If stack memory is filled up JVM will shutdown throwing java.lang.StackOverFlowError error where as if heap memory is filled JVm will shutdown throwing java.lang.OutOfMemoryError error.
  3. Each thread will have it's own private stack. Meaning each stack memory is private to some thread where as heap area is shared among all the threads.

Related Links

Sunday, 22 February 2015

Java Class Design using Builder

Background

Two important principle of Object Oriented programming are - 
  1. For each class design aim for low coupling and high cohesion.
  2. Classes should be open for extension but closed for modification.

We will see how we can use these to design any classes.



Class Design


Lets design a simple Employee class which has it's name.

public class Employee {
    
    private String name;
    
    public Employee(String name)
    {
        this.name = name;
    }
    
}


Looks good. Every time anyone has to create an instance of Employee he has to supply name in the constructor. So you see any flaw in this?

Well there is. Lets say new requirement comes up and you now have to add employee age. What would you do?

One way would be change the constructor to include age now.

public class Employee {
    
    private String name;
    private int age;
    
    public Employee(String name, int age)
    {
        this.name = name;
        this.age = age;
    }  
}


Though it solves our new requirement it will break all our existing code. All Users using our existing code will  have to make changes now. So we definitely cannot remove the constructor with name in it. So what do we do next ?

Lets create an overridden constructor.

public class Employee {
    
    private String name;
    private int age;
    
    public Employee(String name)
    {
        this.name = name;
    }
    
    public Employee(String name, int age)
    {
        this(name);
        this.age = age;
    }
    
}


Ok this looks good. This will not break existing code and will meet our existing requirement. Now take a minute to this what about future requirements. Lets say you may have to add employees sex, salary etc in the Employee mode. What will you do then? Keep adding overloaded constructors?

Sure you can. But that is a very poor design choice. Simplest thing to do is following -

public class Employee {
    
    private String name;
    private int age;
    
    public Employee(){}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
}


That's right. A simple no argument default constructor and getter, setter methods corresponding to instance variables. This is flexible design implementation. Going forward we can add as many instance variables with corresponding get and set methods.

Though this is good and simple class design. I would not say it is optimal. What if you want to ensure that user should not create a Employee instance without providing name.

Sure different developers will have different methods to ensure that and have good design. I like to use builder for that. See following -


import static org.apache.commons.lang3.Validate.*;
public class Employee
{
    private String name;
    private int age;
    
    private Employee() {}

    public String getName()
    {
        return name;
    }
    
    public int getAge()
    {
        return age;
    }

    public static class EmployeeBuilder
    {
        private final Employee employee;

        public EmployeeBuilder()
        {
            employee = new Employee();
        }

        public EmployeeBuilder setName(String name)
        {
            employee.name = name;
            return this;
        }
        
        public EmployeeBuilder setAge(int age)
        {
            employee.age = age;
            return this;
        }

        public Employee build()
        {
            validateFields();
            return employee;
        }

        private void validateFields()
        {
            notNull(employee.name, "Employee Name cannot be Empty");
            isTrue(employee.age >= 21, "Employee age cannot be less than 21");
        }
    }
}



Notice following points -
  1. We made constructor of Employee class private. So no one can directly instantiate Employee class. He or she has to use our Builder class.
  2. There is not setter methods in Employee class. Again builder should be used.
  3. Builder's build() methods validates our requirements like name cannot be null or age has to be more than 21.
  4. You can easily create Employee objects using - 
Employee employee = new EmployeeBuilder().setName("Aniket").setAge(23).build();

Saturday, 14 February 2015

Understanding Java Remote Method Invocation (RMI)

Background

Everyone with Java background would know we can easily call methods on an instantiated object as long as everything is limited to same JVM (Java virtual machine). Even imagined if we can invoke methods on a remote object as if they were local. Well the answer is yes and that is exactly what we are going to see in this post. Infact RMI uses one of the famous design patters - The Proxy Pattern . We will cover that in detail under design patterns. For now keep following in mind -

Proxy Design Pattern involves a representative Object (A proxy) that controls access to another object which may be - 
  • Remote
  • Expensive to Create (Virtual Proxy)
  • Needs secure access (Protection Proxy)

This post aims to help you understand how RMI works, how objects interact with a simple demo.

Getting Started

Java RMI APIs essentially help you to invoke methods on remote object.  There are four essential entities that take part in RMI - 
  1. Client
  2. Stub / Client Helper (Proxy)
  3. Server
  4. Skeleton / Server Helper

Server is where you have your actual implementation of service. Client want to call it.  Client code cannot directly call methods on remote server object as they are on different JVMs .So client creates a representation of actual service called stub or proxy and invokes methods on it. Stub takes this call, serializes method name, parameters etc and send its over network to the skeleton on the server. skeleton then deserializes the information and invokes the method on actual object. It takes the result serializes it and sends in back to stub. Stub deserializes the result and returns it back to the client code.


That's for the overview of how RMI works. Now lets see an actual demo in Java.


To The Code....

Lets start by writing an interface for the remote service - 

import java.rmi.Remote;
import java.rmi.RemoteException;


public interface GreeterService extends Remote {
    public String displayWelcomeMessage(String name) throws RemoteException;
}

Notice how our interface extends java.rmi.Remote interface? It is a marker interface(No methods in it) just like - 
  • java.lang.Cloneable
  • java.io.Serializable

It is used to mark that methods of instances of class that implement this interface can be called from non local (remote) virtual machines.

Also notices how our method declaration throws RemoteException ? Well it's not mandatory but a good practice so that the implementation handles it and is aware that thing may go wrong as calls are made to another virtual machine (which may be remote).

Lets write implementation for this -

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;


public class GreeterServiceImpl extends UnicastRemoteObject implements GreeterService {

    protected GreeterServiceImpl() throws RemoteException { }

    @Override
    public String displayWelcomeMessage(String name) throws RemoteException {
        return "Hi " + name + " welcome to Open Source For Geeks!";
    }
    
    public static void main(String args[])
    {
        try {
            GreeterService greeterService = new GreeterServiceImpl();
            Naming.rebind("greeterServiceObj", greeterService);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


So we wrote a class that implements the GreeterService and it's methods.

Notice how we have extended UnicastRemoteObject? That is because that super class takes care of actual communication part with remote VM.

Also notice we have declared a no-args constructor that throws RemoteException. That's because super class UnicastRemoteObject has constructor that throws that Exception.
  • UnicastRemoteObject is used for exporting a remote object with JRMP and obtaining a stub that communicates to the remote object (Socket level logic). 
  • We will use this GreeterServiceImpl class to generate skeleton and stub and the communication logic is handled by UnicastRemoteObject that GreeterServiceImpl extends.
  • JRMP is Java Remote Method Protocol.  It is a Java-specific, stream-based protocol for Java-to-Java remote calls, requiring both clients and server to use Java objects. RMI-IIOP is an alternative protocol which exposes Java objects to CORBA ORBs.
We are done with our server level logic. Now lets
  1. Create skeleton and stub, 
  2. start rmi registry
  3. Start Remote Service
First Compile classes -
  • javac *.java

You should have two class files - GreeterService.class and GreeterServiceImpl.class. Now you can go ahead and create stub skeleton . Run

  • rmic GreeterServiceImpl 
 You should get GreeterServiceImpl_Stub.class file.


Note : From rmic 1.2 onwards, Java don't generate skeletion class any more. New JRMP protocol supported for RMI has got rid of the use of skeleton files.  




Now start rmiregistry. Just type rmiregistry in command line.


Note 1 : Start rmiregistry from location that has access to the stub class file.
Note 2 : If you want to start your rmi registry on different port (defult is 1099) you can use command - rmiregistry [port]

 Now start your remote Service -

  • java GreeterServiceImpl
Your remote service and rmiregistry are all set. Now lets write client and test our setup -

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;


public class GreeterClient {

    public static void main(String args[])
    {
        try {
            GreeterService greeterService = (GreeterService) Naming.lookup("rmi://127.0.0.1/greeterServiceObj");
            System.out.println(greeterService.displayWelcomeMessage("Aniket"));
        } catch (MalformedURLException | RemoteException | NotBoundException e) {
            e.printStackTrace();
        }
    }
    
}


Make sure your client Java process has access to following Java class files -
  1. GreeterClient.class
  2. GreeterService.class
  3. GreeterServiceImpl_Stub.class
 Yes! That's all client needs. Lets run client.


  • javac *.java
  • java GreeterClient

 Related Links



Friday, 13 February 2015

Understanding how HashMap and HashSet work in Java

Background

Hashing is a very important concept in computer programming and a very popular concept for interview questions. Two important data structures related to hashing are HashMap and HashSet which is exactly what we are going to look at in this post.

Overview

If you are from a computer science background you would know HashMap is a data structure which stores key value pairs where as a HashSet stores unique data. In HashMap we have kind of buckets and each data added to a HashMap falls into one of the buckets depending on the hash value of it. Also you must have heard that adding and retrieving objects in HashMap happen in time complexity O(1).

But still there are open end question like -
  • What happens when two objects added to HashMap have same hash (code) value ? - a situation typically known as collision.
  • If above is handled how get and put work in hashmap?.... and so on.
We will address them now.

Understanding how HashMap works

 You can visualize HashMap as follows-




So you have an Array and each array position is essentially a Linked List. As you know you don't have to specify size of the HashMap. It increases dynamically like ArrayList.  The main data structure is essentially an array.

    /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
    transient Entry[] table;


When you create a HashMap you either choose to provide initial capacity or when you don't a default value is used.

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;


 When table is created it is created with either this initial default capacity or the capacity you provide in the constructor.

Next important thing is when should out table we resized to meet the dynamically changing data size of HashMap. Answer depends on a threshold that is determined by load factor.

    /**

     * The load factor used when none specified in constructor.

     */

    static final float DEFAULT_LOAD_FACTOR = 0.75f;


HashMap provides a constructor to initialize load factor as well. So when your data size equals

  • threshold = table capacity * load factor

then the HashMap table is resized. Constructors are as follows -

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        // Find a power of 2 >= initialCapacity
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;

        this.loadFactor = loadFactor;
        threshold = (int)(capacity * loadFactor);
        table = new Entry[capacity];
        init();
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param  initialCapacity the initial capacity.
     * @throws IllegalArgumentException if the initial capacity is negative.
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
     * (16) and the default load factor (0.75).
     */
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }


How is data with keys generating same hash code stored in HashMap?

As mentioned earlier each index has reference to object of type Entry which is a Linked List. It has a next pointer. So if an entry is added to hash map it's hash code is computed which determines the index at which it should be put. If that index has an entry then new entry is added to the start of the linked list and existing linked list is appended to next of it.

    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

    void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        if (size++ >= threshold)
            resize(2 * table.length);
    }


Also note how null is handled. Yes null is an acceptable key in HashMap.

So how is data retrieved if two keys generate same has code?

Same hash code will make searched for both keys data land on same index in the table. From there the each Entry object is iterated over and it's key compared with the search key. On successful match corresponding value is returned.

    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }


Lastly lets see HashSet.

Understanding HashSet

Well if you are still guessing the data structure of HashSet then following would be a surprise -

    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();



Yup HashSet stores data as keys of HashMap with dummy value. Constructor is equivalent to that of HashMap -

    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * default initial capacity (16) and load factor (0.75).
     */
    public HashSet() {
    map = new HashMap<E,Object>();
    } 



    public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<E,Object>(initialCapacity, loadFactor);
    }



    public HashSet(int initialCapacity) {
    map = new HashMap<E,Object>(initialCapacity);
    }


Add and Remove methods are as follows -

    public boolean add(E e) {
    return map.put(e, PRESENT)==null;
    }



    public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
    }


Related Links

Saturday, 7 February 2015

String processing using Matcher, Pattern and Regex in Java

Background

Using regex or simply regular expressions have been very important part of String processing. We will explore it is this post.


Before you get to Java code lets take a looks at Regex symbols - 

Regex Symbols

Common Regex Symbols : 

Common Regex Meta Symbols : 


Common Regex Quantifier Symbols : 

Now lets head on to Java Code....

Using java.util.regex.Pattern and java.util.regex.Matcher classes

Lets use these classes to demonstrate regex.

    public static void main(String args[])
    {
        String str = "Hi there! My name is John. How can I help you?";
        Pattern p = Pattern.compile("[.!?]");
        Matcher matcher = p.matcher(str);
        int count = 0;
        while(matcher.find()) {
            count++;
        }
        System.out.println("Count : " + count);

    }

and the output is - 3. Lets see what we did here. We have a String - "Hi there! My name is John. How can I help you?"  and we are interested in finding number of times symbol '.', '!' or '?' appears in the String. So we provided the regex "[.!?]". 

Did not quite get the regex part? Go back to previous section - Regex symbols. Notice in Common Regex symbols image [xyz] represent x or y or z. We are simply incrementing the counter if we find such a regex meaning '.', '!' or '?' '.

Lets head on to something more interesting. How many time have you used String classes split() method? Did you realize that it is infact a regex that split method takes. We split words from line as follows -

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        String[] tokens = str.split(" ");
        for(String token : tokens)
        {
            System.out.println(token);
        }

    }


and you get output as -

Hello
all.
Welcome
to
Open
Source
For
Geeks!


as expected.  If you see the split method code it internally used java.util.regex.Pattern to compile you regex and use it to split the String -

    public String[] split(String regex, int limit) {
    return Pattern.compile(regex).split(this, limit);
    }


Now lets do the same thing as split using Patter and Matcher.

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        Pattern pattern= Pattern.compile("\\w+");
        Matcher matcher = pattern.matcher(str);
        while(matcher.find()) {
            System.out.println(matcher.group());
        }

    }


and the output is -

Hello
all
Welcome
to
Open
Source
For
Geeks


Noticed any difference? '.'(dot) and '!'(exclamation) are not present. Well that is expected. See Regex symbols again. We used "\\w+"  which means match one or more word character and dot and exclamation aren't one of them.

Note : Space is also not a word character. Else we would have got whole String as matched pattern (leaving dot and exclamation mark aside). Digits are also part of word characters i.e \\w+ .

 So lets slightly modify our code to get the same output.

    public static void main(String args[])
    {
        String str = "Hello all. Welcome to Open Source For Geeks!";
        Pattern pattern= Pattern.compile("\\w+\\.*!*");
        Matcher matcher = pattern.matcher(str);
        while(matcher.find()) {
            System.out.println(matcher.group());
        }

    }


and the output is -

Hello
all.
Welcome
to
Open
Source
For
Geeks!


Ok that's the same. What did we do here? Notice the regex again. This time it is - "\\w+\\.*!*". We are saying get me sequence that matches [(one or more word characters) then (zero or more dot symbols) then (zero or more exclamation symbols)].

Note :  Dot is a regex symbol and hence you need to escape (like we did \\. ) it if you want to use it for searching dot pattern. Exclamation on the other hand was not so we could directly use it.


Another Example


Lets  do something practical now. Lets say you have following data (maybe in a file or just an array) -

data1=${key1}
data2=${key2}
data3=${key3}

and you have to replace the placeholder with the actual value whose mapping you have (again maybe in a different file).

key1 -> ActualKey1
key2 -> ActualKey2
key3 -> ActualKey3

and finally you want output like -

data1=ActualKey1
data2=ActualKey2
data3=ActualKey3

Lets write code to achieve this using regex.

    public static void main(String args[])

    {

        String[] replacableData = new String[]{"data1=${key1}","data2=${key2}","data3=${key3}"};

        Map<String, String> keyMappings = new HashMap<String, String>();

        keyMappings.put("key1", "ActualKey1");

        keyMappings.put("key2", "ActualKey2");

        keyMappings.put("key3", "ActualKey3");

        Pattern pattern= Pattern.compile("(\\w+=)(\\$\\{)(\\w+)(\\})");

        for(String str : replacableData) {

            Matcher matcher = pattern.matcher(str);

            String key = matcher.replaceAll("$3");

            System.out.println("Key : " + key);

            String newStr = matcher.replaceAll("$1"+ keyMappings.get(key));

            System.out.println("After Replacement : " + newStr);

        }

    }


and the output is -

Key : key1
After Replacement : data1=ActualKey1
Key : key2
After Replacement : data2=ActualKey2
Key : key3
After Replacement : data3=ActualKey3


Another important concept to note here is the groups in the rgex that you can refer later with $groupIndex.

In our regex - "(\\w+=)(\\$\\{)(\\w+)(\\})"

group1 -> (\\w+=)
group2 -> (\\$\\{)
group3 -> (\\w+)
group4 -> (\\})
  Also replaceAll() replaces the entire original String with whatever group combinations you provide. For example matcher.replaceAll("$1$2$3$4") will give you back the same String.

Note : replaceAll() method return a new String. original String is not changed.

Note :  Even used replace() and replaceAll() method of String class?  Both of them replace all occurences with the String you desire. Only difference is replaceAll() uses a regex where as replace() uses simple CharSequence.

Thursday, 8 January 2015

Understanding Localization in Java

Background

Localization is a very important concept. Generally when you write a application or create a website you do it in a particular language Eg. English. But customers of your application/website may be from different country understanding different languages. In fact English itself has may variation. For Eg. you have US English, British English, Indian English etc To make you application/website dynamic to the customers locale understanding and implementing Localization is very important.


In this post I will show basics of localization , classes used in Java.

Locale class

Locale class is used in Java as basis of deciding which locale your program uses. To get all available locales that is supported in the JVM you are running you can run the following code - 

    public static void main(String args[])
    {
        for(Locale locale : Locale.getAvailableLocales())
        {
            System.out.println(locale);
        }
    }


I am not providing output for above as the list is big. Lets see a shorter version of this. Lets see all locales of languages english. Before that's lets understand locale.  you can imagine locale as language specs that people of certain region understand. You can identify locale as  (language + country +variant [if any]). Consider variants as same language different variation. In terms of databases this is the primary key. We will see this in more details in some time. But for now lets come to Locale class. So I was saying following code will show all locales of english language (but different country or variants if any).

    public static void main(String args[])
    {
        for(Locale locale : Locale.getAvailableLocales())
        {
            if(locale.getLanguage().equals("en"))
            {
                System.out.println(locale + " : " + locale.getDisplayName());
            }
        }
    }

and the output is :

en_MT : English (Malta)
en_GB : English (United Kingdom)
en_CA : English (Canada)
en_US : English (United States)
en_ZA : English (South Africa)
en : English
en_SG : English (Singapore)
en_IE : English (Ireland)
en_IN : English (India)
en_AU : English (Australia)
en_NZ : English (New Zealand)
en_PH : English (Philippines)


You can get the default locale using Locale.getDefault() method where as you can set default locale using Locale.setDefault(yourLocaleObject); 

You can create locale class in following ways -

  1. Locale locale = new Locale("en", "", ""); 
  2. Locale locale = Locale.forLanguageTag("en");
  3. Locale locale = new Locale.Builder().setLanguageTag("en").build(); 
  4. Locale locale = Locale.ENGLISH;

Programatically speaking locale can be of following format

language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions

Resource Bundles

Resource Bundles are entities used to map keys to values in different locales. We can simply load or get a resource bundle and then call get on some key to get the locale specific value and show it to the user. We will see this in detail code in some time.

ResourceBundle is an abstract class. It has two derived classes - 

  1. PropertyResourceBundle
  2. ListResourceBundle

In  PropertyResourceBundle we essentially provide property files - one for each locale containing locale specific values. When this resource bundle is loaded and get is called keys from the property file corresponding to locale supplied is fetched and returned.

In ListResourceBundle property file is replaced by Classes. classes that extend ListResourceBundle class and override getContents() method, which returns an Object [][].

 
Code to understand PropertyResourceBundle 

Create project structure as follows -



Add following content in propertied file.

Contents of ResourceBundle_en.properties
HW = "Hello World in English!"

Contents of ResourceBundle_fr.properties
HW = "Hello World in French!"

Contents of ResourceBundle_it.properties
HW = "Hello World in Italian!"

Contents of ResourceBundle.properties
HW = "Hello World!"

and execute the following code - 

import java.util.Locale;
import java.util.ResourceBundle;


public class LocalizationTest {
    
    public static void main1(String args[])
    {

        
        System.out.println("Setting Default locale : " + Locale.getDefault());
        System.out.println("Using Resource Bundle with locale : " + Locale.getDefault());
        ResourceBundle rb = ResourceBundle.getBundle("Resourcebundle", Locale.getDefault());
        System.out.println("HW : " + rb.getString("HW"));
        System.out.println("-----------------------------");
        
        Locale.setDefault(Locale.ITALIAN);
        System.out.println(" Setting Default locale : " + Locale.getDefault());
        System.out.println("Using Resource Bundle with locale : " + Locale.getDefault());
        rb = ResourceBundle.getBundle("Resourcebundle", Locale.getDefault());
        System.out.println("HW : " + rb.getString("HW"));
        System.out.println("-----------------------------");
        
        Locale.setDefault(Locale.FRENCH);
        System.out.println("Setting Default locale : " + Locale.getDefault());
        System.out.println("Using Resource Bundle with locale : " + Locale.getDefault());
        rb = ResourceBundle.getBundle("Resourcebundle", Locale.getDefault());
        System.out.println("HW : " + rb.getString("HW"));
        System.out.println("-----------------------------");
        
        /**
         * If resource bundle property file for given locale (GERMAN in this case) is 
         * not found then resource bundle property file of default locale is considered
         *  i.e FRENCH in this case
         */
        System.out.println("Using Default locale : " + Locale.getDefault());
        System.out.println("Using Resource Bundle with locale : " +  Locale.GERMAN);
        rb = ResourceBundle.getBundle("Resourcebundle", Locale.GERMAN);
        System.out.println("HW : " + rb.getString("HW")); 
        System.out.println("-----------------------------");
        
        /**
         * If resource bundle property file for given locale (GERMAN) is 
         * not found and neither for the default locale (CHINESE)
         * then property file with same name as resource bundle
         * base name(no language or country extensions) 
         * is picked up (ResourceBundle.properties)
         */
        Locale.setDefault(Locale.CHINESE);
        System.out.println("Setting Default locale : " + Locale.getDefault());
        System.out.println("Using Resource Bundle with locale : " +  Locale.GERMAN);
        rb = ResourceBundle.getBundle("Resourcebundle", Locale.GERMAN);
        System.out.println("HW : " + rb.getString("HW"));
    }

}

 and the output is :

Setting Default locale : en_US
Using Resource Bundle with locale : en_US
HW : "Hello World in English!"
-----------------------------
 Setting Default locale : it
Using Resource Bundle with locale : it
HW : "Hello World in Italian!"
-----------------------------
Setting Default locale : fr
Using Resource Bundle with locale : fr
HW : "Hello World in French!"
-----------------------------
Using Default locale : fr
Using Resource Bundle with locale : de
HW : "Hello World in French!"
-----------------------------
Setting Default locale : zh
Using Resource Bundle with locale : de
HW : "Hello World!"

Note : If properties file are not in the path or key is not found then MissingResourceException is thrown.

Similarly for Code to understand ListResourceBundle

// Italian version
public class ResourceBundle_it_IT extends ListResourceBundle {
    public Object[][] getContents() {
        return contents;
    }

    static final Object[][] contents = { 
        { "HW", "Hello World in Italian!" },
        { "GB", "Good bye in Italian" } 
    };
}

Resource Bundle is loaded in same way as Property resource bundle.

Note 1: However in case of ListResourceBundle you call resourceBundle.getObject("ABC") and the call returns an Object unlike the case of PropertyResourceBundle which returns String.

Note2 : Make sure Resource Bundle classes that extend ListResourceBundle  are public as java uses reflection to load these classes.

Resolution of Resource Bundles

A fully qualified resource bundle should be of following format - 

bundlename + "_" + language + "_" + country + "_" + (variant + "_#" | "#") + script + "-" + extensions

When you load a bundle with a locale a sequence is followed to resolve the bundle used. That is as follows - 

  1. The resolution starts by searching for an exact match for the resource bundle with the full name.
  2. The last part (separated by _) is dropped and the search is repeated with the resulting shorter name. This process is repeated till the last locale modifier is left.
  3. The search is restarted using the full name of the bundle for the default locale.
  4. Search for the resource bundle with just the name of the bundle.
  5. If all the above fails , then MissingBundleException is thrown.

Note : The getBundle() method takes a ResourceBundle.Control object as an additional parameter.
You can extend ResourceBundle.Control class, override getCandidateLocales() method and pass it's instance  to the getBundle() method. By this you can change the default resource bundle search process. You can even read from other file formats (Eg. XML files).

Note :  All of the above classes are for String localization. This does not consider numbers or currency representation in different languages. You need to use Format abstract class for that. It's implementation include -
  1. NumberFormat
    1. getInstance()
    2. getIntegerInstance()
    3. getCurrencyInstance()
    4. getPercentageInstance()
  2. DateFormat (SimpleDateFormat)
    1. getDateInstance()
    2. getTimeInstance()
    3. getDateTimeInstance()
After you get an instance of above concrete classes you can call format() method to get locale specific string representation of data. If you want data back you can use corresponding parse() method.

Note : Localization and Internationalization(i18n) are two different concepts.
Internationalization is the process of designing and building an application to facilitate localization. Localization, in turn, is the cultural and linguistic adaptation of an internationalized application to two or more culturally-distinct markets.

For more on this see SO question in related Links section.

Related Links

t> UA-39527780-1 back to top