Detect Absence of Events - WSO2 Siddhi Pattern

Detect Absence of Events - WSO2 Siddhi Pattern

WSO2 Siddhi an opensource complex event processing engine which is used to power the WSO2 Analytics Server received a new feature from GSoC project: Non-Occurrence of Events for Siddhi Patterns. Until Siddhi 3.x, patterns can detect only the events that have arrived but building patterns based on events that have not arrived is an essential requirement and even there were questions on StackOverflow regarding this problem:
This article introduces the new pattern to detect absence of events along with its limitations and sample use cases. In order to get a clear idea, let's begin with a sample use case.
This feature is available from Siddhi v4.0.0-M50. Those who prefer stable version have to wait until Siddhi v4.0.0.
Read More
Why should I have supertype reference & subclass object?

Why should I have supertype reference & subclass object?

Just now I've got an email from one of my student with the following question: "Why should we create Animal obj = new Dog(); instead of Dog obj = new Dog();" Of course the example given here is made by myself but the question in detail is why all use super interface or superclass reference instead of using the same class reference. You got the question right? This article answers the question.

The answer is: "It is a best practice being followed by our ancestors. Stop asking questions and code that way :-)" 

Ok, more seriously, consider the following example:

There is a SuperFancyClass created by developer A for some super fancy purposes. Note that all the references are HashMap.
import java.util.HashMap;

public class SuperFancyClass {
    
    private HashMap<String, Object> mapOne;
    private HashMap<Integer, Object> mapTwo;

    public SuperFancyClass() {
        this.mapOne = new HashMap<>();
        this.mapTwo = new HashMap<>();
    }

    public HashMap<String, Object> doStuff1() {
        // Do something
        return this.mapOne;
    }

    public HashMap<String, Object> doStuff2() {
        // Do something
        return this.mapOne;
    }

    public HashMap<Integer, Object> doStuff3() {
        // Do something
        return this.mapTwo;
    }

    // Some other highly complex code here
}
That class is being used by developer B as given below.
import java.util.HashMap;

public class SensitiveAgent {

    public static void main(String[] args) {
        
        SuperFancyClass superFancy = new SuperFancyClass();
        HashMap<String, Object> map1 = superFancy.doStuff1();
        HashMap<String, Object> map2 = superFancy.doStuff2();
        HashMap<Integer, Object> map3 = superFancy.doStuff3();
    }

    // Some other highly complex code here
}
Assuming both classes are highly complex but both developers A and B are happy with what they have, there is nothing else to worry.

As time progress, now developer A wants to make his Maps to maintain the insertion order. The Java API says, HashMap does not respect the insertion order so if you need insertion order, you need to switch to LinkedHashMap.

So now developer A wants to find and replace all of his/her HashMaps by LinkedHashMap. But this will not be such a short happy ending story in a highly complex codebase where there can be several other local HashMaps which cannot be replaced by LinkedHashMap. So in reality, developer A has to go and change everywhere it requires LinkedHashMap as provided below.
import java.util.LinkedHashMap;

public class SuperFancyClass {
    
    private LinkedHashMap<String, Object> mapOne;
    private LinkedHashMap<Integer, Object> mapTwo;

    public SuperFancyClass() {
        this.mapOne = new LinkedHashMap<>();
        this.mapTwo = new LinkedHashMap<>();
    }

    public LinkedHashMap<String, Object> doStuff1() {
        // Do something
        return this.mapOne;
    }

    public LinkedHashMap<String, Object> doStuff2() {
        // Do something
        return this.mapOne;
    }

    public LinkedHashMap<Integer, Object> doStuff3() {
        // Do something
        return this.mapTwo;
    }

    // Some other highly complex code here
}
But now the code of developer B collapses because of the changes in SuperFancyClass. Then developer B has to go and change the references from HashMap to LinkedHashMap as shown below.
import java.util.LinkedHashMap;

public class SensitiveAgent {

    public static void main(String[] args) {
        
        SuperFancyClass superFancy = new SuperFancyClass();
        LinkedHashMap<String, Object> map1 = superFancy.doStuff1();
        LinkedHashMap<String, Object> map2 = superFancy.doStuff2();
        LinkedHashMap<Integer, Object> map3 = superFancy.doStuff3();
    }

    // Some other highly complex code here
}

Rule of debugging:

Now, this is the time to introduce an important rule of debugging:
Fixing a bug is equivalent to making several other bugs.
In other words, if you modify an existing code, the number of changes you have made will be proportional to the number of newly expected bugs because we are all human and we do mistakes. Without our intention, we might delete a local variable that hides an instance variable. Or else we might modify that single line which causes to bring the entire world to end. So always keep your changes as less as possible.

Coming back to the previous scenario, developer A modifies the SuperFancyClass in 7 places and developer B has to modify the SensitiveAgent in 3 places. Even in a code-base which contains two dummy classes, there are 10 places altogether to modify. Just imagine a project with hundreds/thousands of classes and millions of lines. Yep, they do exist and it will be catastrophic.

Time to travel back...
Suppose if the developer A designed his/her class as given below using super interface references (However the objects must be created using a subclass. See the constructor):
import java.util.Map;
import java.util.HashMap;

public class SuperFancyClass {
    
    private Map<String, Object> mapOne;
    private Map<Integer, Object> mapTwo;

    public SuperFancyClass() {
        this.mapOne = new HashMap<>();
        this.mapTwo = new HashMap<>();
    }

    public Map<String, Object> doStuff1() {
        // Do something
        return this.mapOne;
    }

    public Map<String, Object> doStuff2() {
        // Do something
        return this.mapOne;
    }

    public Map<Integer, Object> doStuff3() {
        // Do something
        return this.mapTwo;
    }

    // Some other highly complex code here
}
The developer B would develop his/her code like this because the return types of those methods are Map; the super interface:
import java.util.Map;

public class SensitiveAgent {

    public static void main(String[] args) {
        
        SuperFancyClass superFancy = new SuperFancyClass();
        Map<String, Object> map1 = superFancy.doStuff1();
        Map<String, Object> map2 = superFancy.doStuff2();
        Map<Integer, Object> map3 = superFancy.doStuff3();
    }

    // Some other highly complex code here
}
Now if the same situation comes where the developer A wants to preserve insertion order in his/her maps, only lines he/she has to change are just those two lines inside the constructor as shown below:
import java.util.Map;
import java.util.LinkedHashMap;

public class SuperFancyClass {
    
    private Map<String, Object> mapOne;
    private Map<Integer, Object> mapTwo;

    public SuperFancyClass() {
        this.mapOne = new LinkedHashMap<>();
        this.mapTwo = new LinkedHashMap<>();
    }

    public Map<String, Object> doStuff1() {
        // Do something
        return this.mapOne;
    }

    public Map<String, Object> doStuff2() {
        // Do something
        return this.mapOne;
    }

    public Map<Integer, Object> doStuff3() {
        // Do something
        return this.mapTwo;
    }

    // Some other highly complex code here
}
Developer B does not need to change anything because there is nothing changed in the API level (return types are not changed by developer A). So now the same behavior is achieved with less number of modifications (This time only 2). This is what we call extensible, modifiable, (all those blah-blah-blah-able) code.

Then why not Object instead of Map?
Now you may have a question: Should we always use the super most interface/class as the reference? Not always. It depends on the requirements. Climbing towards super types means, we are limiting the features because 99% of the time, subclasses have more features than supertypes. For example, compare java.lang.Number with its subclasses or compare java.util.Collection with its subinterfaces/classes. So use the supertype reference which has all the functionalities you are expected to have.

Is the rule applied to local variables?
Then what is the advantage of using super reference in local variables which have no impact on others? I guess this is because we developers are used to that and there is nothing wrong with following the same practice in local variables. For example, consider this case:
import java.util.List;
import java.util.ArrayList;

public class HelloWorld {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");
        System.out.println(list);
    }
}
In this code, there is no advantage of using super interface reference but I do write this way because I am used to it. If there are no disadvantages, why do you bother with it? Keep calm and code your references in supertype :-)
Read More

Microservices Framework for Java (MSF4J) - HelloWorld!

In a recent article: Microservices in a minute, I have introduced a lightweight microservice framework: WSO2 MSF4J. That tutorial shows you how to create a microservice in minutes using the Maven archetype. However, the libraries available in the public Maven repositories are bit older and there are new releases after MSF4J 2.0.1 which are available in WSO2's Maven repository. This article shows you how to create a microservice using the latest stable release of MS4J Framework.

Requirements:
  • Java Development Kit 1.8
  • Apache Maven 3.x
  • Postman or CURL
  • Eclipse IDE for Java EE Developers / Any IDEs with Maven support
Read More

Install Oracle JDK 8 on Linux

Oracle Java is the proprietary, reference implementation for Java. This is no longer currently available in a supported Ubuntu repository. This article shows you the way to manually install the latest Oracle Java Development Kit (Oracle JDK) in Ubuntu.


Note: This article uses JDK8_Update_$java_update_no to demonstrate the installation. In the provided commands, replace the version specific paths and file names to your downloaded version.

Oracle JDK 9 has some differences in its directory structure. Therefore, another article on how to install Oracle JDK 9 is available here: Install Oracle JDK 9 on Linux

Step 1:
Download the latest JDK(jdk-Xuxx-linux-xXX.tar.gz) from this official link.
If you want to download to a remote server or if you simply prefer wget, use the command given in this Stackoverflow answer: Downloading JDK
Read More

Parse PCAP files in Java

This article is for those who have spent hours like me to find a good library that can parse raw PCAP files in Java. There are plenty of open source libraries already available for Java but most of them are acting as a wrapper to the libpcap library which makes them hard to use for simple use cases. The library I came across: pkts is a pure Java library which can be easily imported into your project as a Maven dependency. This article introduces the pkts library using a HelloWorld application to parse a PCAP output.

Requirements:
  • Java IDE with Maven support (Eclipse IDE for Java EE is used here)
  • The PCAP file you want to parse
Read More

Microservices in a minute

Microservices get more light in recent years as a new service oriented architecture with a high level of modularity. Compared to traditional web services either they are SOAP or REST, microservices are small in size and complexity but brings the cohesiveness to web services. Microservices do not require a servlet container or web server to be deployed instead they are created as individual JAR files which you can run as any other JAR files. The idea behind microservices is creating tiny individual services which can be developed, deployed and modified with less effort. This article introduces microservices using WSO2 Microservices Framework in a minute.

Microservices in a minute
Image Credits: http://wso2.com/blogs/thesource/2016/05/enabling-microservice-architecture-with-middleware/

WSO2 Microservices Framework for Java (WSO2 MSF4J) is a lightweight annotation based model to develop microservices in Java. Developers can create a microservice using just two or three classes which of course require a framework to take care of the householding tasks. The MSF4J hides all the complexities of creating a web service and provide a decent API to develop microservices in minutes. Let's dirt your hands with microservices:

Read More

Contact Form

Name

Email *

Message *