Java equals() vs. compareTo() contract

1 05 2016

The definitions

Object’s equals(Object obj) method:

Indicates whether some other object is "equal to" this one

compareTo(T t) is an abstract method from Comparable interface and it:

Compares this object with the specified object for order. 
Returns a negative integer, zero, or a positive integer 
as this object is less than, equal to, or greater than the specified object.

The contract

That being said here seems to appear the contract between those two methods: compareTo should return 0 if equals returns true. This is yet another contract that the equals() is involved (mind the hashCode()). In fact the Comparable JavaDoc says it clearly:

It is strongly recommended, but not strictly required that 
(x.compareTo(y)==0) == (x.equals(y)).

Since it is not strictly required, the JavaDoc clears out things and says:

Generally speaking, any class that implements the Comparable interface 
and violates this condition should clearly indicate this fact. 
The recommended language is: 
"Note: this class has a natural ordering that is inconsistent with equals."

Natural ordering

A class should implement Comparable interface if it is eligible to natural ordering. Natural ordering is perceived as an order where an object can be compared to another of the same type (alphabetical comparison for String, numerical for Number or any other specific to your domain).

If your class does not have a natural ordering that is consistent with equals() but you still need to sort it, you should consider using the Comparator interface instead of Comparable.

In fact the String class follows the equals() and compareTo() contract and it sorts Strings alphabetically according to ASCII characters ordering. Note that this ordering sorts lowercase letters in front of upper case.

The BigDecimal breaks the contract

The BigDecimal class violates the recommendation and its equals() is not consistent with compareTo() inĀ  a matter of a scale. The documentation clearly states it:

according to equals(): 2.0 is not equal to 2.00
according to compareTo(): 2.0 is equal to 2.00

Why? Who knows. There are discussions that in physics for example the 2.0 definetely should not be considered as equal to 2.00 due to the precision. However in most of the domains the values can be considered as equal.

Problems when violating the contract

The problem that arises is for example putting the BigDecimal in a HashSet:

Set<BigDecimal> set = new HashSet<>();
set.add(new BigDecimal("0.20"));
...
if (set.contains(new BigDecimal("0.2")) { // Returns false, but should return true
    ...
}

Because of that the HashSet is usable with BigDecimal if you define the scale that its elements have. So if you put the number with two digits precision, you should always look for two digits precision as well.

The other solution is to use TreeSet, since it uses the compareTo() to search for elements (ignoring the scale). However the TreeSet is sorted as opposed to the HashSet. If you do not need sorting then you ahve to consider whether it hurts your performance (putting an element to the sorted set is more expensive – due to the sorting).





How to run jMeter tests on Jenkins

24 04 2016

If you monitor your system performance with Apache jMeter test suite, you can easily make it a part of your Continuous Integration and monitor the performance on a regular basis. You need to do three things:

  1. Put your Apache jMeter binary files on Jenkins machine
  2. Run jMeter tests in headless mode from Jenkins job, generating the xml test report
  3. Analyze reports with Jenkins Performance Plugin

Let’s get into details!

1. Put your jMeter binaries on Jenkins

Apache jMeter does not require installation so you can just copy the files that you currently use to the Jenkins server. Thanks to it you will have all the plugins ready to use. Then make sure that user that runs jenkins has access rights to execute jMeter.

2. Run jMeter tests from Jenkins job

Create Jenkins job and, as a Build Step, Execute Shell commands:

#remove previous reports
rm jMeter/reports/*.jtl -f

#run tests
$JMETER_PATH/jmeter -n 
     -t jMeter/suites/sampleSuite.jmx 
     -l jMeter/reports/sampleSuiteReport.jtl 
     -p jMeter/properties/user.properties

where:

  • $JMETER_PATH is a path where you put jMeter binaries (for example /opt/apache-jmeter-2.13/bin/)
  • -n param means that jMeter will be run in headless mode
  • – t jMeter/suites/sampleSuite.jmx is a test suite that you are going to run
  • -l jMeter/reports/sampleSuiteReport.jtl is a result report file that will be generated. This file will be interpreted by Jenkins Performance Plugin
  • -p jMeter/properties/user.properties is a properties file where you configure the report file format to XML (interpreted by default in Jenkins Performance Plugin)

By default the .jtl report file is in the csv format. Jenkins Performance Plugin can read the csv, however the default format for it is xml. By the same token I use user.properties file with one line indicating that the jtl output should be xml:

jmeter.save.saveservice.output_format=xml

3. Analyze reports with Jenkins Performance Plugin

Install the Performance Plugin on your Jenkins instance. To use it, add the Post Build Action to your job, providing the path to .jtl report files:

shot_3

Jtl files will be interpreted each time the job is executed. Moreover in the job page on Jenkins you have new option in menu: Performance Trend, where you can find (on graphs) how your performance was changing over time at each build:

shot_1





StackOverflow developer survey 2016

19 03 2016

StackOverflow,as most visited dev page, conducted a survey asking its visitors interesting questions and publishing interesting results. It’s worth to take a look at the results to know how the environment looks like:

http://stackoverflow.com/research/developer-survey-2016

This year, over fifty thousand developers shared where they work, what they build, and who they are. You are about to read the results of the most comprehensive developer survey ever conducted.





Automate Jenkins job creation with DSL

28 02 2016

Jenkins job creation in Web UI is simple but still – manual creation takes time. Depending on your coding and testing practices you may find it acceptable or burdensome and costly.

Jenkins DSL allows you to define Jenkins job in groovy script file, put it on VCS and allow Jenkins to create and execute jobs based on it. The another advantage is that you get your jobs versioned along with codebase.

So… is that hard? Having Jenkins configured to build your code it requires few steps to build jobs from DSL:

1. Install Jenkins Job DSL plugin

Simple thing to begin: go to your Jenkins’ Management page, find the Job DSL plugin and install it (https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin).

2.Create the Seed Job

That is the job that will create other jobs. Do it like any other job creation: Select the ‘New Item‘, give it a name (in my case ‘dsl-demo’) and select type of ‘Build a free-style software project‘ (or ‘Freestyle project’).

Remember to configure the Code Repository url and credentials where this job will do the checkout and find the DSL script files.

3. Configure DSL scripts files location

Then in your job configuration add build step named: ‘Process Job DSLs’ (provided by Job DSL plugin). I am going to use the script files located in the filesystem (Jenkins’ workspace), versioned in my git repo. All of them will be located under the Jenkins/jobs/ directory in my VCS with the .groovy extension. So the path in my config is:

Jenkins/jobs/*.groovy

Where I have one file as for now, named:

Jenkins/jobs/demoJob.groovy

Remember to follow naming conventions for files: script names may only contain letters, digits and underscores, but may not start with a digit

4. DSL Script file content

First of all to simply make Jenkins create the job it is sufficient to have such content in DSL script:

job('simpliest-job-ever') {
    steps {
        shell('echo hello from your automated job!')
    }
}

Here I am creating the job with a name ‘simpliest-job-ever’ with one step inside. The step is using shell plugin and executing the echo command.

5. Run Seed Job

Now is the time to push the DSL file to the git server and trigger the Seed Job execution. The effect found in Jenkins console after running my Seed job was:

Processing DSL script demoJob.groovy
Added items:
    GeneratedJob{name='simpliest-job-ever'}

So my job was created from DSL file.

6. Run newly created Job

Now, coming back to the Jenkins’ job list the new job actually is there. I did not set the triggers on it yet so I have to fire it manually.

Here is the result of executing my newly generated job, printed in Jenkins console:

Started by user LooksOK!
Building in workspace /var/lib/jenkins/jobs/simpliest-job-ever/workspace
+ echo hello from your automated 'job!'
hello from your automated job!
Finished: SUCCESS

Lovely, isn’t it? :>

Enhance your DSL script

Such a basic configuration and script file prooves that the whole thing works. Now is the time to enhance the scripts and make them creating the fully useful jobs. The plugins supported in DSL and their full documentation is here: https://github.com/jenkinsci/job-dsl-plugin/wiki/Job-DSL-Commands.

A list of most useful plugins is:

    • SCM to connect your Job with code repository
scm {
  git('git@github.com:yacekmm/looksok.git')
}
    • Triggers to setup the schedule on your job execution
triggers {
  scm('*/15 * * * *')
}
    • maven to execute maven tasks
