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/


  • $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/ 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 file with one line indicating that the jtl output should be 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:


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:



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:

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 (

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:


Where I have one file as for now, named:


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:

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:

A list of most useful plugins is:

    • SCM to connect your Job with code repository
scm {
    • 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.


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 ( 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

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 ( and grunt-shell ( Whole configuration is described here:

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: 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(",");

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(",")

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 =
        .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:

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() {"Serving event with id: " + eventId);
        try {
        } catch (InterruptedException e) {


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();

    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) {
      "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;

    public void run() {
            try {
                MyEventWorkUnit<MyEvent> workUnit = queue.take();
            } catch (InterruptedException e) {

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);


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:


This post was inspired by the book ‘Well Grounded Java Developer’ and sites:,

Java 7 NIO.2 Paths to make path handling easy for you

12 12 2015

Java 7 introduced a big change in file and directory structure manipulation API. Now you have:

  • Path that represents locacation in a filesystem (filesystem can be Windows, *nix or a zip archive)
  • Files to deal with directory trees (walk directory tree, iterate over files in directory, filter files, perform recursive move, copy, delete)
  • WatchService to listen for the changes in file
  • File attributes access like size, permissions, modification time
  • Symbolic links detection and support
  • Asynchronous I/O operations (with Future or callback style) for processing big files without impact on main application Thread

Now its time for short demo of new Path features. See the demo source code on my GitHub:

Creating a Path

See how to get the absolute path to the current working directory:

Path path = Paths.get("").toAbsolutePath();
System.out.println("Current working dir absolute path is: " + path);

Current absolute path is:


Path properties

On linux system you can analyze the path properties with some convenient methods:

path = Paths.get("/var/lib/jenkins/jobs/sampleJob");
System.out.println("\nSample linux path that will be analyzed: " + path.toAbsolutePath());
System.out.println("Number of segments in path: " + path.getNameCount());
System.out.println("Parent in path: " + path.getParent());
System.out.println("Root on this filesystem: " + path.getRoot());
System.out.println("Subpath (2 elements up): " + path.subpath(path.getNameCount() - 2, path.getNameCount()));

Notice that I’ve created linux Path on Windows machine. This is possible because path is an abstract concept that may point to non existing resource. Because it can be a path to resource that you are just about to create in that Path. Meaning that the path existence will be verified already when you want to do something in this location.

The properties check result is:

Sample linux path that will be analyzed: C:\var\lib\jenkins\jobs\sampleJob
Number of segments in path: 5
Parent in path: \var\lib\jenkins\jobs
Root on this filesystem: \
Subpath (2 elements up): jobs\sampleJob

Symbolic link path finding

When you work with paths containing Symbolic links (kind of shortcuts to the target file on linux OS) you need to know whether it is a file or symlink and get the real location of the file behind the link. Do it with:

path = Paths.get("/var/log/logFile");
System.out.println("Real symlink path: " + path.toRealPath());

getRealPath() throws IOException if Path does not exist. You can also getRealPath(LinkOptions.NOFOLLOW_LINKS) if you want a symlink file path, not the element behind it.

Converting paths

In NIO.2 you can easily join Paths, create a Path between two other Paths, and compare Paths against each other. This is how you join paths

Path currentDir = Paths.get("");
Path relativeConfigPath = Paths.get("conf/");
Path propertiesFilesPath = currentDir.resolve(relativeConfigPath);

The resolved path is:


Path between two other Paths

This is how to get the relative path between two other Paths:

Path logsDir = Paths.get("/var/log/myapp");
Path appDir = Paths.get("/var/lib/myapp");
Path relativePathToLogs = appDir.relativize(logsDir);

And the result is a relative path:


NIO.2 and existing Java’s File class

You can now refactor pre Java 7 code to use new constructs, however if you need to interact with old APIs using File class, be noticed that File has now toPath() method, as well as the Path having its toFile() equivalent:

File file = new File("./");
Path pathFromFile = file.toPath();
file = pathFromFile.toFile();

%d bloggers like this: