Thursday, July 7, 2016

WeakHashMap in Java with Example. Differences and Similarities in HashMap and WeakHashMap in java

A HashMap maintains the key value pairs of any specific data type or custom classes. And as we know, if we want to have any custom class instances as a Key to our HashMap then the custom class must implement the hashcode() and equals() method as per the contract of these two methods. Hence, the key of a HashMap plays a vital role in creating a HashMap.

As we know the nature of Garbage Collection, if any object in the program is not having any live reference anywhere then it is available for the garbage collection. If in any HashMap we are using such a key that the reference of that key(instance of a class) does not exist anymore anywhere then the garbage collection should remove it from the map and should collect it's garbage but in case of HashMap it is not possible.

It is possible only when the keys of the map are stored in a WeakReference. WeakReference is a class in java.lang.ref package.Hence, a WeakHashMap is a special Map implementation where the keys of the map are stored in a java.lang.ref.WeakReference . By storing the keys in a weak reference, key-value pairs can dynamically be dropped from the map when the only reference to the key is from the weak reference. It means the key-value pair will be garbage collected if there is not other live reference of the key other than WeakReference class.

Program Example:

public class WeakHashMapExample {
    
    public static void main(String[] args) { 

           
        // Creating HashMap and WeakHashMap objects

        Map hashmapObject = new HashMap();
        Map weakhashmapObject = new WeakHashMap();
        
       // Created HashMap and WeakHashMap keys

        String hashmapKey = new String ("hashmapkey");
        String weakhashmapKey = new String ("weakhashmapkey");

      // Created HashMap and WeakHashMap values

        String hashmapValue = "hashmapvalue";
        String weakhashmapValue = "weakhashmapvalue";  

      // Putting key and value in HashMap and WeakHashMap Object

        hashmapObject.put(hashmapKey ,hashmapValue); 
        weakhashmapObject.put(weakhashmapKey ,weakhashmapValue); 

      // Print HashMap and WeakHashMap Object : Before Garbage Collection
       
        System.out.println("HashMap before Garbage Collected :"+ hashmapObject);
        System.out.println("WeakHashMap before Garbage Collected :"+
                            weakhashmapObject);

     // Set HashMap and WeakHashMap Object keys to null

        hashmapKey = null;  
        weakhashmapKey = null;

     // Calling Garbage Collection
        System.gc(); 

    // Print HashMap and WeakHashMap Object : After Garbage Collection
       
        System.out.println("HashMap after Garbage Collected :"+ hashmapObject);
        System.out.println("WeakHashMap after Garbage Collected :"+
                            weakhashmapObject); 
 }
}

Output:

HashMap before Garbage Collected :{hashmapkey=hashmapvalue}
WeakHashMap before Garbage Collected :{weakhashmapkey=weakhashmapvalue}
HashMap after Garbage Collected :{hashmapkey=hashmapvalue}
WeakHashMap after Garbage Collected :{}


From the above example it is clear that the entry of WeakHashMap is garbage collected if it does not find any strong reference of it but this is not there in HashMap implementation.

Differences in HashMap and WeakHashMap:

1) Entry object Garbage Collected in WeakHashMap but in HashMap Entry object is not Garbage Collected even if the references are set to null.
2) Automatic Size decrease happens in case of WeakHashMap when run the size() method repeateadly on the WeakHashMap as the garbage collection might decrease the count and remove silently the element which is not strongly referenced. But in case of HashMap size() returns the same value until we remove any element explicitly.
3) Clone and Searilize methods are not in WeakHashMap as this class does not implement Cloneable and Serializable interfaces. Rather these methods are present in HashMap as HashMap implements these interfaces.

Similiarities in HashMap and WeakHashMap:

1) Both can have Null Key and Null Value.
2) Performance is similar in both the classes.
3) Both are not synchronized and can be made synchronized by using Collections.synchronizedMap().
4) Iterators of both the classes are fail-fast.

Variable Argument Methods in Java with Example(Varargs)