maven('-e clean test')
    • shell to execute shell commands
shell('echo hello from your automated job!')
  • and more…

Thanks for reading, give it a try!

 





Run Protractor tests in Jenkins’ headless browser on Linux with Xvfb

13 02 2016

Automated GUI testing is a must for core buisness functionalities in an application. Running them frequently in an automated manner on Continuous Integration environment guarantees reliable results and gives confidence that system isn’t broken.

Test suite should be written in a way that does not require human attention, generates test report and is repetitive to allow investigation of results. That leads to the need of deploying tests on Continuous Integration server (e.g. Jenkins) and running them regurarly. Having Jenkins deployed on Linux without GUI you can’t run web browser in usual windowed mode – you need to use so called headless mode. Headless software is a software available to work without a Graphical User Interface.

Components

The configuration is built upon following components:

  1. Protractor tests – regular test suites that are fired on usual configuration with GUI
  2. Grunt configuration to run protractor tests
  3. Firefox browser installed on Jenkins’ Linux Operating System (CentOS in my case)
  4. Xvfb installed on Jenkins’ host OS. Xvfb is a software that emulates GUI for non GUI systems
  5. Grunt plugins set to run Protractor tests in a non GUI environment
  6. Jenkins job configuration to run your job in a scheduled, regular manner

Find the configuration details below.

1. Protractor tests

These are the test suites you run on your regular development machine and need to run them on Jenkins.

2. Grunt configuration

