Tuesday, 27 January 2015

Java 8: Lambdas



The latest version of Java, namely Java 8, has created quite a stir. Not just because it brings in an enhancement over the previous versions with its new Date API, repeating annotations, Java FX etc.  but more so because it makes room for some interesting features of functional programming paradigm in its otherwise truly object oriented kingdom. Two of these features are Lambda and the Streams API.

In this article we are going to talk about Lambda.
Historically, the concept of Lambda traces back to Lambda calculus formulated by Alonzo Church in the 1930s. In a crude interpretation a Lambda can be thought of as representing a function, most often an anonymous function. The concept slowly streamed into programming. Coming to think of it, the advent of computers and programming languages to communicate with them was paved by the need for performing complex mathematical calculations correctly and quickly. Hence the conceptual bonding between mathematics and computer programming. Anyways, it is useful to think of Lambdas as anonymous functions that can be assigned to variables, passed as an argument to functions and can be returned from functions. Many programming languages like Ruby, Python, Scala, JavaScript etc. already have built-in Lambda functionality. And now, Java 8 has accommodated it too. But Java, an inherently Objected Oriented language did some very clever tricks to retain backward compatibility and make this accommodation.

In the kingdom of Java everything is an object. But Lambdas are functions. How do they get ‘citizenship’? Hence, the introduction of the concept of a Functional Interface under which Lambdas could be classed.  But before delving into its nitty-gritty there is one important feature to take note of. Java 8 allows interfaces to have implementation of methods, typed as “default” and “static” methods. These implemented methods can be inherited and overridden just like the methods of “Abstract” classes. Yes, that brings interfaces closer to “Abstract” classes, but they are still interfaces. They still support “multiple-inheritance”, “Abstract” classes don’t.

Example of default and static methods in Java 8 interfaces.

public interface myFunctionalInterface{

    default void method1(){}
    static String doSomething(){ System.out.println("Do something");}

}

Now, a Functional Interface is a normal Java 8 interface that has exactly one abstract method. Sometimes they are tagged as SAM, Single Abstract Method. An annotation, namely “@FunctionalInterface” has also been introduced to mark such interfaces. And this would prompt a compile time error if the agreement is not adhered to, that is if more than one abstract method is introduced in the interface. 

@FunctionalInterface
public interface myFunctionalInterface2{
    public void myAbstractMethod();
    default void myDefaultMethod(){}
   //public void mySecAbstractMethod();  throws compile time error
}

So the type of a Lambda maps to the signature of the abstract method defined in the functional interface.This has been made possible because of the clever exploitation of InvokeDynamics, a feature introduced in Java 7.

Now that we are clear on the basics, let's get to know Lambdas through some short and simple sample programs  to enable a stronger grip on the concept.

Case: Existing SAM Interfaces
There are interfaces in Java written prior to Java 8 that have only one abstract method. And guess what, a Lambda can be supplied to such functional interfaces. 
 Example: Runnable r = () -> System.out.println("Lambda for runnable interface");
                 r.run(); //prints "Lambda for runnable interface"

Case: Overriding default method
Example: @FunctionalInterface
                 public interface myInterface1(){
                          default void methodTest(){ System.out.println("Test Method");}
                         public void abstractMethod();
                 }

                 public interface myInterface2 extends myInterface1(){
                           default void methodTest(){
                                   System.out.println("Overridden Test Method");
                           }
                  }


Case: Conflict scenario with default method
Example: @FunctionalInterface                                                   @FunctionalInterface
                  interface A{                                                                  interface B{
                        default void someMethod(){};                                       default void someMethod(){};
                       public void abstractMethodA();                                     public void abstractMethodB();
                  }                                                                                    }

                Class AB implements A,B{
                         .............}
               //A compile error would be thrown if class AB does not explicitly specify which 'someMethod()' it refers to OR provides its own implementation of 'someMethod()'
                                                                             
Case: Multiple-inheritance with default methods
 Example: @FunctionalInterface
                  interface Parent{
                         default void testOne() {
                              System.out.println("Test Parent");
                         }
                         public void abstractMethod();
                  }

                  @FunctionalInterface
                   interface Child extends Parent{
                           @Override
                            default void testOne(){
                                        System.out.println("Test Child");
                            }
                            public void abstractChildMethod();
                    }

                  class Test implements Child{
                          ...........}

                  Invoking testOne() on an instance of Test class would print "Test Child"

 
Case: Local Variable access within Lambda
Local variable which are declared final or effectively final, meaning their values are not modified are accessible within Lambda.
Example: public void someMethod(){
                          int x = 10;
                          Runnable r = () -> System.out.println("The variable is: "+x);
                          r.run();
                 }

Case: Using one of the functional interfaces provided in java.util.* package
There are some 43 functional interfaces provided in Java 8. Supplier, Consumer, Predicate etc. for ease of use by the developers. One can simply provide a Lambda that matches the signature of the abstract method defined in these interfaces.
Example: Consumer<Integer> consumer = x -> System.out.println("Printing x: "+ x);
                List<Integer> list = Arrays.asList(34,22,12,456);
       
                list.forEach(consumer);
Case: Using existing custom methods as Lambda
Example: @FunctionalInterface
                 public interface FuncInterface1 {
                      public String encodePassword(String passwd, int id);
                  }
              public class SampleFunctionalIf{ 
                       public static FuncInterface1 sampleEncode(){
                              return (password,i) -> password.toLowerCase(); **
                       }
                      public static void doSomething(FuncInterface1 func){
                           String str = func.encodePassword("PassWord", 123);
                           System.out.println(str);
                      }   
                   public static void main(String[] args){
                           doSomething((password,i) -> password.toUpperCase()); **
               
                          FuncInterface1 f = sampleEncode();
                         doSomething(f);               
                    }
               }

Note: ** The underlined Lambdas map to the encodePassword() in the functional interface. Note that the signature of the Lambda has to match the signature of the abstract method.

Case: Method references
 Lambdas also allow referencing methods of classes or class instances using the "::" <colon> operator. 
Example: public class Person {
                    String firstName, lastName;
                    public Person(){
                          System.out.println("New Person created from default constructor");
                       }
                   }
                  
             public interface PersonFactory<P extends Person> {
                    P create(String fname, String lname);
             }

           public class MethodRefSample1 {
              public static void main(String[] args){
                     PersonFactory<Person> p = Person::new;
                     p.create("Carlie", "Hebdo");
               }
           } 

So, that’s how Lambdas make programming much more succinct, quick and easy. And of course, it could be used to write pretty complex codes as well.

In no way do the above examples cover the length and breadth of Lambdas, but they do provide a quick peek at what Lambda in Java 8 is all about and what it is capable of.


The Streams API exploits Lambdas to make it much easier to perform operations on Java Collections both sequentially and in parallel. Will talk more on Streams in another article.


Thursday, 9 October 2014

Setting-up JMeter in Master-Slave Mode

There is abundant material available on the net on setting up and using JMeter; but sometimes the sought bit of information gets lost amidst too much information. Hence, listing out the basic steps of setting up JMeter in master-slave mode.

  • Have Java 1.6 or higher installed on your system
  • Download Apache JMeter Download Link
  • Just unzip the downloaded file and place it at two suitable locations, say C:/Software/Tools/JMeterRoot/Slave and C:/Software/Tools/JMeterRoot/Master (two locations because remember, we need two instances of JMeter one running in Master and the other in Slave mode)
  •  Some other miscellaneous requirements can be found at the Apache Site 


Steps for setting up the Slave:
  • Go to the 'bin' directory where JMeter is placed, say C:/Software/Tools/JMeterRoot/Slave/bin)
  • Open the 'jmeter.properties' file (and update some properties)
  • Choose a port number at which the Slave is to run locally, say 6000 and then set this as the port number by updating:  server.rmi.localport=6000
  • Then pick another port number at which the Master would connect to the Slave, say 1664 and update the following two properties, server.rmi.port=1664 AND server_port=1664
  • And update the 'rmi create' attribute to true, that is; server.rmi.create=true
  • Next, pull up a console and go to this 'bin' directory and type 'jmeter-server.bat' (in case of a Windows System) or just 'jmeter-server' (in case of a *NIX System)
This  will bring up the JMeter console with an instance running as Slave.


Steps for setting up the Master:
  • Go to the 'bin' directory where JMeter is placed, say C:/Software/Tools/JMeterRoot/Master/bin
  • Open the 'jmeter.properties' file
  • Modify the property 'remote_hosts' and add the <hostname>:<port number> of all the Slaves that were set-up above, that is, remote_hosts=202.202.202.202:1664
  • Note: The port-number set in remote_hosts should be the same as the one set in server.rmi.port in the Slave(s)
  • Next, again bring up a console and go to this 'bin' directory and type 'jmeter.bat' (in case of a Windows System) or just 'jmeter' (in case of a *NIX System)
This will bring up the JMeter GUI of the Master instance from which the Slaves can be made to run by either doing a:
  • Run -> Remote Start -> Choosing the desired Slave OR
  • Run -> Remote Start All




And that's it, different loads maybe set on each Slave from the Master GUI. :)

NIO (Non-Blocking IO) and Asynchronous Calls

Came across the term NIO (introduced in Java 4, Java 7 has rolled out NIO2) in a recent project requirement. To me, there was a very thin line of difference in the concepts of having a REST Client use NIO vs. Asynchronous calls. Googling on the net did not provide a very succinct result either. Hence, based on the knowledge gathered here's the summary:

* Asynchronous implies non-real time. Imagine your newspaper-boy; he just drops the paper and goes off to the next house to deliver without waiting for you to open up and hand it over to you. That's asynchronous. Unlike the earlier times milkman who rings the bell and keeps waiting for you to appear with a container and collect the milk; which is synchronous.

*NIO - well, think of it as collecting stuff into a buffer and then taking from it. Imagine a water tap. People do not take drops from the tap; rather it is collected in some bucket or mug et al, that is buffered and then used. Just that the water in the bucket in terms of NIO happens to be the data we are interested in reading from or writing to. Hence, the use of 'buffers' in NIO.


So how does the above sit in terms of REST Client? Well, we were mainly bothered with Jersey Clients. Just note that Jersey also provides Synchronous and Asynchronous Clients. But neither are NIO. The API states it. But interestingly, Jersey has this feature of allowing the use of different Connectors (at Transport Layer). And one of these, namely GrizzlyConnectorProvider uses NIO at the Transport Layer which can be used with both Synchronous and Asynchronous Clients.

Ref# GrizzlyConnectorProvider


Aah, this is a rather short piece but the time spent in crunching out just these few facts did take us quite a while! ;)