In java we call a method with its signature by passing the suitable arguments it takes. So the calling function must know the number of arguments and the types of arguments the called function will take. But, in some scenarios we need to call a function and we are not sure about the number of arguments the method will take or in other words we can say that the called method is unpredictable in respect of the number of arguments and the type of the arguments. The second scenario is that sometimes we call a function in the class which just performs some kind of operation(let's say multiplication) on the number of arguments that we pass to that function. Hence, we need to pass the each number to that method but it is made easy by variable arguments that while catching those arguments we don't need to specify the type and name of each of those arguments. Rather we can catch all of them in a variable argument. Below is an example of simple code snippet which is not using varargs.

public int multiply(int a,int b,int c,int d){
 return (a*b)*(c*d);
}

Here, we need to declare the type and name of the argument for each variable. Instead of it we can do it using varargs like follows:

public int multiply(int... numbers){
int result = 1;

for(int number: numbers){
 result= result*number;
}

return result
}

Here , in this code each and every number is catched in the numbers argument and is fetched one by one using the fore loop.

So, the biggest benefit of using it is to avoid method overloading for some scenarios.

Another example:

class VarargsExample2{  
   
 static void display(String... values){  
  System.out.println("display method invoked ");  
  for(String s:values){  
   System.out.println(s);  
  }  
 }  
  
 public static void main(String args[]){  
  
 display();//zero argument   
 display("hello");//one argument   
 display("my","name","is","varargs");//four arguments  
 }   
}  

Output:
display method invoked
display method invoked
hello
display method invoked
my
name
is 
varargs

Some points to remember about varargs:

*There can be only one variable argument in the method.
*Variable argument (varargs) must be the last argument.

Note: public static void main(String args[]) is the biggest example of varargs as it takes a undefined number of runtime arguments.

Tuesday, July 5, 2016

Java : Step-By-Step process to secure your RESTful API using ResourceConfig and @RolesAllowed annotations.

It is a very good practice to secure your web services so that the user of that service can be given a limited access to the methods based on the roles they have. We are going to user @RolesAllowed annotations in this section along with ResoourceConfig class. We will go through step by step procedure for this:

1) Modify your web.xml with the below mentioned code:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
         <init-param>
       <param-name>jersey.config.server.provider.packages</param-name>
       <param-value>com.vagalla.jersey.first</param-value>
    </init-param>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.vagalla.jersey.first.MyApplication</param-value>
        </init-param>      
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>


In this section we have mentioned that every request which will hit the /rest uri, will undergo the ServletContainer and MyAppication will be loaded as the initial parameters.

2) Create class MyApplication extending the ResourceConfig internal class like follows:


import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        super(Hello.class);
        //register(RolesAllowedDynamicFeature.class);
        register(AuthenticationFilter.class);
    }
}

Here, in this class we are registering a class named AuthenticationFilter.class, LoggingFilter is a deprecated one. We can also register RolesAllowedDynamicFeature.class if we want. But, here in our example, only AuthenticationFilter.class is needed for simple HTTP basic authentication.

3) Create public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter.

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;

import org.glassfish.jersey.internal.util.Base64;

/**
 * This filter verify the access permissions for a user
 * based on username and passowrd provided in request
 * */
@Provider
@PreMatching
public class AuthenticationFilter implements javax.ws.rs.container.ContainerRequestFilter
{
    
    @Context
    private ResourceInfo resourceInfo;
     
    private static final String AUTHORIZATION_PROPERTY = "Authorization";
    private static final String AUTHENTICATION_SCHEME = "Basic";
    private static final Response ACCESS_DENIED =       Response.status(Response.Status.UNAUTHORIZED)
                                                        .entity("You cannot access this resource").build();
    private static final Response ACCESS_FORBIDDEN = Response.status(Response.Status.FORBIDDEN)
                                                        .entity("Access blocked for all users !!").build();
    
      
    @Override
    public void filter(ContainerRequestContext requestContext)
    {
        Method method = resourceInfo.getResourceMethod();
        //Access allowed for all
        if( ! method.isAnnotationPresent(PermitAll.class))
        {
            //Access denied for all
            if(method.isAnnotationPresent(DenyAll.class))
            {
                requestContext.abortWith(ACCESS_FORBIDDEN);
                return;
            }
              
            //Get request headers
            final MultivaluedMap<String, String> headers = requestContext.getHeaders();
              
            //Fetch authorization header
            final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
            //If no authorization information present; block access
            if(authorization == null || authorization.isEmpty())
            {
                requestContext.abortWith(ACCESS_DENIED);
                return;
            }
              
            //Get encoded username and password
            final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
              
            //Decode username and password
            String usernameAndPassword = new String(Base64.decode(encodedUserPassword.getBytes()));;
  
            //Split username and password tokens
            final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
            final String username = tokenizer.nextToken();
            final String password = tokenizer.nextToken();
              
            //Verify user access
            if(method.isAnnotationPresent(RolesAllowed.class))
            {
                RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
                Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
                  
                //Is user valid?
                if( ! isUserAllowed(username, password, rolesSet))
                {
                    requestContext.abortWith(ACCESS_DENIED);
                    return;
                }
            }
        }
    }
    private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet)
    {
        boolean isAllowed = false;

        if(username.equals("julie") && password.equals("qwerty"))
        {
            String userRole = "member";
            //Step 2. Verify user role
            if(rolesSet.contains(userRole))
            {
                isAllowed = true;
            }
        }
        return isAllowed;
    }
}

Here, in this class we are simply fetching the header from the request and fetching the authentication instance from that to find out the username , password, roles etc inforamtion. In the method isUserAllowed, there can be code for the users authentication and we can go to the database to verify the username and password authenticity. isAnnotationPresent method can be used to find out the which annotation is applied over the said method.

4) Finally, create our service class where we have defined the resources with the specific URI's.

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.SecurityContext;

// Plain old Java Object it does not extend as class or implements 
// an interface

// The class registers its methods for the HTTP GET request using the @GET annotation. 
// Using the @Produces annotation, it defines that it can deliver several MIME types,
// text, XML and HTML. 

// The browser requests per default the HTML MIME type.

//Sets the path to base URL + /test
@Path("test")
@PermitAll
public class Hello {

    @GET
    @Path("editor")
    @Produces(MediaType.TEXT_PLAIN)
    @RolesAllowed("editor")
    public String editorOnly() {
        return "Got to editor path!";
    }

    @GET
    @Path("member")
    @Produces(MediaType.TEXT_PLAIN)
    @RolesAllowed("member")
    public String memberOnly() {
        return "Got to member path!";
    }

    @GET 
    @Path("open")
    @Produces(MediaType.TEXT_PLAIN)
    public String open(@Context SecurityContext context) {
        return "Open to all! - " + context.getUserPrincipal().getName();
    }
}

Run the program on server and try to access the method with @RolesAllowed("member") and it won't go through the code if the username and password doesn't match with julie and qwert with role as member.

Monday, July 4, 2016

Java : Usage of Enums with Example

Enums are the set of some constants in java. In other words, if you want to define some constants in your program which you are going to use throughout and need not be changed, use Enums. For example, in an application you can represent the different statuses as a list of constants and take Enums type.

Example:
public enum Status{
APPROVED,DECLINED,IN-PROGRESS,PENDING,NEW
}

Hence, it is recommended to use the Enums every-time when a variable seems to take the value definitely from the set of defined values.

Full Java Example to Demonstrate it:

public class EnumExample {

public enum Status {
APPROVED,DECLINED,IN-PROGRESS,PENDING,NEW
}

Status statusVal;

public EnumExample(Status statusVal) {
this.statusVal = statusVal;
}

public void statusDetails() {
switch (statusVal) {
case APPROVED:
System.out.println("Application has been approved");
break;

case DECLINED:
System.out.println("Application has been declined");
break;

case PENDING:
System.out.println("Application is in pending status");
break;

default:
System.out.println("Application is in New status");
break;
}
}

public static void main(String[] args) {
EnumExample approved = new EnumExample(Status.APPROVED);
approved.statusDetails();
EnumExample declined = new EnumExample(Status.DECLINED);
declined.statusDetails();
EnumExample pending = new EnumExample(Status.PENDING);
pending.statusDetails();

}
}
Output would be like: 
Application has been approved
Application has been declined
Application is in pending status



Some points to note about Enums:

* Enums are truely type safe. Means once the value is assigned to an enum  can not be overridden.
* Enum constants are implicitly static and final .
* Enum constants can only be created inside Enums itself. These can not be created using new operator. That's the reason Enums are preferred over the Singleton class.
* Enums can not be declared in a method.
* Enum constructors can have arguments.
* Enum constructors can be overloaded.

Thursday, June 23, 2016

Race Condition in Java

Many of us might be aware of Synchronization in Multi-threading environments in java. 
Race condition in Java is a type of concurrency error which is introduced in your program because  parallel execution of your program by multiple threads at same time, Since Java is a multi-threaded programming language hence risk of Race condition is higher in Java which demands clear understanding of what causes a race condition and how to avoid that. 

To Find Race conditions is very difficult, though since readability of Java code is very good and synchronized constructs are well defined heaps to find race conditions by code review. One can not find the race condition at the time of unit testing. Because race condition is the situation that won't occur often.  You can find the race condition in your program by reviewing it manually or you can use best code review tools available in the marketplace(try to find one such tool and let me know if you found that :).


Mostly it is reviewed that the collections like HashMap must be used with very much care as this is non-synchronized and multiple threads can apply for the re-size operation at the same time. Hence, it is recommended for you that if you are working in the multi-threaded application then use ConcurrentHashMap or use the synchronized HashMap which is again not recommended because of low performance in the multi-threaded environment.