My tests are fired from command line with grunt-protractor-runner plugin (https://www.npmjs.com/package/grunt-protractor-runner). Plugin provides the protractor: task and requires config file where you specify all the options: spec files (suites), your system URL (baseUrl), as well as any custom params (params) that you can refer in your specs or browser you run your test against. Check the configuration details and instructions on plugin page.

3. Firefox browser

You can use the browsers of your choice. In my case this is the firefox. On CentOS the installation command is:

yum install firefox

3. Xvfb

This is the key component of running tests in headless mode. Xvfb is a virtual display frame buffer for X – the display system used by Linux. It provides a fake display buffer for graphical programs. This way it allows any program to run headlessly.

To install Xvfb on CentOS execute:

yum install xorg-X11-server-Xvfb

Xvfb usage is simple. To open certain url in browser execute:

xvfb-run firefox https://looksok.wordpress.com

This way you make sure that xvfb is available on your PATH and it opens the firefox application in headless mode with an url as a param.

4. Grunt plugins

To tie it up all together I use Grunt with plugins that starts xvfb buffer: grunt-env (https://github.com/jsoverson/grunt-env) and grunt-shell (https://github.com/cri5ti/grunt-shell-spawn). Whole configuration is described here: https://gist.github.com/nwinkler/f0928740e7ae0e7477dd

The idea behind that config is to execute shell command that create a new display before test. After the test is done, the display is killed.

5. Jenkins job configuration

This is an usual part of the setup. Simply make a new job that will fire up your protractor tests on a schedule you define. In my case Jenkins executes the grunt task:

grunt protractor-xvfb

In most cases that’s all the Jenkins job does. If your your system is already built and running, that Jenkins config enough. You can just target your tests against your running instance.

In my case Jenkins task is more complex. First it checkouts the repository for newest code version, then builds artifacts, starts all system components, fires tests and kills system that it has started. And it all works as a charm :)

 





Java 8 StringJoiner demo

24 01 2016

Finally Java has convenient and intuitive API for joining strings with delimiters! Since Java 8 there is StringJoiner class. It is an API that you may know from Guava Joiner classes (see my post: https://looksok.wordpress.com/2015/10/17/guava-joiner-join-all-strings-in-an-array-or-map/). Here is a short StringJoiner demo.

Basic String joins

The most basic usage is to create StringJoiner instance with delimiter as a constructor param and add() strings:

StringJoiner joiner = new StringJoiner(",");
joiner.add("apple");
joiner.add("banana");
joiner.add("orange");

System.out.println("Joiner result is: " + joiner.toString());

The result is:

Joiner result is: apple,banana,orange

If you prefer, you can chain add() calls:

StringJoiner joiner = new StringJoiner(",")
    .add("apple")
    .add("banana")
    .add("orange");

Join Collection of Strings

If you have Collection of Strings, the new static String.join() method can join them:

List<String> list = Arrays.asList("apple", "banana", "orange");
String joined = String.join(", ", list);

System.out.println("Join Array result is: " + joined);

With the result of:

Join Array result is: apple, banana, orange

Join inline

You can prepare joined String in one line with String.join() overloaded with varargs, like that:

String.join(", ", "apple", "banana", "orange");

Joining Collector in Stream API

When using streams you have joining Collector at your disposal:

List<String> list = Arrays.asList("apple", "banana", "orange");
String joined = list.stream()
        .collect(Collectors.joining(", "));

System.out.println("Joined with collector: " + joined);

This will result with:

Joined with collector: apple, banana, orange

Source Code

As always, I share with you the source code for this demo on my github: https://github.com/yacekmm/looksok/tree/StringJoinerDemo/Java/JavaDemo





Asynchronous Producer Consumer with BlockingQueue in Java

19 12 2015

What is it

Producer Consumer pattern is used when one module (producer) produces events, messages or any other kind of data with various pace and the other module (consumer) processes it when the data occur. The asynchronous version means that the producer does not wait until consumer processes each item – just sends it to consumer and forgets about it. The consumer consumes it when its turn comes.

How it works? BlockingQueue

Technically Producer puts events into FIFO BlockingQueue and Consumer takes the event one by one. The queue instance is shared among both actors, so that they can access is. BlockingQueue API has two main operations:

  • put() used by Producer to add new item (if the queue is bounded and is full, the put() method will block the Producer thread until there is a space to add new item)
  • take() used by Consumer to take next event to process (if the queue is empty, the consumer will be blocked until the event occur)

One more API method that is a good practice to use over the take() is:

  • offer() used by the producer to put() with maximum timeout to block producer thread when the queue is full. The offer() method returns boolean result saying if put was successful or not. This value should be interpreted in your code.

There are two BlockingQueue implementations:

  • ArrayBlockingQueue that has to be bounded and is more performant (use it if your case uses constant queue size)
  • LinkedBlockingQueue that can be bounded or not (in fact it is then bounded to Integer.MAX_VALUE) but can be less performant because of that

BlockingQueue is thread-safe and does not accept null values.

Work Unit

It is also a good practice to wrap your messages put in the queue in a wrapper that holds the message and returns it when consumer needs it. The reason to introduce this level of indirection is to be able to add additional data to the Producer Consumer mechanism that your message does not need. That can be:

  • performance metrics indicating when and how fast your messages are processed
  • testing to track the changes in your object

Work unit implementation according to this practice is:

public class MyEventWorkUnit<T> {

    private T myEventWorkUnit;

    public MyEventWorkUnit(T myEventWorkUnit) {
        this.myEventWorkUnit = myEventWorkUnit;
    }

    public T getWorkUnit() {
        return myEventWorkUnit;
    }
}

Then your BlockingQueue holds this type:

BlockingQueue<MyEventWorkUnit<MyEvent>> queue

The MyEvent class is a simple object that can handle itself when asked and has externally generated id. Notice that handle() method sleeps thread to simulate that handling events takes certain amount of time:

public class MyEvent {

    private static final Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());

    private final int eventId;

    public MyEvent(int eventId) {
        this.eventId = eventId;
    }

    public void handle() {
        log.info("Serving event with id: " + eventId);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

 

Producer Consumer implementation

My Producer generates 10 events and puts it into queue with offer() method with a timeout. This is the implementation:

public class EventProducer extends Thread {
    private final BlockingQueue<MyEventWorkUnit<MyEvent>> queue;
    private AtomicInteger idGenerator;

    public static final Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

    public EventProducer(BlockingQueue<MyEventWorkUnit<MyEvent>> queue) {
        this.queue = queue;
        idGenerator = new AtomicInteger();
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            boolean wasAdded = false;
            MyEvent eventToAdd = new MyEvent(idGenerator.getAndIncrement());
            try {
                wasAdded = queue.offer(new MyEventWorkUnit<>(eventToAdd), 100, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                log.info("Adding Thread was interrupted");
            } finally {
                handleAddResult(wasAdded, eventToAdd);
            }
        }
    }
    
    ...
}

My consumer simply takes events from the queue and handles them:

public class EventConsumer extends Thread{
    private final BlockingQueue<MyEventWorkUnit<MyEvent>> queue;

    public EventConsumer(BlockingQueue<MyEventWorkUnit<MyEvent>> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while(true){
            try {
                MyEventWorkUnit<MyEvent> workUnit = queue.take();
                workUnit.getWorkUnit().handle();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Producer Consumer Construction

I create the ArrayBlockingQueue instance with size bounded to 3 items. This is not enough to handle fast-producing and slow consuming Threads. I limit the size to show how offer() timeouts helps to handle such situations:

BlockingQueue<MyEventWorkUnit<MyEvent>> queue = new ArrayBlockingQueue<>(3);

EventProducer producer = new EventProducer(queue);
EventConsumer consumer = new EventConsumer(queue);

producer.start();
consumer.start();

The result

Notice that:
1. the event (id=0) is immediately added and served. Service takes some time
2. the events with ids 1, 2, 3 are added to the queue, event with id=0 is still being served
3. events 4, 5, 6, and 7 are not added to the queue since it’s full so the timeout occur
4. event id=1 is served by the consumer. There is room for one more event in the queue
5. event id = 8 is added successfully to the queue, event id=9 is rejected due to timeout
6. all events from the queue are handled

INFO: Event was added to the queue: MyEvent{eventId=0}
INFO: Serving event with id: 0
INFO: Event was added to the queue: MyEvent{eventId=1}
INFO: Event was added to the queue: MyEvent{eventId=2}
INFO: Event was added to the queue: MyEvent{eventId=3}
WARNING: Unable to add event to queue due to timeout: MyEvent{eventId=4}
WARNING: Unable to add event to queue due to timeout: MyEvent{eventId=5}
WARNING: Unable to add event to queue due to timeout: MyEvent{eventId=6}
WARNING: Unable to add event to queue due to timeout: MyEvent{eventId=7}
INFO: Serving event with id: 1
INFO: Event was added to the queue: MyEvent{eventId=8}
WARNING: Unable to add event to queue due to timeout: MyEvent{eventId=9}
INFO: Serving event with id: 2
INFO: Serving event with id: 3
INFO: Serving event with id: 8

Source Code
You can run this sample on your own. Get the conde from my GitHub: https://github.com/yacekmm/looksok/tree/ProducerConsumer/Java/BlockingQueue

Inspirations

This post was inspired by the book ‘Well Grounded Java Developer’ and sites: http://ashkrit.blogspot.com/2014/01/java-queues-bad-practices.html, http://javarevisited.blogspot.com/2012/12/blocking-queue-in-java-example-ArrayBlockingQueue-LinkedBlockingQueue.html








%d bloggers like this: