Quantcast
Channel: Baeldung
Viewing all 3702 articles
Browse latest View live

Intro to Gatling

$
0
0

1. Overview

Gatling is a load testing tool that comes with excellent support of the HTTP protocol – which makes it a really good choice for load testing any HTTP server.

This quick guide will show you how to setup a simple scenario for load testing an HTTP server.

Gatling simulation scripts are written in Scala, but don’t worry – the tool comes to help us with a GUI allowing us to record the scenario. Once we have finished recording the scenario the GUI create the Scala script representing the simulation.

After running the simulation we have a ready-to-present HTML reports.

Last but not least, Gatling’s architecture is asynchronous. This kind of architecture lets us implement virtual users as messages instead of dedicated threads, making them very resource cheap. Thus, running thousands of concurrent virtual users is not an issue.

It’s also worth noting though that the core engine is actually protocol agnostic, so it’s perfectly possible to implement support for other protocols. For example, Gatling currently also ships JMS support.

2. Creating a Project Using the Archetype

Although we can get Gatling bundles as a .zip we choose to use Gatling’s Maven Archetype. This allows us to integrate Gatling and run it into an IDE and make it easy to maintain the project in a version control system. Be careful as Gatling require a JDK8.

From the command line, type:

mvn archetype:generate

Then, when prompted:

Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains):

Type:

gatling

You should then see:

Choose archetype:
1: remote -> 
  io.gatling.highcharts:gatling-highcharts-maven-archetype (gatling-highcharts-maven-archetype)

Type:

1

to select the archetype, then select the version to use (choose the latest version).

Select the groupId, artifactId, version and package name for the classes before confirming the archetype creation.

Finish by importing the archetype into an IDE – for example into the Scala IDE (based on Eclipse) or into IntelliJ IDEA.

3. Define a Scenario

Before launching the recorder, we need to define a scenario. It will be a representation of what really happens when users navigate a web application.

In this tutorial, we will use the application provided by the Gatling’s team for sample purpose and hosted at the URL http://computer-database.gatling.io.

Our simple scenario could be:

  • A user arrives at the application.
  • The user searches for ‘amstrad’.
  • The user opens one of the related models.
  • The user goes back to home page.
  • The user iterates through pages.

4. Configuring the Recorder

First of all launch the Recorder class from the IDE. Once launched, the GUI lets you configure how requests and responses will be recorded. Choose the following options:

  • 8000 as listening port
  • org.baeldung.simulation package
  • RecordedSimulation class name
  • Follow Redirects? checked
  • Automatic Referers? checked
  • Black list first filter strategy selected
  • .*\.css, .*\.js and .*\.ico in the black list filters
setting

Now we have to configure our browser to use the defined port (8000) chosen during the configuration. This is the port our browser must connect to so that the Recorder is able to capture our navigation.

Here is how to do with Firefox, open the browser Advanced settings, then go to the Network panel and update the connection settings:

proxy settings

5. Recording the Scenario

Now that everything is configured we can record the scenario that we have defined above. The step are the following:

  1. Initiate the recording by clicking the ‘Start’ button
  2. Go to the website: http://computer-database.gatling.io
  3. Search for models with ‘amstrad’ in their name
  4. Select ‘Amstrad CPC 6128’
  5. Go back to home page
  6. Iterates several times through the model pages by clicking on Next button
  7. Click on ‘Stop & save’ button

The Simulation will be generated in the package org.baeldung defined during the configuration under the name RecordedSimulation.scala

6. Run a Simulation with Maven

To run our recorded simulation we need to update our pom.xml:

<plugin>
    <groupId>io.gatling</groupId>
    <artifactId>gatling-maven-plugin</artifactId>
    <version>2.2.0</version>
    <executions>
        <execution>
            <phase>test</phase>
            <goals><goal>execute</goal></goals>
        </execution>
    </executions>
</plugin>

This let us execute the simulation at test phase. To start the test just run:

mvn test

When the simulation is done, the console will display the path to the HTML reports.

7. Reviewing the Result

If we open the index.html at the suggested location the reports look like as follow:

reports

8. Conclusion

In this tutorial we have explored load testing an HTTP server with Gatling. The tools allows us to record a simulation based on a defined scenario with the help of a GUI interface. After the recording is done we can launch our test. The test report will be in a form of HTML resume.

To build up our example we have chosen to use a maven archetype. This help us to integrate Gatling and run it into an IDE and make it easy to maintain the project in a version control system.

The example code can be found in the GitHub project.


Intro to XPath with Java

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this article we’re going to go over the basics of XPath with the support in the standard Java JDK.

We are going to use a simple XML document, process it and see how to go over the document to extract the information we need from it.

XPath is a standard syntax recommended by the W3C, it is a set of expressions to navigate XML documents.  You can find a full XPath reference here.

2. A Simple XPath Parser

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;

public class DefaultParser {
    
    private File file;

    public DefaultParser(File file) {
        this.file = file;
    }
}

Now lets take a closer look to the elements you will find in the DefaultParser:

FileInputStream fileIS = new FileInputStream(this.getFile());
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Tutorials/Tutorial";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

Let’s break that down:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

We will use this object to produce a DOM object tree from our xml document:

DocumentBuilder builder = builderFactory.newDocumentBuilder();

Having an instance of this class, we can parse XML documents from many different input sources like InputStream, File, URL and SAX:

Document xmlDocument = builder.parse(fileIS);

A Document (org.w3c.dom.Document) represents the entire XML document, is the root of the document tree, provides our first access to data:

XPath xPath = XPathFactory.newInstance().newXPath();

From the XPath object we’ll access the expressions and execute them over our document to extract what we need from it:

xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

We can compile an XPath expression passed as string and define what kind of data we are expecting to receive such a NODESET, NODE or String for example.

3. Lets Start

Now that we took a look to the base components we will use, lets start with some code using some simple XML, for testing purposes:

<?xml version="1.0"?>
<Tutorials>
    <Tutorial tutId="01" type="java">
        <title>Guava</title>
	<description>Introduction to Guava</description>
	<date>04/04/2016</date>
	<author>GuavaAuthor</author>
    </Tutorial>
    <Tutorial tutId="02" type="java">
        <title>XML</title>
	<description>Introduction to XPath</description>
	<date>04/05/2016</date>
	<author>XMLAuthor</author>
    </Tutorial>
</Tutorials>

3.1. Retrieve a Basic List of Elements

The first method is a simple use of an XPath expression to retrieve a list of nodes from the XML:

FileInputStream fileIS = new FileInputStream(this.getFile());
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fileIS);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Tutorials/Tutorial";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

We can retrieve the tutorial list contained in the root node by using the expression above, or by using the expression “//Tutorial” but this one will retrieve all <Tutorial> nodes in the document from the current node no matter where they are located in the document, this means at whatever level of the tree starting from the current node.

The NodeList it returns by specifying NODESET to the compile instruction as return type, is an ordered collection of nodes that can be accessed by passing an index as parameter.

3.2. Retrieving an Specific Node by its ID

We can look for an element based on any given id just by filtering:

DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(this.getFile());
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Tutorials/Tutorial[@tutId=" + "'" + id + "'" + "]";
node = (Node) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODE);

By using this kind of expressions we can filter for whatever element we need to look for just by using the correct syntax. These kind of expressions are called predicates and they are an easy way to locate specific data over a document, for example:

/Tutorials/Tutorial[1]

/Tutorials/Tutorial[first()]

/Tutorials/Tutorial[position()<4]

You can find a complete reference of predicates here

3.3. Retrieving Nodes by a Specific Tag Name

Now we’re going further by introducing axes, lets see how this works by using it in an XPath expression:

Document xmlDocument = builder.parse(this.getFile());
this.clean(xmlDocument);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//Tutorial[descendant::title[text()=" + "'" + name + "'" + "]]";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

With the expression used above, we are looking for every <Tutorial> element who has a descendant <title> with the text passed as parameter in the “name” variable.

Following the sample xml provided for this article, we could look for a <title> containing the text “Guava” or “XML” and we will retrieve the whole <Tutorial> element with all its data.

Axes provide a very flexible way to navigate an XML document and you can find a full documentation it the official site.

3.4. Manipulating Data in Expressions

XPath allows us to manipulate data too in the expressions if needed.

XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//Tutorial[number(translate(date, '/', '')) > " + date + "]";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

In this expression we are passing to our method a simple string as a date that looks like “ddmmyyyy” but the XML stores this data with the format “dd/mm/yyyy“, so to match a result we manipulate the string to convert it to the correct data format used by our document and  we do it by using one of the functions provided by XPath

3.5. Retrieving Elements from a Document with Namespace Defined

If our xml document has a namespace defined as it is in the example_namespace.xml used here, the rules to retrieve the data we need are going to change since our xml starts like this:

<?xml version="1.0"?>
<Tutorials xmlns="http://www.baeldung.com/full_archive">

</Tutorials>

Now when we use an expression similar to “//Tutorial”, we are not going to get any result.  That XPath expression is going to return all <Tutorial> elements that aren’t under any namespace, and in our new example_namespace.xml, all <Tutorial> elements are defined in the namespace http://www.baeldung.com/full_archive.

Lets see how to handle namespaces.

First of all we need to set the namespace context so XPath will be able to know where are we looking for our data:

xPath.setNamespaceContext(new NamespaceContext() {
    @Override
    public Iterator getPrefixes(String arg0) {
        return null;
    }
    @Override
    public String getPrefix(String arg0) {
        return null;
    }
    @Override
    public String getNamespaceURI(String arg0) {
        if ("bdn".equals(arg0)) {
            return "http://www.baeldung.com/full_archive";
        }
        return null;
    }
});

In the method above, we are defining “bdn” as the name for our namespace “http://www.baeldung.com/full_archive“, and from now on, we need to add “bdn” to the XPath expressions used to locate elements:

String expression = "/bdn:Tutorials/bdn:Tutorial";
nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

Using the expression above we are able to retrieve all <Tutorial> elements under “bdn” namespace.

3.6. Avoiding Empty Text Nodes Troubles

As you could notice, in the code at the 3.3 section of this article a new function is called just right after parsing our XML to a Document object, this.clean(xmlDocument);

Sometimes when we iterate through elements, childnodes and so on, if our document has empty text nodes we can find an unexpected behavior in the results we want to get.

We called node.getFirstChild() when we are iterating over all <Tutorial> elements looking for the <title> information, but instead of what we are looking for we just have “#Text” as an empty node.

To fix the problem we can navigate through our document and remove those empty nodes, like this:

NodeList childs = node.getChildNodes();
for (int n = childs.getLength() - 1; n >= 0; n--) {
    Node child = childs.item(n);
    short nodeType = child.getNodeType();
    if (nodeType == Node.ELEMENT_NODE) {
        clean(child);
    }
    else if (nodeType == Node.TEXT_NODE) {
        String trimmedNodeVal = child.getNodeValue().trim();
        if (trimmedNodeVal.length() == 0){
            node.removeChild(child);
        }
        else {
            child.setNodeValue(trimmedNodeVal);
        }
    } else if (nodeType == Node.COMMENT_NODE) {
        node.removeChild(child);
    }
}

By doing this we can check each type of node we find and remove those ones we don’t need.

4. Conclusions

Here we just introduced the default XPath provided support, but there are many popular libraries as JDOM, Saxon, XQuery, JAXP, Jaxen or even Jackson now. There are libraries for specific HTML parsing too like JSoup.

It’s not limited to java, XPath expressions can be used by XSLT language to navigate XML documents.

As you can see, there is a wide range of possibilities on how to handle these kind of files.

There is a great standard support by default for XML/HTML documents parsing, reading and processing. You can find the full working sample here.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

A Guide to Java Enums

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this article we will see what Java enums are, what problems they solve and how some of the design patterns they can be used in practice.

The enum keyword was introduced in Java 5. It denotes a special type of class that always extends the java.lang.Enum class. For the official documentation on their usage have a look at the documentation.

Constants defined this way make the code more readable, allow compile time checking, document upfront the list of accepted values and avoid unexpected behavior due to invalid values being passed in.

Here’s a quick and simple example of an enum that defines the status of an order for a pizza; the order status can be ORDERED, READY or DELIVERED:

public enum PizzaStatus {
    ORDERED,
    READY, 
    DELIVERED; 
}

Additionally, they come with many useful methods, which you would otherwise have to write yourself if you were using traditional public static final constants.

1.1. An Enum with a Custom API

OK, so now that we have a basic understanding of what enums are and how you can use them, let’s take our previous example to the next level by defining some extra API methods on the enum

public class Pizza {
    private PizzaStatus status;
    public enum PizzaStatus {
        ORDERED,
        READY,
        DELIVERED;
    }

    public boolean isDeliverable() {
        if (getStatus() == PizzaStatus.READY) {
            return true;
        }
        return false;
    }
    
    // Methods that set and get the status variable.
}

1.2. Comparing Enum Types using “==” Operator

Since enum types ensure that only one instance of the constants exist in the JVM, we can safely use “==” operator to compare two variables as seen in the example above; moreover the “==” operator provides compile-time and run-time safety.

Let’s first have a look at run-time safety in the following snippet where the “==” operator is used to compare statuses and a NullPointerException will not be thrown if either value is null. Conversely the an NullPointerException would be thrown if the equals method were used:

if(testPz.getStatus().equals(Pizza.PizzaStatus.DELIVERED)); 
if(testPz.getStatus() == Pizza.PizzaStatus.DELIVERED); 

As for compile time safety, let’s have a look at another example where an enum of a different type is compared using the equals method is determined to be true – because the values of the enum and the getStatus method coincidentally are the same, but logically the comparison should be false. This issue is avoided by using the “==” operator.

The compiler will flag the comparison as an incompatibility error:

if(testPz.getStatus().equals(TestColor.GREEN));
if(testPz.getStatus() == TestColor.GREEN);

1.3. Using Enum Types in Switch Statements

Enum types can be used in a switch statements also:

public int getDeliveryTimeInDays() {
    switch (status) {
        case ORDERED: return 5;
        case READY: return 2;
        case DELIVERED: return 0;
    }
    return 0;
}

1.4. Fields, Methods and Constructors in Enums

You can define constructors, methods and fields inside enum types that make it very powerful.

Let’s extend the example above and implement the transition from one stage of a pizza to another and see how we can get rid of the if statement and switch statement used before:

public class Pizza {

    private PizzaStatus status;
    public enum PizzaStatus {
        ORDERED (5){
            @Override
            public boolean isOrdered() {
                return true;
            }
        },
        READY (2){
            @Override
            public boolean isReady() {
                return true;
            }
        },
        DELIVERED (0){
            @Override
            public boolean isDelivered() {
                return true;
            }
        };

        private int timeToDelivery;

        public boolean isOrdered() {return false;}

        public boolean isReady() {return false;}

        public boolean isDelivered(){return false;}

        public int getTimeToDelivery() {
            return timeToDelivery;
        }

        PizzaStatus (int timeToDelivery) {
            this.timeToDelivery = timeToDelivery;
        }
    }

    public boolean isDeliverable() {
        return this.status.isReady();
    }

    public void printTimeToDeliver() {
        System.out.println("Time to delivery is " + 
          this.getStatus().getTimeToDelivery());
    }
    
    // Methods that set and get the status variable.
}

The test snippet below demonstrate how this works:

@Test
public void givenPizaOrder_whenReady_thenDeliverable() {
    Pizza testPz = new Pizza();
    testPz.setStatus(Pizza.PizzaStatus.READY);
    assertTrue(testPz.isDeliverable());
}

2. EnumSet and EnumMap

2.1. EnumSet

The EnumSet is a specialized Set implementation meant to be used with Enum types.

It is a very efficient and compact representation of a particular Set of Enum constants when compared to a HashSet, owning to the internal Bit Vector Representation that is used. And it provides a type safe alternative to traditional int-based “bit flags”, allowing us to write concise code that is more readable and maintainable.

The EnumSet is an abstract class that has two implementations called RegularEnumSet and JumboEnumSet, one of which is chosen depending on the number of constants in the enum at the time of instantiation.

Therefore it is always a good idea to use this set when ever we want to work with a collection of enum constants in most of the scenarios (like subsetting, adding, removing, and for bulk operations like containsAll and removeAll) and use Enum.values() if you just want to iterate over all possible constants.

In the code snippet below, you can see how EnumSet is used to create a subset of constants and its usage:

public class Pizza {

    private static EnumSet<PizzaStatus> undeliveredPizzaStatuses =
      EnumSet.of(PizzaStatus.ORDERED, PizzaStatus.READY);

    private PizzaStatus status;

    public enum PizzaStatus {
        ...
    }

    public boolean isDeliverable() {
        return this.status.isReady();
    }

    public void printTimeToDeliver() {
        System.out.println("Time to delivery is " + 
          this.getStatus().getTimeToDelivery() + " days");
    }

    public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
        return input.stream().filter(
          (s) -> undeliveredPizzaStatuses.contains(s.getStatus()))
            .collect(Collectors.toList());
    }

    public static EnumMap<PizzaStatus, List<Pizza>> 
      groupPizzaByStatus(List<Pizza> pzList) {
        return pzList.stream().collect(
          Collectors.groupingBy(Pizza::getStatus,
          () -> new EnumMap<>(PizzaStatus.class), Collectors.toList()));
    }

    public void deliver() { 
        if (isDeliverable()) { 
            PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy()
              .deliver(this); 
            this.setStatus(PizzaStatus.DELIVERED); 
        } 
    }
    
    // Methods that set and get the status variable.
}

Executing the following test demonstrated the power of the EnumSet implementation of the Set interface:

@Test
public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved() {
    List<Pizza> pzList = new ArrayList<>();
    Pizza pz1 = new Pizza();
    pz1.setStatus(Pizza.PizzaStatus.DELIVERED);

    Pizza pz2 = new Pizza();
    pz2.setStatus(Pizza.PizzaStatus.ORDERED);

    Pizza pz3 = new Pizza();
    pz3.setStatus(Pizza.PizzaStatus.ORDERED);

    Pizza pz4 = new Pizza();
    pz4.setStatus(Pizza.PizzaStatus.READY);

    pzList.add(pz1);
    pzList.add(pz2);
    pzList.add(pz3);
    pzList.add(pz4);

    List<Pizza> undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList); 
    assertTrue(undeliveredPzs.size() == 3); 
}

2.2. EnumMap

EnumMap is a specialized Map implementation meant to be used with enum constants as keys. It is an efficient and compact implementation compared to its counterpart HashMap and is internally represented as an array:

EnumMap<Pizza.PizzaStatus, Pizza> map;

Let’s have a quick look at a real example that shows how it can be used in practice:

public static EnumMap<PizzaStatus, List<Pizza>> 
  groupPizzaByStatus(List<Pizza> pizzaList) {
    EnumMap<PizzaStatus, List<Pizza>> pzByStatus = 
      new EnumMap<PizzaStatus, List<Pizza>>(PizzaStatus.class);
    
    for (Pizza pz : pizzaList) {
        PizzaStatus status = pz.getStatus();
        if (pzByStatus.containsKey(status)) {
            pzByStatus.get(status).add(pz);
        } else {
            List<Pizza> newPzList = new ArrayList<Pizza>();
            newPzList.add(pz);
            pzByStatus.put(status, newPzList);
        }
    }
    return pzByStatus;
}

Executing the following test demonstrated the power of the EnumMap implementation of the Map interface:

@Test
public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped() {
    List<Pizza> pzList = new ArrayList<>();
    Pizza pz1 = new Pizza();
    pz1.setStatus(Pizza.PizzaStatus.DELIVERED);

    Pizza pz2 = new Pizza();
    pz2.setStatus(Pizza.PizzaStatus.ORDERED);

    Pizza pz3 = new Pizza();
    pz3.setStatus(Pizza.PizzaStatus.ORDERED);

    Pizza pz4 = new Pizza();
    pz4.setStatus(Pizza.PizzaStatus.READY);

    pzList.add(pz1);
    pzList.add(pz2);
    pzList.add(pz3);
    pzList.add(pz4);

    EnumMap<Pizza.PizzaStatus,List<Pizza>> map = Pizza.groupPizzaByStatus(pzList);
    assertTrue(map.get(Pizza.PizzaStatus.DELIVERED).size() == 1);
    assertTrue(map.get(Pizza.PizzaStatus.ORDERED).size() == 2);
    assertTrue(map.get(Pizza.PizzaStatus.READY).size() == 1);
}

3. Implement Design Patterns using Enums

3.1. Singleton Pattern

Normally, implementing a class using the Singleton pattern is quite non-trivial. Enums provide an easy and quick way of implementing singletons. In addition to that, since the enum class implements the Serializable interface under the hood, the class is guaranteed to be a singleton by the JVM, which unlike the conventional implementation where we have to ensure that no new instances are created during deserialization.

In the code snippet below, we see how we can implement singleton pattern:

public enum PizzaDeliverySystemConfiguration {
    INSTANCE;
    PizzaDeliverySystemConfiguration() {
        // Initialization configuration which involves
        // overriding defaults like delivery strategy
    }

    private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL;

    public static PizzaDeliverySystemConfiguration getInstance() {
        return INSTANCE;
    }

    public PizzaDeliveryStrategy getDeliveryStrategy() {
        return deliveryStrategy;
    }
}

3.2. Strategy Pattern

Conventionally the Strategy pattern is written by having an interface that is implemented by different classes. Adding a new strategy meant adding a new implementation class. With enums, this is achieved with less effort, adding a new implementation means defining just another instance with some implementation.

The code snippet below shows how to implement the Strategy pattern:

public enum PizzaDeliveryStrategy {
    EXPRESS {
        @Override
        public void deliver(Pizza pz) {
            System.out.println("Pizza will be delivered in express mode");
        }
    },
    NORMAL {
        @Override
        public void deliver(Pizza pz) {
            System.out.println("Pizza will be delivered in normal mode");
        }
    };

    public abstract void deliver(Pizza pz);
}

Add the following method to the Pizza class:

public void deliver() {
    if (isDeliverable()) {
        PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy()
          .deliver(this);
        this.setStatus(PizzaStatus.DELIVERED);
    }
}
@Test
public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() {
    Pizza pz = new Pizza();
    pz.setStatus(Pizza.PizzaStatus.READY);
    pz.deliver();
    assertTrue(pz.getStatus() == Pizza.PizzaStatus.DELIVERED);
}

4. Java 8 and Enums

The Pizza class can be rewritten in Java 8, and you can see how the methods getAllUndeliveredPizzas() and groupPizzaByStatus() become so concise with the use of lambdas and the Stream APIs:

public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
    return input.stream().filter(
      (s) -> !deliveredPizzaStatuses.contains(s.getStatus()))
        .collect(Collectors.toList());
}

public static EnumMap<PizzaStatus, List<Pizza>> 
  groupPizzaByStatus(List<Pizza> pzList) {
    EnumMap<PizzaStatus, List<Pizza>> map = pzList.stream().collect(
      Collectors.groupingBy(Pizza::getStatus,
      () -> new EnumMap<>(PizzaStatus.class), Collectors.toList()));
    return map;
}

5. JSON Representation of Enum

Using Jackson libraries, it is possible to have a JSON representation of enum types as if they are POJOs. The code snippet below shows the Jackson annotations that can be used for the same:

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PizzaStatus {
    ORDERED (5){
        @Override
        public boolean isOrdered() {
            return true;
        }
    },
    READY (2){
        @Override
        public boolean isReady() {
            return true;
        }
    },
    DELIVERED (0){
        @Override
        public boolean isDelivered() {
            return true;
        }
    };

    private int timeToDelivery;

    public boolean isOrdered() {return false;}

    public boolean isReady() {return false;}

    public boolean isDelivered(){return false;}

    @JsonProperty("timeToDelivery")
    public int getTimeToDelivery() {
        return timeToDelivery;
    }

    private PizzaStatus (int timeToDelivery) {
        this.timeToDelivery = timeToDelivery;
    }
}

We can use the Pizza and PizzaStatus as follows:

Pizza pz = new Pizza();
pz.setStatus(Pizza.PizzaStatus.READY);
System.out.println(Pizza.getJsonString(pz));

to generate the following JSON representation of the Pizzas status:

{
  "status" : {
    "timeToDelivery" : 2,
    "ready" : true,
    "ordered" : false,
    "delivered" : false
  },
  "deliverable" : true
}

For more information on JSON serializing/deserializing (including customization) of enum types refer to the Jackson – Serialize Enums as JSON Objects.

6. Conclusion

In this article we explored the Java enum, from the language basics to more advanced and interesting real-world use cases.

Code snippets from this article can be found in the Core Java 8 main Github repository and tests can be found in the Core Java 8 test Github repository.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 128

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> Notes on Reactive Programming Part I: The Reactive Landscape [spring.io]

A solid intro to the reactive programming.

And no, it’s no coincidence that this is first.

>> The Top 10 Exception Types in Production Java Applications – Based on 1B Events [takipi.com]

Another set of insights out of an interesting dataset – with the venerable NullPointerException of course at number one.

>> How To Implement equals Correctly [codefx.org]

A back-to-basics looking at equals – nicely done.

>> How to implement equals and hashCode using the entity identifier (primary key) [vladmihalcea.com]

And since we were just talking about equals, this writeup definitely fits well into that narrative with a look from the persistence side of things.

>> Observations From A History of Java Backwards Incompatibility [marxsoftware.com]

You might argue that keeping full backwards compatibility is what made Java as popular as it is today, or that it’s what keeps Java from actually moving forward well.

Either way – here’s a quick look at what it means to keep that compatibility for over 20 years.

>> Spring-Reactive samples [java-allandsundry.com]

The reactive programming model is coming to Spring, no two-ways about it. And there isn’t a whole lot of information about it out there – so this piece looks quite interesting in terms of filling that gap.

>> Netflix OSS, Spring Cloud, or Kubernetes? How About All of Them! [christianposta.com]

The Netflix ecosystem of tools is based on practical usage at scale, so it’s always super useful to go deep into understanding their tools.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Practical Event Sourcing And CQRS Benefits [sapiensworks.com]

If you’re literally just starting out, than this may be to early, but if you’ve been building systems for a while know in one form or another and haven’t explored things like DDD, Event Sourcing and CQRS – well, this is as good of time as any to.

Yes, it’s a significantly different way of building a system, but then again, really leveling up probably won’t happen from doing CRUD marginally better.

Also worth reading:

3. Musings

>> Why I switched to making products [swizec.com]

A quick and fun intro to why it’s well worth doing products. This was a fun read for me, since I made the jump into products almost one year ago today.

>> Why is Github Taking over the World? [daedtech.com]

A discussion around the history and the Why of Github.

>> Creating virtual assets in service virtualization: record and playback or behaviour modeling? [ontestautomation.com]

Definitely an interesting read exploring the two alternatives of driving the testing and explorations of a system, either by using a recorder, or programmatically. A bit high level but well worth reading.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> How are you doing on your unspoken objectives? [dilbert.com]

>> A monkey could do your assignment while eating a banana [dilbert.com]

>> Moving to a shared leadership model [dilbert.com]

5. Pick of the Week

>> Happiness is the Only Logical Pursuit [mrmoneymustache.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Load Testing Baeldung with Gatling

$
0
0

1. Overview

In the previous tutorial, we’ve seen how to use Gatling to load test a custom web application.

In this article we’ll make use the Gatling stress tool to measure the performance of the staging environment of this website.

2. The Test Scenario

Let’s first set up our main usage scenario – one that comes close to a typical user that might be browsing the site:

  1. Go to the Home Page
  2. Open an Article from Home Page
  3. Go to Guides/REST
  4. Go to the REST Category
  5. Go to the Full Archive
  6. Open an Article from the Archive

3. Record the Scenario

Now, we’ll record our scenario using the Gatling recorder – as follows:

$GATLING_HOME/bin/recorder.sh

And for Windows users:

%GATLING_HOME%\bin\recorder.bat

Note: GATLING_HOME is your Gatling installation directory.

There are two modes for Gatling Recorder: HTTP Proxy and HAR Converter.

We discussed the HTTP Proxy mode in detail in the previous tutorial – so let’s now have a look at the HAR Converter option.

3.1. HAR Converter

HAR is short for HTTP Archive – which is a format that basically records the full information about a browsing session.

We can obtain HAR files from the browser then use the Gatling Recorder to convert it into a Simulation.

We’ll create our HAR file with the help of the Chrome Developer Tools:

  • Menu -> More Tools -> Developer Tools
  • Go to Network Tab
  • Make sure Preserve log is checked
  • After you finish navigating the website, right click on the requests you want to export
  • Then, select Copy All as HAR
  • Paste them in a file, then import it from the Gatling recorder

After you finish adjusting Gatling recorder to your preference, Click start.

Note that the output folder is by default GATLING_HOME/user-files-simulations

4. The Simulation

The generated simulation file is similarly written in Scala. It’s generally OK, but not super readable, so we’ll do some adjustments to clean up. Here is our final Simulation:

class RestSimulation extends Simulation {

    val httpProtocol = http.baseURL("http://staging.baeldung.com")

    val scn = scenario("RestSimulation")
      .exec(http("home").get("/"))
      .pause(23)
      .exec(http("article_1").get("/spring-rest-api-metrics"))
      .pause(39)
      .exec(http("rest_series").get("/rest-with-spring-series"))
      .pause(60)
      .exec(http("rest_category").get("/category/rest/"))
      .pause(26)
      .exec(http("archive").get("/full_archive"))
      .pause(70)
      .exec(http("article_2").get("/spring-data-rest-intro"))

    setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

An important note here is that the full simulation file is much larger; here, we didn’t include static resources for simplicity.

5. Run the Load Test

Now, we can run our simulation – as follows:

$GATLING_HOME/bin/gatling.sh

And for Windows users:

%GATLING_HOME%\bin\gatling.bat

The Gatling tool will scan GATLING_HOME/user-files-simulations and list all found simulations for us to choose.

After running the simulation here’s what the results look like:

For one user:

> request count                                304 (OK=304    KO=0)
> min response time                             75 (OK=75     KO=-)
> max response time                          13745 (OK=13745  KO=-)
> mean response time                          1102 (OK=1102   KO=-)
> std deviation                               1728 (OK=1728   KO=-)
> response time 50th percentile                660 (OK=660    KO=-)
> response time 75th percentile               1006 (OK=1006   KO=-)
> mean requests/sec                           0.53 (OK=0.53   KO=-)
---- Response Time Distribution ------------------------------------
> t < 800 ms                                           183 ( 60%)
> 800 ms < t < 1200 ms                                  54 ( 18%)
> t > 1200 ms                                           67 ( 22%)
> failed                                                 0 (  0%)

For 5 simultaneous users:

> request count                               1520 (OK=1520   KO=0)
> min response time                             70 (OK=70     KO=-)
> max response time                          30289 (OK=30289  KO=-)
> mean response time                          1248 (OK=1248   KO=-)
> std deviation                               2079 (OK=2079   KO=-)
> response time 50th percentile                504 (OK=504    KO=-)
> response time 75th percentile               1440 (OK=1440   KO=-)
> mean requests/sec                          2.411 (OK=2.411  KO=-)
---- Response Time Distribution ------------------------------------
> t < 800 ms                                           943 ( 62%)
> 800 ms < t < 1200 ms                                 138 (  9%)
> t > 1200 ms                                          439 ( 29%)
> failed                                                 0 (  0%)

For 10 simultaneous users:

> request count                               3058 (OK=3018   KO=40)
> min response time                              0 (OK=69     KO=0)
> max response time                          44916 (OK=44916  KO=30094)
> mean response time                          2193 (OK=2063   KO=11996)
> std deviation                               4185 (OK=3953   KO=7888)
> response time 50th percentile                506 (OK=494    KO=13670)
> response time 75th percentile               2035 (OK=1976   KO=15835)
> mean requests/sec                          3.208 (OK=3.166  KO=0.042)
---- Response Time Distribution ----------------------------------------
> t < 800 ms                                          1752 ( 57%)
> 800 ms < t < 1200 ms                                 220 (  7%)
> t > 1200 ms                                         1046 ( 34%)
> failed                                                40 (  1%)

Note that some of the requests failed when tested 10 simultaneous users – simply because the staging environment isn’t capable of handling that kind of load.

6. Conclusion

In this quick article we explored the HAR option of recording test scenarios in Gatling as well as did a simple initial test of baeldung.com.

Introduction to Project Lombok

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

Lombok is one of the tools I literally always drop into my projects builds the first. I couldn’t imagine myself programming Java without it these days. I really hope you find its power reading this article!

1. Avoid Repetitive Code

Java is a great language but it sometimes gets too verbose for things you have to do in your code for common tasks or compliancy with some framework practices. These do very often bring no real value to the business side of your programs – and this is where Lombok is here to make your life happier and yourself more productive.

The way it works is by plugging into your build process and autogenerating Java bytecode into your .class files as per a number of project annotations you introduce in your code.

Including it in your builds, whichever system you are using, is very straight forward. Their project page  has detailed instructions on the specifics. Most of my projects are maven based, so I just typically drop their dependency in the provided scope and I’m good to go:

<dependencies>
    ...
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.8</version>
        <scope>provided</scope>
    </dependency>
    ...
</dependencies>

Check for the most recent available version here.

Note that depending on Lombok won’t make users of your .jars depend on it as well, as it is a pure build dependency, not runtime.

2. Getters/Setters, Constructors – So Repetitive

Encapsulating object properties via public getter and setter methods is such a common practice in the Java world, and lots of frameworks rely on this “Java Bean” pattern extensively: a class with an empty constructor and get/set methods for “properties”.

This is so common that most IDE’s support autogenerating code for these patterns (and more). This code however needs to live in your sources and also be maintained when, say, a new property is added or a field renamed.

Let’s consider this class we want to use as a JPA entity as an example:

@Entity
public class User implements Serializable {

    private @Id Long id; // will be set when persisting

    private String firstName;
    private String lastName;
    private int age;

    public User() {
    }

    public User(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    // getters and setters: ~30 extra lines of code
}

This is a rather simple class, but still consider if we added the extra code for getters and setters we’d end up with a definition where we would have more boilerplate zero-value code than the relevant business information: “a User has first and last names, and age.”

Let us now Lombok-ize this class:

@Entity
@Getter @Setter @NoArgsConstructor // <--- THIS is it
public class User implements Serializable {

    private @Id Long id; // will be set when persisting

    private String firstName;
    private String lastName;
    private int age;

    public User(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

By adding the @Getter and @Setter annotations we told Lombok to, well, generate these for all the fields of the class. @NoArgsConstructor will lead to an empty constructor generation.

Note this is the whole class code, I am not omitting anything as opposed to the version above with the // getters and setters comment. For a three relevant attributes class, this is a significant saving in code!

If you further add attributes (properties) to your User class, the same will happen: you applied the annotations to the type itself so they will mind all fields by default.

What if you wanted to refine the visibility of some properties? For example, I like to keep my entities’ id field modifiers package or protected visible because they are expected to be read but not explicitly set by application code. Just use a finer grained @Setter for this particular field:

private @Id @Setter(AccessLevel.PROTECTED) Long id;

3. Value Classes/DTO’s

There are many situations in which we want to define a data type with the sole purpose of representing complex “values” or as “Data Transfer Objects”, most of the time in the form of immutable data structures we build once and never want to change.

We design a class to represent a successful login operation. We want all fields to be non-null and objects be immutable so that we can thread-safely access its properties:

public class LoginResult {

    private final Instant loginTs;

    private final String authToken;
    private final Duration tokenValidity;
    
    private final URL tokenRefreshUrl;

    // constructor taking every field and checking nulls

    // read-only accessor, not necessarily as get*() form
}

Again, the amount of code we’d have to write for the commented sections would be of a much larger volume that the information we want to encapsulate and that has real value for us. We can use Lombok again to improve this:

@RequiredArgsConstructor
@Accessors(fluent = true) @Getter
public class LoginResult {

    private final @NonNull Instant loginTs;

    private final @NonNull String authToken;
    private final @NonNull Duration tokenValidity;
    
    private final @NonNull URL tokenRefreshUrl;

}

Just add the @RequiredArgsConstructor annotation and you’d get a constructor for all the final fields int the class, just as you declared them. Adding @NonNull to attributes makes our constructor check for nullability and throw NullPointerExceptions accordingly. This would also happen if the fields were non-final and we added @Setter for them.

Don’t you want boring old get*() form for your properties? Because we added @Accessors(fluent=true) in this example “getters” would have the same method name as the properties: getAuthToken() simply becomes authToken().

This “fluent” form would apply to non-final fields for attribute setters and as well allow for chained calls:

// Imagine fields were no longer final now
return new LoginResult()
  .loginTs(Instant.now())
  .authToken("asdasd")
  . // and so on

4. Core Java Boilerplate

Another situation in which we end up writing code we need to maintain is when generating toString(), equals() and hashCode() methods. IDEs try to help with templates for autogenerating these in terms of our class attributes.

We can automate this by means of other Lombok class-level annotations:

  • @ToString: will generate a toString() method including all class attributes. No need to write one ourselves and maintain it as we enrich our data model.
  • @EqualsAndHashCode: will generate both equals() and hashCode() methods by default considering all relevant fields, and according to very well though semantics.

These generators ship very handy configuration options. For example, if your annotated classes take part of a hierarchy you can just use the callSuper=true parameter and parent results will be considered when generating the method’s code.

More on this: say we had our User JPA entity example include a reference to events associated to this user:

@OneToMany(mappedBy = "user")
private List<UserEvent> events;

We wouldn’t like to have the hole list of events dumped whenever we call the toString() method of our User, just because we used the @ToString annotation. No problem: just parameterize it like this: @ToString(exclude = {“events”}), and that won’t happen. This is also helpful to avoid circular references if, for example, UserEvents had a reference to a User.

For the LoginResult example, we may want to define equality and hash code calculation just in terms of the token itself and not the other final attributes in our class. Then, simply write something like @EqualsAndHashCode(of = {“authToken”}).

Bonus: if you liked the features from the annotations we’ve reviewed so far you may want to examine @Data and @Value annotations as they behave as if a set of them had been applied to our classes. After all, these discussed usages are very commonly put together in many cases.

5. The Builder Pattern

The following could make for a sample configuration class for a REST API client:

public class ApiClientConfiguration {

    private String host;
    private int port;
    private boolean useHttps;

    private long connectTimeout;
    private long readTimeout;

    private String username;
    private String password;

    // Whatever other options you may thing.

    // Empty constructor? All combinations?

    // getters... and setters?
}

We could have an initial approach based on using the class default empty constructor and providing setter methods for every field. However, we’d ideally want configurations no to be set-ed once they have been built (instantiated), effectively making them immutable. We therefore want to avoid setters, but writing such a potentially long args constructor is an anti-pattern.

Instead, we can tell the tool to generate a builder pattern, preventing us to write an extra Builder class and associated fluent setter-like methods by simply adding the @Builder annotation to our ApiClientConfiguration.

@Builder
public class ApiClientConfiguration {

    // ... everything else remains the same

}

Leaving the class definition above as such (no declare constructors nor setters + @Builder) we can end up using it as:

ApiClientConfiguration config = 
    new ApiClientConfigurationBuilder()
        .host("api.server.com")
        .port(443)
        .useHttps(true)
        .connectTimeout(15_000L)
        .readTimeout(5_000L)
        .username("myusername")
        .password("secret")
    .build();

6. Checked Exceptions Burden

Lots of Java APIs are designed so that they can throw a number of checked exceptions client code is forced to either catch or declare to throws. How many times have you turned these exceptions you know won’t happen into something like this?

public String resourceAsString() {
    try (InputStream is = this.getClass().getResourceAsStream("sure_in_my_jar.txt")) {
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        return br.lines().collect(Collectors.joining("\n"));
    } catch (IOException | UnsupportedCharsetException ex) {
        // If this ever happens, then its a bug.
        throw new RuntimeException(ex); <--- encapsulate into a Runtime ex.
    }
}

If you want to avoid this code patterns because the compiler won’t be otherwise happy (and, after all, you know the checked errors cannot happen), use the aptly named @SneakyThrows:

@SneakyThrows
public String resourceAsString() {
    try (InputStream is = this.getClass().getResourceAsStream("sure_in_my_jar.txt")) {
        BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        return br.lines().collect(Collectors.joining("\n"));
    } 
}

7. Ensure Your Resources are Released

Java 7 introduced the try-with-resources block to ensure your resources held by instances of anything implementing java.lang.AutoCloseable are released when exiting.

Lombok provides an alternative way of achieving this, and more flexibly via @Cleanup. Use it for any local variable whose resources you want to make sure are released. No need for them to implement any particular interface, you’ll just get its close() method called.

@Cleanup InputStream is = this.getClass().getResourceAsStream("res.txt");

Your releasing method has a different name? No problem, just customize the annotation:

@Cleanup("dispose") JFrame mainFrame = new JFrame("Main Window");

8. Annotate Your Class To Get a Logger

Many of us add logging statements to our code sparingly by creating an instance of a Logger from our framework of choice. Say, SLF4J:

public class ApiClientConfiguration {

    private static Logger LOG = LoggerFactory.getLogger(ApiClientConfiguration.class);

    // LOG.debug(), LOG.info(), ...

}

This is such a common pattern that Lombok developers have cared to simplify it for us:

@Slf4j // or: @Log @CommonsLog @Log4j @Log4j2 @XSlf4j
public class ApiClientConfiguration {

    // log.debug(), log.info(), ...

}

Many logging frameworks are supported and of course you can customize the instance name, topic, etc.

9. Write Thread-Safer Methods

In Java you can use the synchronized keyword to implement critical sections. However, this is not a 100% safe approach: other client code can eventually also synchronize on your instance, potentially leading to unexpected deadlocks.

This is where @Synchronized comes in: annotate your methods (both instance and static) with it and you’ll get an autogenerated private, unexposed field your implementation will use for locking:

@Synchronized
public /* better than: synchronized */ void putValueInCache(String key, Object value) {
    // whatever here will be thread-safe code
}

10. Automate Objects Composition

Java does not have language level constructs to smooth out a “favor composition inheritance” approach. Other languages have built-in concepts such as Traits or Mixins to achieve this.

Lombok’s @Delegate comes in very handy when you want to use this programming pattern. Let’s consider an example:

  • We want Users and Customers to share some common attributes for naming and phone number
  • We define both an interface and an adapter class for these fields
  • We’ll have our models implement the interface and @Delegate to their adapter, effectively composing them with our contact information

First, let’s define an interface:

public interface HasContactInformation {

    String getFirstName();
    void setFirstName(String firstName);

    String getFullName();

    String getLastName();
    void setLastName(String lastName);

    String getPhoneNr();
    void setPhoneNr(String phoneNr);

}

And now an adapter as a support class:

@Data
public class ContactInformationSupport implements HasContactInformation {

    private String firstName;
    private String lastName;
    private String phoneNr;

    @Override
    public String getFullName() {
        return getFirstName() + " " + getLastName();
    }
}

The interesting part comes now, see how easy it is to now compose contact information into both model classes:

public class User implements HasContactInformation {

    // Whichever other User-specific attributes

    @Delegate(types = {HasContactInformation.class})
    private final ContactInformationSupport contactInformation =
            new ContactInformationSupport();

    // User itself will implement all contact information by delegation
    
}

The case for Customer would be so similar we’d omit the sample for brevity.

11. Rolling Lombok Back?

Short answer: Not at all really.

You may be worried there is a chance that you use Lombok in one of your projects, but later want to rollback that decision. You’d then have a maybe large number of classes annotated for it… what could you do?

I have never really regretted this, but who knows for you, your team or your organization. For these cases you’re covered thanks to the delombok tool from the same project.

By delombok-ing your code you’d get autogenerated Java source code with exactly the same features from the bytecode Lombok built. So then you may simply replace your original annotated code with these new delomboked files and no longer depend on it.

This is something you can integrate in your build and I have done this in the past to just study the generated code or to integrate Lombok with some other Java source code based tool.

12. Conclusion

There are some other features we have not presented in this article, I’d encourage you to take a deeper dive into the feature overview for more details and use cases.

Also most functions we’ve shown have a number of customization options you may find handy to get the tool generate things the most compliant with your team practices for naming etc. The available built-in configuration system could also help you with that.

I hope you have found the motivation to give Lombok a chance to get into your Java development toolset. Give it a try and boost your productivity!

The example code can be found in the GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Scheduling in Java EE

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In a previous article we demonstrated how to schedule tasks in Spring using @Scheduled annotation. In this article we will demonstrate how to achieve the same by using the timer service in a Java Enterprise Edition application for each case presented in the previous article.

2. Enable Support for Scheduling

In a Java EE application there is no need to enable support for timed tasks. The timer service is a container managed service that allows applications to call methods that are scheduled for time based events. As an example an application may have to run some daily reports at a certain hour in order to generate statistics.

There are two types of timers:

  • Programmatic timers: the timer service can be injected in to any bean (except a stateful session bean) and the business logic should be placed in a method annotated with @Timeout. The timer can be initialized by a method annotated @PostConstruct of the beans or it can also be initialized just by calling a method.
  • Automatic timers: the business logic is placed in any method annotated with @Schedule or @Schedules. These timers are initialized as soon as the application starts.

So let’s get started with our first example.

3. Schedule Task with a Fixed Delay

In Spring this is done simply by using the @Scheduled(fixedDelay = 1000) annotation. In this case, the duration between the end of the last execution and the start of next execution is fixed. The task always waits until the previous one is finished.

Doing exactly same thing in Java EE is a little bit harder to achieve because there is no similar built in mechanism provided, nevertheless a similar scenario can be implemented with a bit of extra coding. Let’s have a look at how this is done:

@Singleton
public class FixedTimerBean {

    @EJB
    private WorkerBean workerBean;

    @Lock(LockType.READ)
    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    public void atSchedule() throws InterruptedException {
        workerBean.doTimerWork();
    }
}
@Singleton
public class WorkerBean {

    private AtomicBoolean busy = new AtomicBoolean(false);

    @Lock(LockType.READ)
    public void doTimerWork() throws InterruptedException {
        if (!busy.compareAndSet(false, true)) {
            return;
        }
        try {
            Thread.sleep(20000L);
        } finally {
            busy.set(false);
        }
    }
}

As you can see the timer is scheduled to be triggered every five seconds. However the method triggered in our case simulated a 20 seconds response time by call sleep() on the current Thread.

As a consequence the container will continue to call doTimerWork() every five seconds but the condition put at the beginning of the method, busy.compareAndSet(false, true), will return immediately if the previous call has not finished. In this we ensure that the next task will be executed only after the previous one has finished.

4. Schedule Task at a Fixed Rate

One way of doing this is to use the timer service which is injected by using @Resource and configured in the method annotated @PostConstruct. The method annotated with @Timeout will be called when the timer expires.

As mentioned in the previous article the beginning of the task execution doesn’t wait for the completion of the previous execution. This option should be used when each execution of the task is independent. The following code snippet creates a timer that fires every second:

@Startup
@Singleton
public class ProgrammaticAtFixedRateTimerBean {

    @Inject
    Event<TimerEvent> event;

    @Resource
    TimerService timerService;

    @PostConstruct
    public void initialize() {
        timerService.createTimer(0,1000, "Every second timer with no delay");
    }

    @Timeout
    public void programmaticTimout(Timer timer) {
        event.fire(new TimerEvent(timer.getInfo().toString()));
    }
}

Another way is to use @Scheduled annotation. In the following code snippet we fire a timer every five seconds:

@Startup
@Singleton
public class ScheduleTimerBean {

    @Inject
    Event<TimerEvent> event;

    @Schedule(hour = "*", minute = "*", second = "*/5", info = "Every 5 seconds timer")
    public void automaticallyScheduled(Timer timer) {
        fireEvent(timer);
    }


    private void fireEvent(Timer timer) {
        event.fire(new TimerEvent(timer.getInfo().toString()));
    }
}

5. Schedule Task with Initial Delay

If your use case scenario requires the timer to start with a delay we can do that too. In this case Java EE allows the use of the timer service. Let’s have a look at an example where the timer has an initial delay of 10 seconds and then fires every five seconds:

@Startup
@Singleton
public class ProgrammaticWithInitialFixedDelayTimerBean {

    @Inject
    Event<TimerEvent> event;

    @Resource
    TimerService timerService;

    @PostConstruct
    public void initialize() {
        timerService.createTimer(10000, 5000, "Delay 10 seconds then every 5 seconds timer");
    }

    @Timeout
    public void programmaticTimout(Timer timer) {
        event.fire(new TimerEvent(timer.getInfo().toString()));
    }
}

The createTimer method used in our sample is using the following signature createTimer(long initialDuration, long intervalDuration, java.io.Serializable info) where initialDuration is the number of milliseconds that must elapse before the first timer expiration notification and intervalDuration is the number of milliseconds that must elapse between timer expiration notifications.

In this example we’re using an initialDuration of 10 seconds and an intervalDuration of five seconds. The task will be executed for the first time after the initialDuration value and it will continue to be executed according to the intervalDuration.

6. Schedule Task using Cron Expressions

All the schedulers that we have seen, both programmatic and automatic, allow the use of cron expressions. Let’s see an example:

@Schedules ({
   @Schedule(dayOfMonth="Last"),
   @Schedule(dayOfWeek="Fri", hour="23")
})
public void doPeriodicCleanup() { ... }

In this example the method doPeriodicCleanup() will be called every Friday at 23:00 and on the last day of the month.

7. Conclusion

In this article we have looked at various ways to schedule tasks in the Java EE environment using as a starting point a previous article where samples were done using Spring.

Code samples can be found in the github repository.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

The Market Share of Java IDEs in Q2 2016

$
0
0

The adoption numbers in the Java IDE ecosystem have always been interesting to watch.

So, this year, when I ran the regular Java and Spring survey, I decided to include the IDE question:

What is your main IDE?

And 2255 responses later – here’s what the market share looks like for the major players:

It definitely is a tight race between Eclipse in IntelliJ – both of them effectively hold about half of the market.

What’s even more interesting is understanding these numbers in the context of the ZeroTurnaround 2014 survey – which had a similar sample size – 2164 answers.

The 2014 data has Eclipse at a slightly higher market share – 52%, and IntelliJ at only 33% of market.

The trend is clear – Eclipse has been slowly shedding users, and IntelliJ IDEA has been picking up these users as well as a good chunk of the Netbeans and other numbers.


The Java 8 Stream API Tutorial

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this in-depth tutorial we will go through practical usage of Java 8 Streams from creation to parallel execution.

To understand this material reader should have the basic knowledge of Java 8 (lambda expressions, Optional, method references) and Stream API. If you aren’t familiar with these topics, please take a look at our previous articles – New Features in Java 8 and Introduction to Java 8 Streams.

2. Stream Creation

There are many ways to create a stream instance of different sources. Once created, the instance will not modify its source, therefore allowing creation of multiple instances from a single source.

2.1. Empty Stream

The empty() method should be used in case of a creation of an empty stream:

Stream<String> streamEmpty = Stream.empty();

Its often the case that the empty() method is used upon creation to avoid returning null for streams with no element:

public Stream<String> streamOf(List<String> list) {
    return list == null || list.isEmpty() ? Stream.empty() : list.stream();
}

2.2. Stream of Collection

Stream can also be created of any type of Collection (Collection, List, Set):

Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();

2.3. Stream of Array

Array can also be a source of a Stream:

Stream<String> streamOfArray = Stream.of("a", "b", "c");

They can also be created out of an existing array or of a part of an array:

String[] arr = new String[]{"a", "b", "c"};
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);

2.4. Stream.builder()

When builder is used the desired type should be additionally specified in the right part of the statement, otherwise the build() method will create an instance of the Stream<Object>:

Stream<String> streamBuilder =
  Stream.<String>builder().add("a").add("b").add("c").build();

2.5. Stream.generate()

The generate() method accepts a Supplier<T> for element generation. As the resulting stream is infinite, developer should specify the desired size or the generate() method will work until it reaches the memory limit:

Stream<String> streamGenerated =
  Stream.generate(() -> "element").limit(10);

The code above creates a sequence of ten strings with the value – “element”.

2.6. Stream.iterate()

Another way of creating an infinite stream is by using the iterate() method:

Stream<Integer> streamIterated = Stream.iterate(40, n -> n + 2).limit(20);

The first element of the resulting stream is a first parameter of the iterate() method. For creating every following element the specified function is applied to the previous element. In the example above the second element will be 42.

2.7. Stream of Primitives

Java 8 offers a possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

Using the new interfaces alleviates unnecessary auto-boxing allows increased productivity:

IntStream intStream = IntStream.range(1, 3);
LongStream longStream = LongStream.rangeClosed(1, 3);

The range(int startInclusive, int endExclusive) method creates an ordered stream from first parameter to the second parameter. It increments the value of subsequent elements with the step equal to 1. The result doesn’t include the last parameter, it is just an upper bound of the sequence.

The rangeClosed(int startInclusive, int endInclusive) method does the same with only one difference – the second element is included. These two methods can be used to generate any of the three types of streams of primitives.

Since Java 8 the Random class provides a wide range of methods for generation streams of primitives. For example, the following code creates a DoubleStream, which has three elements:

Random random = new Random();
DoubleStream doubleStream = random.doubles(3);

2.8. Stream of String

String can also be used as a source for creating a stream.

With the help of the chars() method of the String class. Since there is no interface CharStream in JDK, the IntStream is used to represent stream of chars instead.

IntStream streamOfChars = "abc".chars();

The following example breaks a String into sub-strings according to specified RegEx:

Stream<String> streamOfString =
  Pattern.compile(", ").splitAsStream("a, b, c");

2.9. Stream of File

Java NIO class Files allows to generate a Stream<String> of a text file through the lines() method. Every line of the text becomes an element of the stream:

Path path = Paths.get("C:\\file.txt");
Stream<String> streamOfStrings = Files.lines(path);
Stream<String> streamWithCharset = 
  Files.lines(path, Charset.forName("UTF-8"));

The Charset can be specified as an argument of the lines() method.

3. Referencing a Stream

It is possible to instantiate a stream and to have an accessible reference to it as long as only intermediate operations was called. Executing a terminal operation makes a stream inaccessible.

To demonstrate this we will forget for a while that the best practice is to chain sequence of operation. Besides its unnecessary verbosity, technically the following code is valid:

Stream<String> stream = 
  Stream.of("a", "b", "c").filter(element -> element.contains("b"));
Optional<String> anyElement = stream.findAny();

But an attempt to reuse the same reference after calling the terminal operation will trigger the IllegalStateException:

Optional<String> firstElement = stream.findFirst();

As the IllegalStateException is a RuntimeException, compiler will not signalize about a problem. So, it is very important to remember that Java 8 streams can’t be reused.

This kind of behavior is logical because streams were designed to provide an ability of applying a finite sequence of operations to the source of elements in a functional style, but not to store elements.

So, to make previous code work properly some changes should be done:

List<String> elements =
  Stream.of("a", "b", "c").filter(element -> element.contains("b"))
    .collect(Collectors.toList());
Optional<String> anyElement = elements.stream().findAny();
Optional<String> firstElement = elements.stream().findFirst();

4. Stream Pipeline

To perform a sequence of operations over the elements of the data source and aggregate their results, three parts are needed – the source, intermediate operation(s) and a terminal operation.

Intermediate operations return a new modified stream. For example, to create a new stream of the existing one without few elements the skip() method should be used:

Stream<String> onceModifiedStream =
  Stream.of("abcd", "bbcd", "cbcd").skip(1);

If more than one modification is needed, intermediate operations can be chained. Assume that we also need to substitute every element of current Stream<String> with a sub-string of first few chars. This will be done by chaining the skip() and the map() methods:

Stream<String> twiceModifiedStream =
  stream.skip(1).map(element -> element.substring(0, 3));

As you can see, the map() method takes a lambda expression as a parameter. If you want to learn more about lambdas take a look at our tutorial Lambda Expressions and Functional Interfaces: Tips and Best Practices.

A stream by itself is worthless, the real thing a user is interested in is a result of the terminal operation, which can be a value of some type or an action applied to every element of the stream. Only one terminal operation can be used per stream.

The right and most convenient way to use streams is by a stream pipeline, which is a chain of stream source, intermediate operations and a terminal operation. For example:

List<String> list = Arrays.asList("abc1", "abc2", "abc3");
long size = list.stream().skip(1)
  .map(element -> element.substring(0, 3)).sorted().count();

5. Lazy Invocation

Intermediate operations are lazy. This means that they will be invoked only if it is necessary for the terminal operation execution.

To demonstrate this, imagine that we have method wasCalled(), which increments an inner counter every time it was called:

private long counter;
 
private void wasCalled() {
    counter++;
}

Lets call method wasCalled() from operation filter():

List<String> list = Arrays.asList(“abc1”, “abc2”, “abc3”);
counter = 0;
Stream<String> stream = list.stream().filter(element -> {
    wasCalled();
    return element.contains("2");
});

As we have a source of three elements we can assume that method filter() will be called three times and the value of the counter variable will be 3. But running this code doesn’t change counter at all, it is still zero, so, the filter() method wasn’t called even once. The reason why – is missing of the terminal operation.

Lets rewrite this code a little bit by adding a map() operation and a terminal operation – findFirst(). We will also add an ability to track an order of method calls with a help of logging:

Optional<String> stream = list.stream().filter(element -> {
    log.info("filter() was called");
    return element.contains("2");
}).map(element -> {
    log.info("map() was called");
    return element.toUpperCase();
}).findFirst();

Resulting log shows that the filter() method was called twice and the map() method just once. It is so, because the pipeline executes vertically. In our example the first element of the stream didn’t satisfy filter’s predicate, than the filter() method was invoked for the second element, which passed the filter. Without calling the filter() for third element we went down through pipeline to the map() method. The findFirst() operation satisfies by just one element. So, in this particular example the lazy invocation allowed to avoid two method calls – one for the filter() and one for the map().

6. Order of Execution

From the performance point of view, the right order is one of the most important aspects of chaining operations in the stream pipeline:

long size = list.stream().map(element -> {
    wasCalled();
    return element.substring(0, 3);
}).skip(2).count();

Execution of this code will increase the value of counter by three. This means that the map() method of the stream was called three times. But the value of the size is one. So, resulting stream has just one element and we executed the expensive map() operations for no reason twice out of three times.

If we change the order of the skip() and the map() methodsthe counter will increase only by one. So, the method map() will be called just once:

long size = list.stream().skip(2).map(element -> {
    wasCalled();
    return element.substring(0, 3);
}).count();

This bring us up to the rule: intermediate operations which reduce the size of the stream should be placed before operations which are applying to each element. So, keep such methods as skip(), filter(), distinct() at the top of your stream pipeline.

7. Stream Reduction

The API has many terminal operations which aggregate a stream to a type or to a primitive, for example count(), max(), min(), sum(), but these operations work according to the predefined implementation. And what if developer needs to customize a stream’s reduction mechanism? There are two methods which allow to do this – the reduce() and the collect() methods.

7.1. The reduce() Method

There are three variations of this method, which differ by their signatures and returning types. They can have the following parameters:

identity – the initial value for accumulator or a default value if stream is empty and there is nothing to accumulate;

accumulator – a function which specifies a logic of aggregation of elements. As accumulator creates a new value for every step of reducing, the quantity of new values equals to the stream’s size and only the last value is useful. This is not very good for the performance.

combiner – a function which aggregates results of the accumulator. Combiner is called only in parallel mode to reduce results of accumulators from different threads.

So, lets look at these three methods in action:

OptionalInt reduced =
  IntStream.range(1, 4).reduce((a, b) -> a + b);

reduced = 6 (1 + 2 + 3)

int reducedTwoParams =
  IntStream.range(1, 4).reduce(10, (a, b) -> a + b);

reducedTwoParams = 16 (10 + 1 + 2 + 3)

int reducedParams = Stream.of(1, 2, 3)
  .reduce(10, (a, b) -> a + b, (a, b) -> {
     log.info("combiner was called");
     return a + b;
  });

The result will be the same as in the previous example (16) and there will be no login which means, that combiner wasn’t called. To make a combiner work, stream should be parallel:

int reducedParallel = Arrays.asList(1, 2, 3).parallelStream()
    .reduce(10, (a, b) -> a + b, (a, b) -> {
       log.info("combiner was called");
       return a + b;
    });

The result here is different (36) and the combiner was called twice. Here the reduction works by the following algorithm: accumulator ran three times by adding every element of the stream to identity to every element of the stream. These actions are being done in parallel. As a result, they have (10 + 1 = 11; 10 + 2 = 12; 10 + 3 = 13;). Now combiner can merge these three results. It needs two iterations for that (12 + 13 = 25; 25 + 11 = 36).

7.2. The collect() Method

Reduction of a stream can also be executed by another terminal operation – the collect() method. It accepts an argument of the type Collector, which specifies the mechanism of reduction. There are already created predefined collectors for most common operations. They can be accessed with the help of the Collectors type.

In this section we will use the following List as a source for all streams:

List<Product> productList = Arrays.asList(new Product(23, "potatoes"),
  new Product(14, "orange"), new Product(13, "lemon"),
  new Product(23, "bread"), new Product(13, "sugar"));

Converting a stream to the Collection (Collection, List or Set):

List<String> collectorCollection = 
  productList.stream().map(Product::getName).collect(Collectors.toList());

Reducing to String:

String listToString = productList.stream().map(Product::getName)
  .collect(Collectors.joining(", ", "[", "]"));

The joiner() method can have from one to three parameters (delimiter, prefix, suffix). The most handy thing about using joiner() – developer don’t need to check if the stream reaches its end to apply the suffix and not to apply a delimiter. Collector will take care of that.

Processing the average value of all numeric elements of the stream:

double averagePrice = productList.stream()
  .collect(Collectors.averagingInt(Product::getPrice));

Processing the sum of all numeric elements of the stream:

int summingPrice = productList.stream()
  .collect(Collectors.summingInt(Product::getPrice));

Methods averagingXX(), summingXX() and summarizingXX() can work as with primitives (int, long, double) as with their wrapper classes (Integer, Long, Double). One more powerful feature of these methods is providing mapping. So, developer don’t need to use an additional map() operation before the collect() method.

Collecting statistical information about stream’s elements:

IntSummaryStatistics statistics = productList.stream()
  .collect(Collectors.summarizingInt(Product::getPrice));

By using the resulting instance of type IntSummaryStatistics developer can create a statistical report by applying toString() method. The result will be a String common to this one “IntSummaryStatistics{count=5, sum=86, min=13, average=17,200000, max=23}”. It is also easy to extract from this object separate values for count, sum, min, average by applying methods getCount(), getSum(), getMin(), getAverage(), getMax(). All these values can be extracted from a single pipeline.

Grouping of stream’s elements according to the specified function:

Map<Integer, List<Product>> collectorMapOfLists = productList.stream()
  .collect(Collectors.groupingBy(Product::getPrice));

In the example above the stream was reduced to the Map which groups all products by their price.

Dividing stream’s elements into groups according to some predicate:

Map<Boolean, List<Product>> mapPartioned = productList.stream()
  .collect(Collectors.partitioningBy(element -> element.getPrice() > 15));

Pushing the collector to perform additional transformation:

Set<Product> unmodifiableSet = productList.stream()
  .collect(Collectors.collectingAndThen(Collectors.toSet(),
  Collections::unmodifiableSet));

In this particular case the collector has converted a stream to a Set and then created the unmodifiable Set out of it.

Custom collector:

If, for some reason, a custom collector should be created, the most easier and the less verbose way of doing so – is to use the method of() of the type Collector.

Collector<Product, ?, LinkedList<Product>> toLinkedList =
  Collector.of(LinkedList::new, LinkedList::add, 
    (first, second) -> { 
       first.addAll(second); 
       return first; 
    });

LinkedList<Product> linkedListOfPersons =
  productList.stream().collect(toLinkedList);

In this example an instance of the Collector got reduced to the LinkedList<Persone>.

Parallel Streams

Before Java 8, parallelization was complex. Emerging of the ExecutorService and the ForkJoin simplified developer’s life a little bit, but they still should to keep in mind how to create a specific executor, how to run it and so on. Java 8 introduced a way of accomplishing parallelism in a functional style.

The API allows creating parallel streams, which perform operations in a parallel mode. When the source of a stream is a Collection or an array it can be achieved with the help of the parallelStream() method:

Stream<Product> streamOfCollection = productList.parallelStream();
boolean isParallel = streamOfCollection.isParallel();
boolean bigPrice = streamOfCollection
  .map(product -> product.getPrice() * 12)
  .anyMatch(price -> price > 200);

If the source of stream is something different than a Collection or an array, the parallel() method should be used:

IntStream intStreamParallel = IntStream.range(1, 150).parallel();
boolean isParallel = intStreamParallel.isParallel();

Under the hood, Stream API automatically uses the ForkJoin framework to execute operations in parallel. By default the common thread pool will be used and there is no way (at least for now) to assign some custom thread pool to it.

When using streams in parallel mode, avoid blocking operations and use parallel mode when tasks need the similar amount of time to execute (if one task lasts much longer than the other, it can slow down the complete app’s workflow).

The stream in parallel mode can be converted back to sequential mode by using the sequential() method:

IntStream intStreamSequential = intStreamParallel.sequential();
boolean isParallel = intStreamSequential.isParallel();

Conclusions

The Stream API is a powerful but simple to understand set of tools for processing sequence of elements. It allows us to reduce a huge amount of boilerplate code, create more readable programs and improve app’s productivity when used properly.

In most of the code samples shown in this article streams were left unconsumed (we didn’t apply the close() method or a terminal operation). In a real app, don’t leave an instantiated streams unconsumed as that will lead to memory leaks.

The complete code samples that accompany the article are available at GitHub.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

A Quick Guide to Spring MVC Matrix Variables

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

The URI specification RFC 3986 defined URI path parameters as name-value pairs. Matrix variables is a Spring coined term, and an alternative implementation for passing and parsing URI path parameters.

Matrix variables support became available in Spring MVC 3.2 and is meant to simplify requests with a large number of parameters.

In this article, we will show how we can simplify complex GET requests that use either variable or optional path parameters inside the different path segments of an URI.

2. Configuration

In order to enable Spring MVC Matrix Variables, let’s start with the configuration:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);
    }
}

Otherwise, they’re disabled by default.

3. How to Use Matrix Variables

These variables can appear in any part of the path and the character equals (“=”) is used for giving values and the semicolon(‘;’) for delimiting each matrix variable. On the same path, we can also repeat the same variable name or separate different values using the character comma(‘,’).

Our example has a controller that provides information about the employees. Each employee has a working area and we are able to do a search by that attribute. The following request could be used for searching:

http://localhost:8080/spring-mvc-java/employeeArea/workingArea=rh,informatics,admin

or like this:

http://localhost:8080/spring-mvc-java
  /employeeArea/workingArea=rh;workingArea=informatics;workingArea=admin

When we want to refer to these variables in Spring MVC, we should use the annotation @MatrixVariable.

In our examples, we will use the Employee class:

public class Employee {

    private long id;
    private String name;
    private String contactNumber;

    // standard setters and getters 
}

And also the Company class:

public class Company {

    private long id;
    private String name;

    // standard setters and getters
}

These two classes will bind the request parameters.

4. Defining Matrix Variable Properties

We are able to define required or default properties for the variable. In the following example, the contactNumber is required, so it must be included in our path, something like this:

http://localhost:8080/spring-mvc-java/employeesContacts/contactNumber=223334411

The request will be handled by the following method:

@RequestMapping(value = "/employeesContacts/{contactNumber}", 
  method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<List<Employee>> getEmployeeBycontactNumber(
  @MatrixVariable(required = true) String contactNumber) {
    List<Employee> employeesList = new ArrayList<Employee>();
    ...
    return new ResponseEntity<List<Employee>>(employeesList, HttpStatus.OK);
}

As a result, we will get all the employees which have the contact number 223334411.

5. Complement Parameter

Matrix variables can complement path variables.

For example, we are searching an employee for his/her name, but we can also include the starting numbers of his/her contact number.

The request for this search should be like this:

http://localhost:8080/spring-mvc-java/employees/John;beginContactNumber=22001

The request will be handled by the following method:

@RequestMapping(value = "/employees/{name}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<List<Employee>> getEmployeeByNameAndBeginContactNumber(
  @PathVariable String name, @MatrixVariable String beginContactNumber) {
    List<Employee> employeesList = new ArrayList<Employee>();
    ...
    return new ResponseEntity<>(employeesList, HttpStatus.OK);
}

As a result, we will get all the employees which have the contact number 22001 or whose name is John.

6. Binding All Matrix Variables

If, for some reason, we want to get all the variables that are available on the path, we can binding them to a Map:

http://localhost:8080/spring-mvc-java/employeeData/id=1;name=John;contactNumber=2200112334

This request will be handled by the following method:

@RequestMapping(value = "employeeData/{employee}",
  method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Map<String, String>> getEmployeeData(
  @MatrixVariable Map<String, String> matrixVars) {
    return new ResponseEntity<>(matrixVars, HttpStatus.OK);
}

Of course, we are able to restrict binding to the matrix variables of a specific part of the path. For example, if we have a request like this:

http://localhost:8080/spring-mvc-java/
  companyEmployee/id=2;name=Xpto/employeeData/id=1;name=John;
  contactNumber=2200112334

And we only want to get all the variables that belong to employeeData, then we should use as an input parameter this:

@RequestMapping(
 value = "/companyEmployee/{company}/employeeData/{employee}",
 method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Map<String, String>> getEmployeeDataFromCompany(
  @MatrixVariable(pathVar = "employee") Map<String, String> matrixVars) {
  ...
}

7. Partial Binding

Apart from simplicity, flexibility is another gain, matrix variables can be used in a variety of different ways. For example, we are able to get each variable from each path segment. Consider the following request:

http://localhost:8080/spring-mvc-java/
  companyData/id=2;name=Xpto/employeeData/id=1;name=John;
  contactNumber=2200112334

If we only want to know the matrix variable name of the companyData segment, then, we should use as an input parameter the following:

@MatrixVariable(value="name", pathVar="company") String name

8. Conclusion

This article illustrated some of the various ways that matrix variables can be used.

It’s very important to understand how this new tool can deal with requests that are too complex or help us add more parameters to delimit our search.

The implementation of all these examples and code snippets can be found in a github project – this is an Eclipse based project, so it should be easy to import and run as it is.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Java Web Weekly, Issue 129

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> Notes on Reactive Programming Part II: Writing Some Code [spring.io]

A reactive system is an entirely different beast, and such a good fit for a small set of scenarios.

A great writeup to go through if you want to skate where the puck is going.

>> Java EE 8 in Crisis [xenonique.co.uk]

And since we’re talking about where we’re headed, the state and outlook of Java EE 8 is significant for the entire Java community and ecosystem.

>> How to implement a custom String-based sequence identifier generator with Hibernate [vladmihalcea.com]

A super practical, focused solution on generating String ids with Hibernate (which is actually something I wandered about in the past).

And, as always, Vlad’s picking his topics with the help and involvement of the community, which is a really a solid way to go about things. A cool resource.

>> How To Implement hashCode Correctly [codefx.org]

The next back-to-basics writeup after we had a look at equals last week. I knew this one was coming.

>> Configure Once, Run Everywhere: Decoupling Configuration and Runtime [infoq.com]

Real-world project configuration is never as easy as we might initially think.

Now – I’m not sure if a standard is the answer here, but the practical approach here looks interesting.

>> It’s Time to Unlearn Everything You Know About Java Exceptions [takipi.com]

A high level piece about how to actually do exceptions well. It also reads well, I think Alex had some fun writing this one.

>> Should you use JPA for your next project? [thoughts-on-java.org]

Hibernate and JPA are certainly not a good fit for every type of project out there, but they’re a solid base for a lot of them. And if you really get to know the tool well, it can be surprising how far you can go.

This interactive writeup can be helpful in making the decision when you’re starting up a new project, or at least give you some context around that decision.

>> JDK 9 is not (yet) Feature Complete — how will we get there? [mail.openjdk.java.net]

Yeah.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Mutation Testing [cleancoder.com]

A good intro to mutation testing and also to a library that might be interesting to explore – pitest.

>> Serverless Architectures [martinfowler.com]

>> Serverless Reference Architectures with AWS Lambda [allthingsdistributed.com]

I don’t know much about this architectural style, and these writeups were a good way to get started.

Also worth reading:

3. Musings

>> Things I learned from doing my first workshop [swizec.com]

I like this writeup, mostly because it resonates with my own experiences, but also because I learn a lot from seeing other people leveling up and getting a glimpse into how they think. Good stuff.

>> Creating Your Code Review Checklist [daedtech.com]

Some good aspects to think about on your next code review.

>> Three Martini Open Office Plans [daedtech.com]

A fun exploration of whether or not open office plans make sense, from the POV of an outsider.

For me personally it’s been long enough since I last had the experience of trying to get work done in an open office, so I can half-laugh about it. But I very distinctly remember it wasn’t easy to pull off.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> What do you think management is? [dilbert.com]

>> He’s wearing headphones, what do I do? [dilbert.com]

>> All roads headed in this direction – I just took the shortest one [dilbert.com]

5. Pick of the Week

The “Hibernate Performance Tuning” course only opens up a few times a year, and the early-bird pricing only lasts until next Friday.

So, basically – if you want to level up in your understanding and command of Hibernate – definitely go through this material:

>> Hibernate Performance Tuning Online Training [thoughts-on-java.org]

If you’ve been reading Java Web Weekly for a while, you know that I very rarely pick products here. That’s simply because there aren’t too many solid courses to pick in our ecosystem. I know two of them that I feel comfortable picking here and sending out to twenty thousand readers.

This is one of the two, and I’ll definitely pick the other one when it gets close to being live.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Guava Set + Function = Map

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this tutorial – we will illustrate one of many useful features in Guava‘s collect package: how to apply a Function to a Guava Set and obtain a Map.

We’ll discuss two approaches – creating an immutable map and a live map based on the built-in guava operations and then an implementation of a custom live Map implementation.

2. Setup

First, we’ll add the Guava library as a dependency in pom.xml:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>19.0</version>
</dependency>

A quick note – you can check if there’s a newer version here.

3. The Mapping Function

Let’s first define the function that we’ll apply on the sets elements:

    Function<Integer, String> function = new Function<Integer, String>() {
        @Override
        public String apply(Integer from) {
            return Integer.toBinaryString(from.intValue());
        }
    };

The function is simply converting the value of an Integer to its binary String representation.

4. Guava toMap()

Guava offers a static utility class pertaining to Map instances. Among others, it has two operations that can be used to convert a Set to a Map by applying the defined Guava’s Function.

The following snippet shows creating an immutable Map:

Map<Integer, String> immutableMap = Maps.toMap(set, function);

The following tests asserts that the set is properly converted:

@Test
public void givenStringSetAndShhimpleMap_whenMapsToElementLength_thenCorrect() {
    Set set = new TreeSet(Arrays.asList(32, 64, 128));
    Map<Integer, String> immutableMap = Maps.toMap(set, function);
    assertTrue(immutableMap.get(32).equals("100000")
      && immutableMap.get(64).equals("1000000")
      && immutableMap.get(128).equals("10000000"));
}

The problem with the created map is that if an element is added to the source set, the derived map is not updated.

4. Guava asMap()

If we use the previous example and create a map using the Maps.asMap method:

Map<Integer, String> liveMap = Maps.asMap(set, function);

We’ll get a live map view – meaning that the changes to the originating Set will be reflected in the map as well:

@Test
public void givenStringSet_whenMapsToElementLength_thenCorrect() {
    Set<Integer> set = new TreeSet<Integer>(Arrays.asList(32, 64, 128));
    Map<Integer, String> liveMap = Maps.asMap(set, function);
    assertTrue(liveMap.get(32).equals("100000")
            && liveMap.get(64).equals("1000000")
            && liveMap.get(128).equals("10000000"));
    
    set.add(256);
    assertTrue(liveMap.get(256).equals("100000000") && liveMap.size() == 4);
}

Note that the tests assert properly despite that we added an element through a set and looked it up inside the map.

5. Building Custom Live Map

When we talk of the Map View of a Set, we are basically extending the capability of the Set using a Guava Function.

In the live Map view, changes to the Set should be updating the Map EntrySet in real time. We will create our own generic Map, sub-classing AbstractMap<K,V>, like so:

public class GuavaMapFromSet<K, V> extends AbstractMap<K, V> {
    public GuavaMapFromSet(Set<K> keys, 
        Function<? super K, ? extends V> function) { 
    }
}

Worthy of note is that the main contract of all sub-classes of AbstractMap is to implement the entrySet method, as we’ve done. We will then look at 2 critical parts of the code in the following sub-sections.

5.1. Entries

Another attribute in our Map will be entries, representing our EntrySet:

private Set<Entry<K, V>> entries;

The entries field will always be initialized using the input Set from the constructor:

public GuavaMapFromSet(Set<K> keys,Function<? super K, ? extends V> function) {
    this.entries=keys;
}

A quick note here – in order to maintain a live view, we will use the same iterator in the input Set for the subsequent Map‘s EntrySet.

In fulfilling the contract of AbstractMap<K,V>, we implement the entrySet method in which we then return entries:

@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
    return this.entries;
}

5.2. Cache

This Map stores the values obtained by applying Function to Set:

private WeakHashMap<K, V> cache;

6. The Set Iterator

We will use the input Set‘s iterator for the subsequent Map‘s EntrySet. To do this, we use a customized EntrySet as well as a customized Entry class.

6.1. The Entry Class

First, let’s see how a single entry in the Map will look like:

private class SingleEntry implements Entry<K, V> {
    private K key;
    public SingleEntry( K key) {
        this.key = key;
    }
    @Override
    public K getKey() {
        return this.key;
    }
    @Override
    public V getValue() {
        V value = GuavaMapFromSet.this.cache.get(this.key);
	if (value == null) {
	    value = GuavaMapFromSet.this.function.apply(this.key);
	    GuavaMapFromSet.this.cache.put(this.key, value);
	}
	return value;
    }
    @Override
    public V setValue( V value) {
        throw new UnsupportedOperationException();
    }
}

Clearly, in this code, we don’t allow modifying the Set from the Map View as a call to setValue throws an UnsupportedOperationException.

Pay close attention to getValue – this is the crux of our live view functionality. We check cache inside our Map for the current key (Set element).

If we find the key, we return it, else we apply our function to the current key and obtain a value, then store it in cache.

This way, whenever the Set has a new element, the map is up to date since the new values are computed on the fly.

6.2. The EntrySet

We will now implement the EntrySet:

private class MyEntrySet extends AbstractSet<Entry<K, V>> {
    private Set<K> keys;
    public MyEntrySet(Set<K> keys) {
        this.keys = keys;
    }
    @Override
    public Iterator<Map.Entry<K, V>> iterator() {
        return new LiveViewIterator();
    }
    @Override
    public int size() {
        return this.keys.size();
    }
}

We have fulfilled the contract for extending AbstractSet by overriding the iterator and size methods. But there’s more.

Remember the instance of this EntrySet will form the entries in our Map View. Normally, the EntrySet of a map simply returns a complete Entry for each iteration.

However, in our case, we need to use the iterator from the input Set to maintain our live view. We know well it will only return the Set‘s elements, so we also need a custom iterator.

6.3. The Iterator

Here is the implementation of our iterator for the above EntrySet:

public class LiveViewIterator implements Iterator<Entry<K, V>> {
    private Iterator<K> inner;
    
    public LiveViewIterator () {
        this.inner = MyEntrySet.this.keys.iterator();
    }
    
    @Override
    public boolean hasNext() {
        return this.inner.hasNext();
    }
    @Override
    public Map.Entry<K, V> next() {
        K key = this.inner.next();
        return new SingleEntry(key);
    }
    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
}

LiveViewIterator must reside inside the MyEntrySet class, this way, we can share the Set‘s iterator at initialization.

When looping through GuavaMapFromSet‘s entries using the iterator, a call to next simply retrieves the key from the Set‘s iterator and constructs a SingleEntry.

7. Putting It all Together

After stitching together what we have covered in this tutorial, let us take a replace the liveMap variable from the previous samples, and replace it with our custom map:

@Test
public void givenIntSet_whenMapsToElementBinaryValue_thenCorrect() {
    Set<Integer> set = new TreeSet<>(Arrays.asList(32, 64, 128));
    Map<Integer, String> customMap = new GuavaMapFromSet<Integer, String>(set, function);
    
    assertTrue(customMap.get(32).equals("100000")
      && customMap.get(64).equals("1000000")
      && customMap.get(128).equals("10000000"));
}

Changing the content of input Set, we will see that the Map updates in real time:

@Test
public void givenStringSet_whenMapsToElementLength_thenCorrect() {
    Set<Integer> set = new TreeSet<Integer>(Arrays.asList(32, 64, 128));
    Map<Integer, String> customMap = Maps.asMap(set, function);
    
    assertTrue(customMap.get(32).equals("100000")
      && customMap.get(64).equals("1000000")
      && customMap.get(128).equals("10000000"));
    
    set.add(256);
    assertTrue(customMap.get(256).equals("100000000") && customMap.size() == 4);
}

8. Conclusion

In this tutorial, we have looked at the different ways that one can leverage Guava operations and obtain a Map view from a Set by applying a Function.

The full implementation of all these examples and code snippets can be found in my Guava github project – this is an Eclipse based project, so it should be easy to import and run as it is.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Mockito vs EasyMock vs JMockit

$
0
0

1. Introduction

1.1. Overview

In this post we’re going to talk about mocking: what it is, why use it and several examples of how to mock the same test case using some of the most used mocking libraries for Java.

We’ll start with some formal/semi-formal definitions of mocking concepts, then we’ll present the case under test, follow up with examples for each library and end up with some conclusions. The chosen libraries are Mockito, EasyMock and JMockit.

If you feel that you already know the basics of mocking, maybe you can skip to Point 2 without reading the next three points.

1.2. Reasons to Use Mocks

We’ll start assuming that you already code following some kind of driven development methodology centred on tests (TDD, ATDD or BDD). Or simply that you want to create a test for an existing class that relies on dependencies to achieve its functionality.

In any case, when unit-testing a class, we want to test only its functionality and not that of its dependencies (either because we trust their implementation or because we’ll test it ourselves).

In order to achieve this, we need to provide to the object-under-test, a replacement that we can control for that dependency. This way we can force extreme return values, exception throwing or simply reduce time-consuming methods to a fixed return value.

This controlled replacement is the mock and it will help you to simplify test coding and to reduce test execution time.

1.3. Mock Concepts and Definition

Let’s see four definitions from an article written by Martin Fowler that sums up the basics everyone should know about mocks:

  • Dummy objects are passed around but never actually used. Usually, they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it ‘sent’, or maybe only how many messages it ‘sent’.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

1.4 To Mock or Not to Mock: That Is the Question

Not everything must be mocked. Sometimes it’s better to do an integration test as mocking that method/feature would actually be just working for little actual benefit. In our test case (that will be shown in the next point) that would be testing the LoginDao.

The LoginDao would use some kind of third party library for DB access, and mocking it would only consist on assuring that parameters had been prepared for the call, but we still would need to test that the call returns the data we really wanted.

For that reason, it won’t be included in this example (although we could actually write both the unit test with mock calls for the third party library calls AND an integration test with DBUnit for testing the actual performance of the third party library).

2. Test Case

With everything in the previous section in mind, let’s propose a quite typical test case and how we’ll test it using mocks (when it makes sense to actually use mocks). This will help us to have a common scenario for later on been able to compare the different mocking libraries.

2.1 Proposed Case

The proposed test case will be the login process in an application with a layered architecture.

The login request will be handled by a controller, that uses a service, that uses a DAO (that looks for user credentials on a DB). We won’t deepen too much into each layer’s implementation and will focus more on the interactions between the components of each layer.

This way, we’ll have a LoginController, a LoginService and a LoginDAO. Let’s see a diagram for clarification:

Test case diagram

2.2 Implementation

We’ll follow now with the implementation used for the test case, so we can understand what’s happening (or what should happen) on the tests.

We’ll start with the model used for all operations, UserForm, that will only hold the user’s name and password (we’re using public access modifiers to simplify) and a getter method for the username field in order to allow mocking for that property:

public class UserForm {
    public String password;
    public String username;
    public String getUsername(){
        return username;
    }
}

Let’s follow with LoginDAO, that will be void of functionality as we only want its methods to be there so we can mock them when needed:

public class LoginDao {
    public int login(UserForm userForm){
        return 0;
    }
}

LoginDao will be used by LoginService in its login method. LoginService will also have a setCurrentUser method that returns void in order to test that kind of mocking.

public class LoginService {
    private LoginDao loginDao;
    private String currentUser;

    public boolean login(UserForm userForm) {
        assert null != userForm;
        int loginResults = loginDao.login(userForm);
        switch (loginResults){
            case 1:
                return true;
            default:
                return false;
        }
    }

    public void setCurrentUser(String username) {
        if(null != username){
            this.currentUser = username;
        }
    }
}

Finally, LoginController will use LoginService for its login method. This will include:

  • a case in which no calls to the mocked service will be done.
  • a case in which only one method will be called.
  • a case in which all methods will be called.
  • a case in which exception throwing will be tested.
public class LoginController {
    public LoginService loginService;

    public String login(UserForm userForm){
        if(null == userForm){
            return "ERROR";
        }else{
            boolean logged;

            try {
                logged = loginService.login(userForm);
            } catch (Exception e) {
                return "ERROR";
            }

            if(logged){
                loginService.setCurrentUser(userForm.getUsername());
                return "OK";
            }else{
                return "KO";
            }
        }
    }
}

Now that we’ve seen what is it that we’re trying to test, let’s see how we’ll mock it with each library.

3. Test Setup

3.1 Mockito

For Mockito we’ll be using version 1.10.19 as version 2 is still beta (at least while writing this).

The easiest way of creating and using mocks is via the @Mock and @InjectMocks annotations. The first one will create a mock for the class used to define the field and the second one will try to inject said created mocks into the annotated mock.

There are more annotations such as @Spy that lets you create a partial mock (a mock that uses the normal implementation in non-mocked methods).

That been said, you need to call MockitoAnnotations.initMocks(this) before executing any tests that would use said mocks for all of this “magic” to work. This is usually done in a @Before annotated method. You can also use the MockitoJUnitRunner.

public class LoginControllerTest {

    @Mock
    private LoginDao loginDao;

    @Spy
    @InjectMocks
    private LoginService spiedLoginService;

    @Mock
    private LoginService loginService;

    @InjectMocks
    private LoginController loginController;

    @Before
    public void setUp() {
        loginController = new LoginController();
        MockitoAnnotations.initMocks(this);
    }
}

3.2 EasyMock

For EasyMock, we’ll be using version 3.4 (Javadoc). Note that with EasyMock, for mocks to start “working”, you must call EasyMock.replay(mock) on every test method, or you will receive an exception.

Mocks and tested classes can also be defined via annotations, but in this case instead of calling a static method for it to work, we’ll be using the EasyMockRunner for the test class.

Mocks are created with the @Mock annotation and the tested object with the @TestSubject one (which will get its dependencies injected from created mocks). The tested object must be created in-line.

@RunWith(EasyMockRunner.class)
public class LoginControllerTest {

    @Mock
    private LoginDao loginDao;

    @Mock
    private LoginService loginService;

    @TestSubject
    private LoginController loginController = new LoginController();
}

3.3. JMockit

For JMockit we’ll be using version 1.24 (Javadoc) as version 1.25 hasn’t been released yet (at least while writing this).

Setup for JMockit is as easy as with Mockito, with the exception that there is no specific annotation for partial mocks (and really no need either) and that you must use JMockit as the test runner.

Mocks are defined using the @Injectable annotation (that will create only one mock instance) or with @Mocked annotation (that will create mocks for every instance of the class of the annotated field).

The tested instance gets created (and its mocked dependencies injected) using the @Tested annotation.

@RunWith(JMockit.class)
public class LoginControllerTest {

    @Injectable
    private LoginDao loginDao;

    @Injectable
    private LoginService loginService;

    @Tested
    private LoginController loginController;
}

4. Verifying No Calls to Mock

4.1. Mockito

For verifying that a mock received no calls in Mockito you have the method verifyZeroInteractions() that accepts a mock.

@Test
public void assertThatNoMethodHasBeenCalled() {
    loginController.login(null);
    Mockito.verifyZeroInteractions(loginService);
}

4.2. EasyMock

For verifying that a mock received no calls you simply don’t specify behaviour, you replay the mock and lastly you verify it.

@Test
public void assertThatNoMethodHasBeenCalled() {
    EasyMock.replay(loginService);
    loginController.login(null);
    EasyMock.verify(loginService);
}

4.3. JMockit

For verifying that a mock received no calls you simply don’t specify expectations for that mock and do a FullVerifications(mock) for said mock.

@Test
public void assertThatNoMethodHasBeenCalled() {
    loginController.login(null);
    new FullVerifications(loginService) {};
}

5. Defining Mocked Method Calls and Verifying Calls to Mocks

5.1. Mockito

For mocking method calls, you can use Mockito.when(mock.method(args)).thenReturn(value). Here you can return different values for more than one call just adding them as more parameters: thenReturn(value1, value2, value-n, …).

Note that you can’t mock void returning methods with this syntax. In said cases you’ll use a verification of said method (as shown on line 11).

For verifying calls to a mock you can use Mockito.verify(mock).method(args) and you can also verify that no more calls were done to a mock using verifyNoMoreInteractions(mock).

For verifying args, you can pass specific values or use predefined matchers like any(), anyString()anyInt(). There are a lot more of that kind of matchers and even the possibility to define your own matchers which we’ll see in following examples.

@Test
public void assertTwoMethodsHaveBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    Mockito.when(loginService.login(userForm)).thenReturn(true);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    Mockito.verify(loginService).login(userForm);
    Mockito.verify(loginService).setCurrentUser("foo");
}

@Test
public void assertOnlyOneMethodHasBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    Mockito.when(loginService.login(userForm)).thenReturn(false);

    String login = loginController.login(userForm);

    Assert.assertEquals("KO", login);
    Mockito.verify(loginService).login(userForm);
    Mockito.verifyNoMoreInteractions(loginService);
}

5.2. EasyMock

For mocking method calls, you use EasyMock.expect(mock.method(args)).andReturn(value).

For verifying calls to a mock, you can use EasyMock.verify(mock) but you must call it always after calling EasyMock.replay(mock).

For verifying args, you can pass specific values or you have predefined matchers like isA(Class.class), anyString()anyInt(), and a lot more of that kind of matchers and again the possibility to define your own matchers.

@Test
public void assertTwoMethodsHaveBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    EasyMock.expect(loginService.login(userForm)).andReturn(true);
    loginService.setCurrentUser("foo");
    EasyMock.replay(loginService);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    EasyMock.verify(loginService);
}

@Test
public void assertOnlyOneMethodHasBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    EasyMock.expect(loginService.login(userForm)).andReturn(false);
    EasyMock.replay(loginService);

    String login = loginController.login(userForm);

    Assert.assertEquals("KO", login);
    EasyMock.verify(loginService);
}

5.3. JMockit

With JMockit, you have clearly defined steps for testing: record, replay and verify.

Record is done in a new Expectations(){{}} block (into which you can define actions for several mocks), replay is done simply by invoking a method of the tested class (that should call some mocked object) and verification is done inside a new Verifications(){{}} block (into which you can define verifications for several mocks).

For mocking method calls, you can use mock.method(args); result = value; inside any Expectations block. Here you can return different values for more than one call just using returns(value1, value2, …, valuen); instead of result = value;.

For verifying calls to a mock you can use new Verifications(){{mock.call(value)}} or new Verifications(mock){{}} to verify every expected call previously defined.

For verifying args, you can pass specific values or you have predefined values like any, anyStringanyLong, and a lot more of that kind of special values and again the possibility to define your own matchers (that must be Hamcrest matchers).

@Test
public void assertTwoMethodsHaveBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    new Expectations() {{
        loginService.login(userForm); result = true;
        loginService.setCurrentUser("foo");
    }};

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    new FullVerifications(loginService) {};
}

@Test
public void assertOnlyOneMethodHasBeenCalled() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    new Expectations() {{
        loginService.login(userForm); result = false;
        // no expectation for setCurrentUser
    }};

    String login = loginController.login(userForm);

    Assert.assertEquals("KO", login);
    new FullVerifications(loginService) {};
}

6. Mocking Exception Throwing

6.1. Mockito

Exception throwing can be mocked using .thenThrow(ExceptionClass.class) after a Mockito.when(mock.method(args)).

@Test
public void mockExceptionThrowin() {
    UserForm userForm = new UserForm();
    Mockito.when(loginService.login(userForm)).thenThrow(IllegalArgumentException.class);

    String login = loginController.login(userForm);

    Assert.assertEquals("ERROR", login);
    Mockito.verify(loginService).login(userForm);
    Mockito.verifyZeroInteractions(loginService);
}

6.2. EasyMock

Exception throwing can be mocked using .andThrow(new ExceptionClass()) after an EasyMock.expect(…) call.

@Test
public void mockExceptionThrowing() {
    UserForm userForm = new UserForm();
    EasyMock.expect(loginService.login(userForm)).andThrow(new IllegalArgumentException());
    EasyMock.replay(loginService);

    String login = loginController.login(userForm);

    Assert.assertEquals("ERROR", login);
    EasyMock.verify(loginService);
}

6.3. JMockit

Mocking exception throwing with JMockito is especially easy. Just return an Exception as the result of a mocked method call instead of the “normal” return.

@Test
public void mockExceptionThrowing() {
    UserForm userForm = new UserForm();
    new Expectations() {{
        loginService.login(userForm); result = new IllegalArgumentException();
        // no expectation for setCurrentUser
    }};

    String login = loginController.login(userForm);

    Assert.assertEquals("ERROR", login);
    new FullVerifications(loginService) {};
}

7. Mocking an Object to Pass Around

7.1. Mockito

You can create a mock also to pass as an argument for a method call. With Mockito, you can do that with a one-liner.

@Test
public void mockAnObjectToPassAround() {
    UserForm userForm = Mockito.when(Mockito.mock(UserForm.class).getUsername())
      .thenReturn("foo").getMock();
    Mockito.when(loginService.login(userForm)).thenReturn(true);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    Mockito.verify(loginService).login(userForm);
    Mockito.verify(loginService).setCurrentUser("foo");
}

7.2. EasyMock

Mocks can be created in-line with EasyMock.mock(Class.class). Afterwards, you can use EasyMock.expect(mock.method()) to prepare it for execution, always remembering to call EasyMock.replay(mock) before using it.

@Test
public void mockAnObjectToPassAround() {
    UserForm userForm = EasyMock.mock(UserForm.class);
    EasyMock.expect(userForm.getUsername()).andReturn("foo");
    EasyMock.expect(loginService.login(userForm)).andReturn(true);
    loginService.setCurrentUser("foo");
    EasyMock.replay(userForm);
    EasyMock.replay(loginService);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    EasyMock.verify(userForm);
    EasyMock.verify(loginService);
}

7.3. JMockit

To mock an object for just one method, you can simply pass it mocked as a parameter to the test method. Then you can create expectations as with any other mock.

@Test
public void mockAnObjectToPassAround(@Mocked UserForm userForm) {
    new Expectations() {{
        userForm.getUsername(); result = "foo";
        loginService.login(userForm); result = true;
        loginService.setCurrentUser("foo");
    }};
    
    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    new FullVerifications(loginService) {};
    new FullVerifications(userForm) {};
}

8. Custom Argument Matching

8.1. Mockito

Sometimes argument matching for mocked calls needs to be a little more complex than just a fixed value or anyString(). For that cases with Mockito has its own matcher class that is used with argThat(ArgumentMatcher<>).

@Test
public void argumentMatching() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // default matcher
    Mockito.when(loginService.login(Mockito.any(UserForm.class))).thenReturn(true);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    Mockito.verify(loginService).login(userForm);
    // complex matcher
    Mockito.verify(loginService).setCurrentUser(Mockito.argThat(
        new ArgumentMatcher<String>() {
            @Override
            public boolean matches(Object argument) {
                return argument instanceof String && 
                  ((String) argument).startsWith("foo");
            }
        }
    ));
}

8.2. EasyMock

Custom argument matching is a little bit more complicated with EasyMock as you need to create a static method in which you create the actual matcher and then report it with EasyMock.reportMatcher(IArgumentMatcher).

Once this method is created, you use it on your mock expectation with a call to the method (like seen in the example in line ).

@Test
public void argumentMatching() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // default matcher
    EasyMock.expect(loginService.login(EasyMock.isA(UserForm.class))).andReturn(true);
    // complex matcher
    loginService.setCurrentUser(specificArgumentMatching("foo"));
    EasyMock.replay(loginService);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    EasyMock.verify(loginService);
}

private static String specificArgumentMatching(String expected) {
    EasyMock.reportMatcher(new IArgumentMatcher() {
        @Override
        public boolean matches(Object argument) {
            return argument instanceof String 
              && ((String) argument).startsWith(expected);
        }

        @Override
        public void appendTo(StringBuffer buffer) {
            //NOOP
        }
    });
    return null;
}

8.3. JMockit

Custom argument matching with JMockit is done with the special withArgThat(Matcher) method (that receives Hamcrest‘s Matcher objects).

@Test
public void argumentMatching() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // default matcher
    new Expectations() {{
        loginService.login((UserForm) any);
        result = true;
        // complex matcher
        loginService.setCurrentUser(withArgThat(new BaseMatcher<String>() {
            @Override
            public boolean matches(Object item) {
                return item instanceof String && ((String) item).startsWith("foo");
            }

            @Override
            public void describeTo(Description description) {
                //NOOP
            }
        }));
    }};

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    new FullVerifications(loginService) {};
}

9. Partial Mocking

9.1. Mockito

Mockito allows partial mocking (a mock that uses the real implementation instead of mocked method calls in some of its methods) in two ways.

You can either use .thenCallRealMethod() in a normal mock method call definition or you can create a spy instead of a mock in which case the default behaviour for that will be to call the real implementation in all non-mocked methods.

@Test
public void partialMocking() {
    // use partial mock
    loginController.loginService = spiedLoginService;
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // let service's login use implementation so let's mock DAO call
    Mockito.when(loginDao.login(userForm)).thenReturn(1);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    // verify mocked call
    Mockito.verify(spiedLoginService).setCurrentUser("foo");
}

9.2. EasyMock

Partial mocking also gets a little more complicated with EasyMock, as you need to define which methods will be mocked when creating the mock.

This is done with EasyMock.partialMockBuilder(Class.class).addMockedMethod(“methodName”).createMock(). Once this is done, you can use the mock as any other non-partial mock.

@Test
public void partialMocking() {
    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // use partial mock
    LoginService loginServicePartial = EasyMock.partialMockBuilder(LoginService.class)
      .addMockedMethod("setCurrentUser").createMock();
    loginServicePartial.setCurrentUser("foo");
    // let service's login use implementation so let's mock DAO call
    EasyMock.expect(loginDao.login(userForm)).andReturn(1);

    loginServicePartial.setLoginDao(loginDao);
    loginController.loginService = loginServicePartial;
    
    EasyMock.replay(loginDao);
    EasyMock.replay(loginServicePartial);

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    // verify mocked call
    EasyMock.verify(loginServicePartial);
    EasyMock.verify(loginDao);
}

9.3. JMockit

Partial mocking with JMockit is especially easy. Every method call for which no mocked behaviour has been defined in an Expectations(){{}} uses the “real” implementation.

In this case as no expectation is given for LoginService.login(UserForm) the actual implementation (and the call to LoginDAO.login(UserForm)) is performed.

@Test
public void partialMocking() {
    // use partial mock
    LoginService partialLoginService = new LoginService();
    partialLoginService.setLoginDao(loginDao);
    loginController.loginService = partialLoginService;

    UserForm userForm = new UserForm();
    userForm.username = "foo";
    // let service's login use implementation so let's mock DAO call
    new Expectations() {{
        loginDao.login(userForm); result = 1;
        // no expectation for loginService.login
        partialLoginService.setCurrentUser("foo");
    }};

    String login = loginController.login(userForm);

    Assert.assertEquals("OK", login);
    // verify mocked call
    new FullVerifications(partialLoginService) {};
    new FullVerifications(loginDao) {};
}

10. Conclusion

In this post, we’ve been comparing three Java mock libraries, each one with its strong points and downsides.

  • All three of them are easily configured with annotations to help you define mocks and the object-under-test, with runners to make mock injection as painless as possible.
    • We’d say Mockito would win here as it has a special annotation for partial mocks, but JMockit actually doesn’t even need it, so let’s say that it’s a tie between those two.
  • All three of them follow more or less the record-replay-verify pattern, but in our opinion, the best one to do so is JMockit as it actually forces you to use those in blocks, so tests get more structured.
  • Easiness of use is important so you can work as less as possible to define your tests. JMockit will be the chosen option for its fixed-always-the-same structure.
  • Mockito is more or less THE most known, so the community will be bigger.
  • Having to call replay every time you want to use a mock is a clear no-go so we’ll put a minus one for EasyMock.
  • Consistency/simplicity is also important for me. We loved the way of returning results of JMockit that is the same for “normal” results as for exceptions.

Will all this been said, we’re going to choose JMockit as a kind of a winner even though up till now we’ve been using Mockito as we’ve been captivated by its simplicity and fixed structure and will try and use it from now on.

The full implementation of this tutorial can be found on the GitHub project so feel free to download it and play with it.

Spring REST API with Protocol Buffers

$
0
0

I just announced the Master Class of my "REST With Spring" Course:

>> THE "REST WITH SPRING" CLASSES

1. Overview

Protocol Buffers is a language and platform neutral mechanism for serialization and deserialization of structured data, which is proclaimed by Google, its creator, to be much faster, smaller and simpler than other types of payloads, such as XML and JSON.

This tutorial guides you through setting up a REST API to take advantage of this binary-based message structure.

2. Protocol Buffers

This section gives some basic information on Protocol Buffers and how they are applied in the Java ecosystem.

2.1. Introduction to Protocol Buffers

In order to make use of Protocol Buffers, we need to define message structures in .proto files. Each file is a description of the data that might be transferred from one node to another, or stored in data sources. Here is an example of .proto files, which is named baeldung.proto and lives in the src/main/resources directory. This file will be used in this tutorial later on:

syntax = "proto3";
package baeldung;
option java_package = "com.baeldung.protobuf";
option java_outer_classname = "BaeldungTraining";

message Course {
    int32 id = 1;
    string course_name = 2;
    repeated Student student = 3;
}
message Student {
    int32 id = 1;
    string first_name = 2;
    string last_name = 3;
    string email = 4;
    repeated PhoneNumber phone = 5;
    message PhoneNumber {
        string number = 1;
        PhoneType type = 2;
    }
    enum PhoneType {
        MOBILE = 0;
        LANDLINE = 1;
    }
}

In this tutorial, we use version 3 of both protocol buffer compiler and protocol buffer language, therefore the .proto file must start with the syntax = “proto3” declaration. If a compiler version 2 is in use, this declaration would be omitted. Next comes the package declaration, which is the namespace for this message structure to avoid naming conflicts with other projects.

The following two declarations are used for Java only: java_package option specifies the package for our generated classes to live in, and java_outer_classname option indicates name of the class enclosing all the types defined in this .proto file.

Subsection 2.3 below will describe the remaining elements and how those are compiled into Java code.

2.2. Protocol Buffers with Java

After a message structure is defined, we need a compiler to convert this language neutral content to Java code. You can follow the instructions in the Protocol Buffers repository in order to get an appropriate compiler version. Alternatively, you may download a pre-built binary compiler from the Maven central repository by searching for the com.google.protobuf:protoc artifact, then picking up an appropriate version for your platform.

Next, copy the compiler to the src/main directory of your project and execute the following command in the command line:

protoc --java_out=java resources/baeldung.proto

This should generate a source file for the BaeldungTraining class within the com.baeldung.protobuf package, as specified in the option declarations of the baeldung.proto file.

In addition to the compiler, Protocol Buffers runtime is required. This can be achieved by adding the following dependency to the Maven POM file:

<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.0.0-beta-3</version>
</dependency>

We may use another version of the runtime, provided that it is the same as the compiler’s version. For the latest one, please check out this link.

2.3. Compiling a Message Description

By using a compiler, messages in a .proto file are compiled into static nested Java classes. In the above example, the Course and Student messages are converted to Course and Student Java classes, respectively. At the same time, messages’ fields are compiled into JavaBeans style getters and setters inside those generated types. The marker, composed of an equal sign and a number, at the end of each field declaration is the unique tag used to encode the associated field in the binary form.

We will walk through typed fields of the messages to see how those are converted to accessor methods.

Let’s start with the Course message. It has two simple fields, including id and course_name. Their protocol buffer types, int32 and string, are translated into Java int and String types. Here are their associated getters after compilation (with implementations being left out for brevity):

public int getId();
public java.lang.String getCourseName();

Note that names of typed fields should be in snake case (individual words are separated by underscore characters) to maintain the cooperation with other languages. The compiler will convert those names to camel case according to Java conventions.

The last field of Course message, student, is of the Student complex type, which will be described below. This field is prepended by the repeated keyword, meaning that it may be repeated any number of times. The compiler generates some methods associated with the student field as follows (without implementations):

public java.util.List<com.baeldung.protobuf.BaeldungTraining.Student> getStudentList();
public int getStudentCount();
public com.baeldung.protobuf.BaeldungTraining.Student getStudent(int index);

Now we will move on to the Student message, which is used as complex type of the student field of Course message. Its simple fields, including id, first_name, last_name and email are used to create Java accessor methods:

public int getId();
public java.lang.String getFirstName();
public java.lang.String getLastName();
public java.lang.String.getEmail();

The last field, phone, is of the PhoneNumber complex type. Similar to the student field of Course message, this field is repetitive and has several associated methods:

public java.util.List<com.baeldung.protobuf.BaeldungTraining.Student.PhoneNumber> getPhoneList();
public int getPhoneCount();
public com.baeldung.protobuf.BaeldungTraining.Student.PhoneNumber getPhone(int index);

The PhoneNumber message is compiled into the BaeldungTraining.Student.PhoneNumber nested type, with two getters corresponding to the message’s fields:

public java.lang.String getNumber();
public com.baeldung.protobuf.BaeldungTraining.Student.PhoneType getType();

PhoneType, the complex type of the type field of the PhoneNumber message, is an enumeration type, which will be transformed into a Java enum type nested within the BaeldungTraining.Student class:

public enum PhoneType implements com.google.protobuf.ProtocolMessageEnum {
    MOBILE(0),
    LANDLINE(1),
    UNRECOGNIZED(-1),
    ;
    // Other declarations
}

3. Protobuf In Spring REST API

This section will guide you through setting up a REST service using Spring Boot.

3.1. Bean Declaration

Let’s start with the definition of our main @SpringBootApplication:

@SpringBootApplication
public class Application {
    @Bean
    ProtobufHttpMessageConverter protobufHttpMessageConverter() {
        return new ProtobufHttpMessageConverter();
    }

    @Bean
    public CourseRepository createTestCourses() {
        Map<Integer, Course> courses = new HashMap<>();
        Course course1 = Course.newBuilder()
          .setId(1)
          .setCourseName("REST with Spring")
          .addAllStudent(createTestStudents())
          .build();
        Course course2 = Course.newBuilder()
          .setId(2)
          .setCourseName("Learn Spring Security")
          .addAllStudent(new ArrayList<Student>())
          .build();
        courses.put(course1.getId(), course1);
        courses.put(course2.getId(), course2);
        return new CourseRepository(courses);
    }

    // Other declarations
}

The ProtobufHttpMessageConverter bean is used to convert responses returned by @RequestMapping annotated methods to protocol buffer messages.

The other bean, CourseRepository, contains some test data for our API.

What’s important here is that we’re operating with Protocol Buffer specific data – not with standard POJOs.

Here’s the simple implementation of the CourseRepository:

public class CourseRepository {
    Map<Integer, Course> courses;
    
    public CourseRepository (Map<Integer, Course> courses) {
        this.courses = courses;
    }
    
    public Course getCourse(int id) {
        return courses.get(id);
    }
}

3.2. Controller Configuration

We can define the @Controller class for a test URL as follows:

@RestController
public class CourseController {
    @Autowired
    CourseRepository courseRepo;

    @RequestMapping("/courses/{id}")
    Course customer(@PathVariable Integer id) {
        return courseRepo.getCourse(id);
    }
}

And again – the important thing here is that the Course DTO that we’re returning from the controller layer is not a standard POJO. That’s going to be the trigger for it to be converted to protocol buffer messages before being transferred back to the Client.

4. REST Clients and Testing

Now that we had a look at the simple API implementation – let’s now illustrate deserialization of protocol buffer messages on the client side – using two methods.

The first one takes advantage of the RestTemplate API with a pre-configured ProtobufHttpMessageConverter bean to automatically convert messages.

The second is using protobuf-java-format to manually transform protocol buffer responses into JSON documents.

To begin, we need to set up the context for an integration test and instruct Spring Boot to find configuration information in the Application class by declaring a test class as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest
public class ApplicationTest {
    // Other declarations
}

All code snippets in this section will be placed in the ApplicationTest class.

4.1. Expected Response

The first step to access a REST service is to determine the request URL:

private static final String COURSE1_URL = "http://localhost:8080/courses/1";

This COURSE1_URL will be used for getting the first test double course from the REST service we created before. After a GET request is sent to the above URL, the corresponding response is verified using the following assertions:

private void assertResponse(String response) {
    assertThat(response, containsString("id"));
    assertThat(response, containsString("course_name"));
    assertThat(response, containsString("REST with Spring"));
    assertThat(response, containsString("student"));
    assertThat(response, containsString("first_name"));
    assertThat(response, containsString("last_name"));
    assertThat(response, containsString("email"));
    assertThat(response, containsString("john.doe@baeldung.com"));
    assertThat(response, containsString("richard.roe@baeldung.com"));
    assertThat(response, containsString("jane.doe@baeldung.com"));
    assertThat(response, containsString("phone"));
    assertThat(response, containsString("number"));
    assertThat(response, containsString("type"));
}

We will make use of this helper method in both test cases covered in the succeeding sub-sections.

4.2. Testing with RestTemplate

Here is how we create a client, send a GET request to the designated destination, receive the response in the form of protocol buffer messages and verify it using the RestTemplate API:

@Autowired
private RestTemplate restTemplate;

@Test
public void whenUsingRestTemplate_thenSucceed() {
    ResponseEntity<Course> course = restTemplate.getForEntity(COURSE1_URL, Course.class);
    assertResponse(course.toString());
}

To make this test case work, we need a bean of the RestTemplate type to be registered in a configuration class:

@Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
    return new RestTemplate(Arrays.asList(hmc));
}

Another bean of the ProtobufHttpMessageConverter type is also required to automatically transform the received protocol buffer messages. This bean is the same as the one defined in sub-section 3.1. Since the client and server share the same application context in this tutorial, we may declare the RestTemplate bean in the Application class and re-use the ProtobufHttpMessageConverter bean.

4.3. Testing with HttpClient

The first step to use the HttpClient API and manually convert protocol buffer messages is adding the following two dependencies to the Maven POM file:

<dependency>
    <groupId>com.googlecode.protobuf-java-format</groupId>
    <artifactId>protobuf-java-format</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>

For the latest versions of these dependencies, please have a look at protobuf-java-format and httpclient artifacts in Maven central repository.

Let’s move on to create a client, execute a GET request and convert the associated response to an InputStream instance using the given URL:

private InputStream executeHttpRequest(String url) throws IOException {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet request = new HttpGet(url);
    HttpResponse httpResponse = httpClient.execute(request);
    return httpResponse.getEntity().getContent();
}

Now, we will convert protocol buffer messages in the form of an InputStream object to a JSON document:

private String convertProtobufMessageStreamToJsonString(InputStream protobufStream) throws IOException {
    JsonFormat jsonFormat = new JsonFormat();
    Course course = Course.parseFrom(protobufStream);
    return jsonFormat.printToString(course);
}

And here is how a test case uses private helper methods declared above and validates the response:

@Test
public void whenUsingHttpClient_thenSucceed() throws IOException {
    InputStream responseStream = executeHttpRequest(COURSE1_URL);
    String jsonOutput = convertProtobufMessageStreamToJsonString(responseStream);
    assertResponse(jsonOutput);
}

4.4. Response in JSON

In order to make it clear, JSON forms of the responses we received in the tests described in previous sub-sections are included herein:

id: 1
course_name: "REST with Spring"
student {
    id: 1
    first_name: "John"
    last_name: "Doe"
    email: "john.doe@baeldung.com"
    phone {
        number: "123456"
    }
}
student {
    id: 2
    first_name: "Richard"
    last_name: "Roe"
    email: "richard.roe@baeldung.com"
    phone {
        number: "234567"
        type: LANDLINE
    }
}
student {
    id: 3
    first_name: "Jane"
    last_name: "Doe"
    email: "jane.doe@baeldung.com"
    phone {
        number: "345678"
    }
    phone {
        number: "456789"
        type: LANDLINE
    }
}

5. Conclusion

This tutorial quickly introduced Protocol Buffers and illustrated the setting up of a REST API using the format with Spring. We then moved to client support and the serialization-deserialization mechanism.

The implementation of all the examples and code snippets can be found in a GitHub project.

The Master Class of my "REST With Spring" Course is finally out:

>> CHECK OUT THE CLASSES

Java Web Weekly, Issue 130

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

At the very beginning of last year, I decided to track my reading habits and share the best stuff here, on Baeldung. Haven’t missed a review since.

Here we go…

1. Spring and Java

>> High-Performance Java Persistence – Part Two [vladmihalcea.com]

I’ve been following the progress of this book for a while, and it’s clear that it’s going to be THE reference material for developers aiming to learn Hibernate and JPA for many years to come.

It’s cool that it’s finally almost ready to go out and make some waves.

>> Bean Validation and the Jigsaw Liaison [in.relation.to]

Very nice, code-heavy look into what’s coming to Java, and specifically how the modularization work is going to play with bean validation.

>> Java 9 Additions To Stream [codefx.org]

Java 9 is a-coming, and the improvements to the Stream APIs and general functionality definitely look interesting.

>> Java vs .NET vs Python vs Ruby vs Node.JS: Who Reigns the Job Market? [takipi.com]

Another interesting, data-driven writeup, this time on the state of the job market.

The guys and gals from Takipi have been on a number crunching rampage lately. My best guess is that they hired someone really good at pulling insights out of data.

>> The Fault in Our JARs: Why We Stopped Building Fat JARs [product.hubspot.com]

A different perspective to the fat jar approach of packaging and deploying applications, which makes a lot of sense at real scale.

>> Java EE Guardians Unite to Save Java EE [infoq.com]

A good, quick intro to what the Java EE Guardians group is all about, and of course the general state of the Java EE ecosystem right now.

>> I do not use a debugger [lemire.me]

An interesting take on the concept of self-imposed limitations.

And a personal note here, on learning. I was once forced to not touch my mouse, in a 2-day TDD workshop. It was frustrating, but also a huge boost in learning to get better on the keyboard.

>> Eclipse Foundation Releases Neon [infoq.com]

Yep, it’s that time of year. The new Eclipse is out.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical

>> Why I Prefer Merge Over Rebase [techblog.bozho.net]

Yes, discussing the best way to approach a git workflows can be a black hole.

This writeup though is pretty to the point, and actually offers a concrete opinion, so it’s well worth a read.

Also worth reading:

3. Musings

>> What It Really Means to Niche Down [daedtech.com]

Intelligent, intentional positioning is rare in our space, which is truly unfortunate. A good read talking about the way to niche down and the benefits that come with such an initially scary prospect.

>> Updating the PerfectTablePlan website [successfulsoftware.net]

This is a cool read about the impact of re-designing a product page.

And it has nothing to do with Java (just FYI).

>> What isn’t Serverless? [martinfowler.com]

>> Serverless [martinfowler.com]

>> Unpacking ‘Function as a Service’ [martinfowler.com]

Different points in the serverless discussion.

Even though I’ve not experimented with most of these concepts in practice, this writeup definitely clears things up and starts making the possibilities clearer for when I will.

Also worth reading:

4. Comics

And my favorite Dilberts of the week:

>> Don’t blame me for not knowing [dilbert.com]

>> Are you trying to be a jerk? [dilbert.com]

>> Engineer thinks news is magic [dilbert.com]

5. Pick of the Week

>> You don’t have my permission [signalvnoise.com]

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE


Migrating to the New Java 8 Date Time API

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this tutorial you will learn how to refactor your code in order to leverage the new Date Time API introduced in Java 8.

2. New API at a Glance

Working with dates in Java used to be hard. The old date library provided by JDK included only three classes: java.util.Date, java.util.Calendar and java.util.Timezone.

These were only suitable for the most basic tasks. For anything even remotely complex, the developers had to either use third-party libraries or write tons of custom code.

Java 8 introduced a completely new Date Time API (java.util.time.*) that is loosely based on the popular Java library called JodaTime. This new API dramatically simplified date and time processing and fixed many shortcomings of the old date library.

1.1. API Clarity

A first advantage of the new API is clarity – the API is very clear, concise and easy to understand. It does not have a lot of inconsistencies found in the old library such as the field numbering (in Calendar months are zero-based, but days of week are one-based).

1.2. API Flexibility

Another advantage is flexibility – working with multiple representations of time. The old date library included only a single time representation class – java.util.Date, which despite its name, is actually a timestamp. It only stores the number of milliseconds elapsed since the Unix epoch.

The new API has many different time representations, each suitable for different use cases:

  • Instant – represents a point in time (timestamp)
  • LocalDate – represents a date (year, month, day)
  • LocalDateTime – same as LocalDate, but includes time with nanosecond precision
  • OffsetDateTime – same as LocalDateTime, but with time zone offset
  • LocalTime – time with nanosecond precision and without date information
  • ZonedDateTime – same as OffsetDateTime, but includes a time zone ID
  • OffsetLocalTime – same as LocalTime, but with time zone offset
  • MonthDay – month and day, without year or time
  • YearMonth – month and year, without day or time
  • Duration – amount of time represented in seconds, minutes and hours. Has nanosecond precision
  • Period – amount of time represented in days, months and years

1.3. Immutability and Thread-Safety

Another advantage is that all time representations in Java 8 Date Time API are immutable and thus thread-safe.

All mutating methods return a new copy instead of modifying state of the original object.

Old classes such as java.util.Date were not thread-safe and could introduce very subtle concurrency bugs.

1.4. Method Chaining

All mutating methods can be chained together, allowing to implement complex transformations in a single line of code.

ZonedDateTime nextFriday = LocalDateTime.now()
  .plusHours(1)
  .with(TemporalAdjusters.next(DayOfWeek.FRIDAY))
  .atZone(ZoneId.of("PST"));

2. Examples

The examples below will demonstrate how to perform common tasks with both old and new API.

Getting current time

// Old
Date now = new Date();

// New
ZonedDateTime now = ZonedDateTime.now();

Representing specific time

// Old
Date birthDay = new GregorianCalendar(1990, Calendar.DECEMBER, 15).getTime();

// New
LocalDate birthDay = LocalDate.of(1990, Month.DECEMBER, 15);

Extracting specific fields

// Old
int month = new GregorianCalendar().get(Calendar.MONTH);

// New
Month month = LocalDateTime.now().getMonth();

Adding and subtracting time

// Old
GregorianCalendar calendar = new GregorianCalendar();
calendar.add(Calendar.HOUR_OF_DAY, -5);
Date fiveHoursBefore = calendar.getTime();

// New
LocalDateTime fiveHoursBefore = LocalDateTime.now().minusHours(5);

Altering specific fields

// Old
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(Calendar.MONTH, Calendar.JUNE);
Date inJune = calendar.getTime();

// New
LocalDateTime inJune = LocalDateTime.now().withMonth(Month.JUNE.getValue());

Truncating

Truncating resets all time fields smaller than the specified field. In the example below minutes and everything below will be set to zero

// Old
Calendar now = Calendar.getInstance();
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
Date truncated = now.getTime();

// New
LocalTime truncated = LocalTime.now().truncatedTo(ChronoUnit.HOURS);

Time zone conversion

// Old
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("CET"));
Date centralEastern = calendar.getTime();

// New
ZonedDateTime centralEastern = LocalDateTime.now().atZone(ZoneId.of("CET"));

Getting time span between two points in time

// Old
GregorianCalendar calendar = new GregorianCalendar();
Date now = new Date();
calendar.add(Calendar.HOUR, 1);
Date hourLater = calendar.getTime();
long elapsed = hourLater.getTime() - now.getTime();

// New
LocalDateTime now = LocalDateTime.now();
LocalDateTime hourLater = LocalDateTime.now().plusHours(1);
Duration span = Duration.between(now, hourLater);

Time formatting and parsing

DateTimeFormatter is a replacement for the old SimpleDateFormat that is thread-safe and provides additional functionality.

// Old
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date now = new Date();
String formattedDate = dateFormat.format(now);
Date parsedDate = dateFormat.parse(formattedDate);

// New
LocalDate now = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = now.format(formatter);
LocalDate parsedDate = LocalDate.parse(formattedDate, formatter);

Number of days in a month

// Old
Calendar calendar = new GregorianCalendar(1990, Calendar.FEBRUARY, 20);
int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

// New
int daysInMonth = YearMonth.of(1990, 2).lengthOfMonth();

3. Interacting with Legacy Code

In many cases a user might need to ensure interoperability with third-party libraries that rely on the old date library.

In Java 8 old date library classes have been extended with methods that convert them to corresponding objects from new Date API.
New classes provide similar functionalities.

Instant instantFromCalendar = GregorianCalendar.getInstance().toInstant();
ZonedDateTime zonedDateTimeFromCalendar = new GregorianCalendar().toZonedDateTime();
Date dateFromInstant = Date.from(Instant.now());
GregorianCalendar calendarFromZonedDateTime = GregorianCalendar.from(ZonedDateTime.now());
Instant instantFromDate = new Date().toInstant();
ZoneId zoneIdFromTimeZone = TimeZone.getTimeZone("PST").toZoneId();

4. Conclusion

In this article we explored the new Date Time API available in Java 8. We took a look at its advantages, compared to the deprecated API and pointed out differences using multiple examples.

Note that we barely scratched surface of the capabilities of the new Date Time API. Make sure to read through the official documentation to discover full range of tools offered by the new API.

Code examples can be found in the GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Introduction to AssertJ

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this article we will be exploring AssertJ – an opensource community-driven library used for writing fluent and rich assertions in Java tests.

This article focuses on tools available in the basic AssertJ module called AssertJ-core.

2. Maven Dependencies

In order to use AssertJ, you need to include the following section in your pom.xml file:

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.4.1</version>
    <scope>test</scope>
</dependency>

This dependency covers only the basic Java assertions. If you want to use advanced assertions, you will need to add additional modules separately.

Note that for Java 7 and earlier you should use AssertJ core version 2.x.x.

Latest versions can be found here.

3. Introduction

AssertJ provides a set of classes and utility methods that allow us to write fluent and beautiful assertions easily for:

  • Standard Java
  • Java 8
  • Guava
  • Joda Time
  • Neo4J and
  • Swing components

A detailed list of all modules is available on project’s website.

Let’s start with a few examples, right from the AssertJ’s documentation:

assertThat(frodo)
  .isNotEqualTo(sauron)
  .isIn(fellowshipOfTheRing);

assertThat(frodo.getName())
  .startsWith("Fro")
  .endsWith("do")
  .isEqualToIgnoringCase("frodo");

assertThat(fellowshipOfTheRing)
  .hasSize(9)
  .contains(frodo, sam)
  .doesNotContain(sauron);

The above examples are only the tip of the iceberg, but gives us an overview of how writing assertions with this library might look like.

 4. AssertJ in Action

In this section we’ll focus on setting up AssertJ and exploring its possibilities.

4.1. Getting Started

With the jar of the library on a classpath, enabling assertions is as easy as adding a single static import to your test class:

import static org.assertj.core.api.Assertions.*;

4.2. Writing Assertions

In order to write an assertion, you always need to start by passing your object to the Assertions.assertThat() method and then you follow with the actual assertions.

It’s important to remember that unlike some other libraries, the code below does not actually assert anything yet and will never fail a test:

assertThat(anyRefenceOrValue);

If you leverage your IDE’s code completion features, writing AssertJ assertions becomes incredibly easy due to its very descriptive methods. This is how it looks like in IntelliJ IDEA 16:

IDE's code completion features

IDE’s code completion features

 

As you can see, you have dozens of contextual methods to choose from and those are available only for String type. Let’s explore in detail some of this API and look at some specific assertions.

4.3. Object Assertions

Objects can be compared in various ways either to determine equality of two objects or to examine the fields of an object.

Let’s look at two ways that we can compare the equality of two objects. Given the following two Dog objects fido and fidosClone:

public class Dog { 
    private String name; 
    private Float weight;
    
    // standard getters and setters
}

Dog fido = new Dog("Fido", 5.25);

Dog fidosClone = new Dog("Fido", 5.25);

We can compare equality with the following assertion:

assertThat(fido).isEqualTo(fidosClone);

This will fail as isEqualTo() compares object references. If we want to compare their content instead, we can use isEqualToComparingFieldByFieldRecursively() like so:

assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

Fido and fidosClone are equal when doing a recursive field by field comparison because each field of one object is compared to the field in the other object.

There are many other assertion methods that provide different ways to compare and contract objects and to examine and assert on their fields. In order to discover them all, refer to the official AbstractObjectAssert documentation.

4.4. Boolean Assertions

Some simple methods exist for truth testing:

  • isTrue()
  • isFalse()

Let’s see them in action:

assertThat("".isEmpty()).isTrue();

4.5. Iterable/Array Assertions

For an Iterable or an Array there are multiple ways of asserting that their content exist. One of the most common assertions would be to check if an Iterable or Array contains a given element:

List<String> list = Arrays.asList("1", "2", "3");

assertThat(list).contains("1");

or if a List is not empty:

assertThat(list).isNotEmpty();

or if a List starts with a given character. For example “1”:

assertThat(list).startsWith("1");

Keep in mind that if you want to create more than one assertion for the same object, you can join them together easily.

Here is an example of an assertion that checks if a provided list is not empty, contains “1” element, does not contains any nulls and contains sequence of elements “2”, “3”:

assertThat(list)
  .isNotEmpty()
  .contains("1")
  .doesNotContainNull()
  .containsSequence("2", "3");

Of course many more possible assertions exist for those types. In order to discover them all, refer to the official AbstractIterableAssert documentation.

4.6. Character Assertions

Assertions for character types mostly involve comparisons and even checking if a given character is from a Unicode table.

Here is an example of an assertions that checks if a provided character is not ‘a’, is in Unicode table, is greater than ‘b’ and is lowercase:

assertThat(someCharacter)
  .isNotEqualTo('a')
  .inUnicode()
  .isGreaterThanOrEqualTo('b')
  .isLowerCase();

For a detailed list of all character types’ assertions, see AbstractCharacterAssert documentation.

4.7. Class Assertions

Assertions for Class type are mostly about checking its fields, Class types, presence of annotations and class finality.

If you want to assert that class Runnable is an interface, you need to simply write:

assertThat(Runnable.class).isInterface();

or if you want to check if one class is assignable from the other:

assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

All possible Class assertions can be viewed in the AbstractClassAssert documentation.

4.8. File Assertions

File assertions are all about checking if a given File instance exists, is a directory or a file, has certain content, is readable, or has given extension.

Here you can see an example of an assertion that checks if a given file exists, is file and not a directory, can be readable and writable:

 assertThat(someFile)
   .exists()
   .isFile()
   .canRead()
   .canWrite();

All possible Class assertions can be viewed in the AbstractFileAssert documentation.

4.9. Double/Float/Integer Assertions

Double/Float/Integer and Other Number Types

Numeric assertions are all about comparing numeric values within or without a given offset. For example, if you want to check if two values are equal according to a given precision we can do the following:

assertThat(5.1).isEqualTo(5, withPrecision(1d));

Notice that we are using already imported withPrecision(Double offset) helper method for generating Offset objects.

For more assertions, visit AbstractDoubleAssert documentation.

4.10. InputStream Assertions

There is only one InputStream-specific assertion available:

  • hasSameContentAs(InputStream expected)

and in action:

assertThat(given).hasSameContentAs(expected);

4.11. Map Assertions

Map assertions allow you to check if a map contains certain entry, set of entries, or keys/values separately.

And here you can see an example of an assertions that checks if a given map is not empty, contains numeric key “2”, does not contain numeric key “10” and contains entry: key: 2, value: “a”:

assertThat(map)
  .isNotEmpty()
  .containsKey(2)
  .doesNotContainKeys(10)
  .contains(entry(2, "a"));

For more assertions, see AbstractMapAssert documentation.

4.12. Throwable Assertions

Throwable assertions allow for example: inspecting exception’s messages, stacktraces, cause checking or verifying if an exception has been thrown already.

Let’s have a look at the example of an assertion that checks if a given exception was thrown and has a message ending with “c”:

assertThat(ex).hasNoCause().hasMessageEndingWith("c");

For more assertions, see AbstractThrowableAssert documentation.

5. Describing Assertions

In order to achieve even higher verbosity level, you can create dynamically generated custom descriptions for your assertions. The key to doing this is the as(String description, Object… args) method.

If you define your assertion like this:

assertThat(person.getAge())
  .as("%s's age should be equal to 100", person.getName())
  .isEqualTo(100);

this is what you will get when running tests:

[Alex's age should be equal to 100] expected:<100> but was:<34>

6. Java 8

AssertJ takes full advantage of Java 8’s functional programming features. Let’s dive into an example and see it in action. First let’s see how we do it in Java 7:

assertThat(fellowshipOfTheRing)
  .filteredOn("race", HOBBIT)
  .containsOnly(sam, frodo, pippin, merry);

Here we are filtering a collection on the race Hobbit and in Java 8 we can do something like this:

assertThat(fellowshipOfTheRing)
  .filteredOn(character -> character.getRace().equals(HOBBIT))
  .containsOnly(sam, frodo, pippin, merry);

We will be exploring AssertJ’s Java8 capabilities in a future article from this series. The above examples were taken from AssertJ’s website.

7. Conclusion

In this article we briefly explored the possibilities that AssertJ gives us along with the most popular assertions for core Java types.

The implementation of all the examples and code snippets can be found in a GitHub project.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Spring MVC and the @ModelAttribute Annotation

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

One of the most important Spring-MVC annotations is the @ModelAttribute annotation.

The @ModelAttribute is an annotation that binds a method parameter or method return value to a named model attribute and then exposes it to a web view.

In the following example, we will demonstrate the usability and functionality of the annotation, through a common concept: a form submitted from a company’s employee.

2. The @ModelAttribute in Depth

As the introductory paragraph revealed, @ModelAttribute can be used either as a method parameter or at the method level.

2.1 At the Method Level

When the annotation is used at the method level it indicates the purpose of that method is to add one or more model attributes. Such methods support the same argument types as @RequestMapping methods but that cannot be mapped directly to requests.

Let’s have a look at a quick example here to start understanding how this works:

@ModelAttribute
public void addAttributes(Model model) {
    model.addAttribute("msg", "Welcome to the Netherlands!");
}

In the example, we show a method that adds an attribute named msg to all models defined in the controller class.

Of course we’ll see this in action later on in the article.

In general, Spring-MVC will always make a call first to that method, before it calls any request handler methods. That is, @ModelAttribute methods are invoked before the controller methods annotated with @RequestMapping are invoked. The logic behind the sequence is that, the model object has to be created before any processing starts inside the controller methods.

It is also important that you annotate the respective class as @ControllerAdvice. Thus, you can add values in Model which will be identified as global. This actually means that for every request a default value exists, for every method in the response part.

2.2 As a Method Argument

When used as a method argument, it indicates the argument should be retrieved from the model. When not present, it should be first instantiated and then added to the model and once present in the model, the arguments fields should be populated from all request parameters that have matching names.

In the code snippet that follows the employee model attribute is populated with data from a form submitted to the addEmployee endpoint. Spring MVC does this behind the scenes before invoking the submit method:

@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public String submit(@ModelAttribute("employee") Employee employee) {
    // Code that uses the employee object

    return "employeeView";
}

Later on in this article we will see a complete example of how to use the employee object to populate the employeeView template.

So, it binds the form data with a bean. The controller annotated with @RequestMapping can have custom class argument(s) annotated with @ModelAttribute.

This is what is commonly know as data binding in Spring-MVC, a common mechanism that saves you from having to parse each form field individually.

3. Form Example

In this section we will provide the example referred to in the overview section: a very basic form that prompts a user (employee of a company, in our specific example), to enter some personal information (specifically name and id). After the submission is completed and without any errors, the user expects to see the previously submitted data, displayed on another screen.

3.1 The View

Let’s first create a simple form with id and name fields:

<form:form method="POST" action="/spring-mvc-java/addEmployee" 
  modelAttribute="employee">
    <form:label path="name">Name</form:label>
    <form:input path="name" />
		
    <form:label path="id">Id</form:label>
    <form:input path="id" />
		
    <input type="submit" value="Submit" />
</form:form>

3.2 The Controller

Here is the controller class, where the logic for the afore-mentioned view is being implemented:

@Controller
@ControllerAdvice
public class EmployeeController {

    private Map<Long, Employee> employeeMap = new HashMap<>();

    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public String submit(
      @ModelAttribute("employee") Employee employee,
      BindingResult result, ModelMap model) {
        if (result.hasErrors()) {
            return "error";
        }
        model.addAttribute("name", employee.getName());
        model.addAttribute("id", employee.getId());

        employeeMap.put(employee.getId(), employee);

        return "employeeView";
    }

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("msg", "Welcome to the Netherlands!");
    }
}

In the submit() method we have an Employee object bound to our View. Can you see the power of this annotation? You can map your form fields to an object model as simply as that. In the method we are fetching values from the form and setting them to ModelMap.

In the end we return employeeView, which means that the respective JSP file is going to be called as a View representative.

Furthermore, there is also an addAttributes() method. It’s purpose is to add values in the Model which will be identified globally. That is, a default value will be returned as a response for every request to every controller method. We also have to annotate the specific class as @ControllerAdvice.

3.3 The Model

As mentioned before, the Model object is very simplistic and contains all that is required by the “front-end” attributes. Now, let’s have a look at an example:

@XmlRootElement
public class Employee {

    private long id;
    private String name;

    public Employee(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // standard getters and setters removed
}

3.4 Wrap Up

The @ControllerAdvice assists a controller and in particular, @ModelAttribute methods that apply to all @RequestMapping methods. Of course, our addAttributes() method will be the very first to run, prior to the rest of the @RequestMapping methods.

Keeping that in mind and after both of submit() and addAttributes() are run, we could just refer to them in the View returned from the Controller class, by mentioning their given name inside a dollarised curly-braces duo, like for example ${name}.

3.5 Results View

Let’s now print what we received from the form:

<h3>${msg}</h3>
Name : ${name}
ID : ${id}

4. Conclusion

In this tutorial we investigated the usage of @ModelAttribute annotation, for both method arguments and method level usage cases.

The implementation of this simple tutorial can be found in the github project – this is an Maven based project, so it should be easy to import and run as it is.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

XML Libraries Support in Java

$
0
0

1. Introduction

In this article we will be comparing Java XML libraries and APIs.

This is the second article from the series about Java support for XML, if you want to go deeper into the XPath support in Java have a look at the previous article.

2. Overview

Now we’re going to dig deeper into the XML world support and for that we’re going to start by explaining as simple as possible all the subject-related initials.

In Java XML support we can find few API definitions, each one has its pros and cons.

SAX: It is an event based parsing API, it provides a low level access, is memory efficient and faster than DOM since it doesn’t load the whole document tree in memory but it doesn’t provide support for navigation like the one provided by XPath, although it is more efficient it is harder to use too.

DOM: It as model based parser that loads a tree structure document in memory, so we have the original elements order, we can navigate our document both directions, it provides an API for reading and writing, it offers XML manipulation and it is very easy to use although the price is high strain on memory resources.

StAX: It offers the ease of DOM and the efficiency of SAX but it lacks of some functionality provided by DOM like XML manipulation and it only allows us to navigate the document forward.

JAXB: It allows us to navigate the document both directions, it is more efficient than DOM, it allows conversion from XML to java types and it supports XML manipulation but it can only parse a valid XML document.

You could still find some references to JAXP but last release of this project is from March 2013 and it is practically dead.

XML Apis Table

XML APIs Table

3. The XML

In this section we are going to see the most popular implementations, so that we can test real working samples and check differences between them.

In the following examples we will be working with a simple XML file with a structure like this:

<tutorials>
    <tutorial tutId="01" type="java">
        <title>Guava</title>
        <description>Introduction to Guava</description>
        <date>04/04/2016</date>
        <author>GuavaAuthor</author>
    </tutorial>
    ...
</tutorials>

4. DOM4J

We’re going to start by taking a look at what we can do with DOM4J and for this example we need to add the last version of this dependency.

This is one of the most popular libraries to work with XML files, since it allows us to perform bi-directional reading, create new documents and update existing ones.

DOM4J can work with DOM, SAX, XPath and XLST. SAX is supported via JAXP.

Let’s take a look here for example, how can we select an element filtering by a given id.

SAXReader reader = new SAXReader();
Document document = reader.read(file);
List<Node> elements = document.selectNodes("//*[@tutId='" + id + "']");
return elements.get(0);

The SAXReader class is responsible for creating a DOM4J tree from SAX parsing events. Once we have a org.dom4j.Document we just need to call the necessary method and pass to it the XPath expression as a String.

We can load an existing document, make changes to its content and then update the original file.

for (Node node : nodes) {
    Element element = (Element)node;
    Iterator<Element> iterator = element.elementIterator("title");
    while (iterator.hasNext()) {
        Element title =(Element)iterator.next();
        title.setText(title.getText() + " updated");
    }
}
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_updated.xml")));
writer.write(document);
writer.close();

In the example above, we are changing every title’s content and create a new file.

Notice here how simple it is to get every title’s node in a list by calling elementIterator and passing the name of the node.

Once we have our content modified, we will use the XMLWriter that takes a DOM4J tree and formats it to a stream as XML.

Creating a new document from the scratch is as simple as we see below.

Document document = DocumentHelper.createDocument();
Element root = document.addElement("XMLTutorials");
Element tutorialElement = root.addElement("tutorial").addAttribute("tutId", "01");
tutorialElement.addAttribute("type", "xml");
tutorialElement.addElement("title").addText("XML with Dom4J");
...
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_new.xml")), format);
writer.write(document);
writer.close();

DocumentHelper gives us a collection of methods to use by DOM4J, such as createDocument that creates an empty document to start working with it.

We can create as many attributes or elements as we need with the methods provided by DOM4J, and once we have our document completed we just write it to a file as we did with the update case before.

5. JDOM

In order to work with with JDOM, we have to add this dependency to our pom.

JDOM’s working style is pretty similar to DOM4J’s, so we are going to take a look at just a couple of examples:

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(this.getFile());
Element tutorials = doc.getRootElement();
List<Element> titles = tutorials.getChildren("tutorial");

In the example above, we are retrieving all elements from the root element in a very simple way as we can do with DOM4J:

SAXBuilder builder = new SAXBuilder();
Document document = (Document) builder.build(file);
String filter = "//*[@tutId='" + id + "']";
XPathFactory xFactory = XPathFactory.instance();
XPathExpression<Element> expr = xFactory.compile(filter, Filters.element());
List<Element> node = expr.evaluate(document);

Again, here in the code above, we have a SAXBuilder creating a Document instance from a given file. We are retrieving an element by its tutId attribute by passing an XPath expression to the XPathFactory provided by JDOM2.

6. StAX

Now, we are going to see how we could retrieve all elements from our root element using the Stax API. Stax is included in the JDK since Java 6 so you don’t need to add any dependencies.

Firstly, we need to create a Tutorial class:

public class Tutorial {
    private String tutId;
    private String type;
    private String title;
    private String description;
    private String date;
    private String author;
    
    // standard getters and setters
}

and then we are ready to follow with:

List<Tutorial> tutorials = new ArrayList<>();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(this.getFile()));
Tutorial current;
while (eventReader.hasNext()) {
    XMLEvent event = eventReader.nextEvent();
    switch (event.getEventType()) {
        case XMLStreamConstants.START_ELEMENT:
            StartElement startElement = event.asStartElement();
            String qName = startElement.getName().getLocalPart();
            ...
            break;
        case XMLStreamConstants.CHARACTERS:
            Characters characters = event.asCharacters();
            ...
            break;
        case XMLStreamConstants.END_ELEMENT:
            EndElement endElement = event.asEndElement();
            
            // check if we found the closing element
            // close resources that need to be explicitly closed
            break;
    }
}

In the example above, in order to help us retrieve the information, we needed to create a class to store the retrieved data in.

To read the document, we declared what is called event handlers and we used them to navigate our document ahead. Remember that the SAX implementations don’t provide bi-directional navigation. As you can see here, a lot of work needs to be done just to retrieve a simple list of elements.

7. JAXB

JAXB is included with the JDK, so initially we could think that we don’t need to add any dependency to our project, but this is not completely true, since JAXB needs XercesImpl to work correctly, so we should add this dependency to make it work.

It’s very simple to load, create and manipulate information from an XML file using JAXB.

We just need to create the correct java entities to bind the XML and that’s it.

JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Tutorials tutorials = (Tutorials) jaxbUnmarshaller.unmarshal(this.getFile());

In the example above, we load our XML file into our object and from there we can handle everything as a normal Java structure;

To create a new document, it is as simple as reading it but doing the reverse way, like done in the below code.

Firstly, we are going to modify our Tutorial class to add JAXB annotations to getters and setters:

public class Tutorial {
    ...
    
    public String getTutId() {
        return tutId;
    }
	
    @XmlAttribute
    public void setTutId(String tutId) {
        this.tutId = tutId;
    }
    ...
    @XmlElement
    public void setTitle(String title) {
        this.title = title;
    }
    ...
}

@XmlRootElement
public class Tutorials {
    private List<Tutorial> tutorial;

    // standard getters and setters with @XmlElement annotation
}

With @XmlRootElement we define what object is going to represent the root node of our document and then we use @XmlAttribute or @XmlElement to define whether that attribute represents an attribute of a node or an element of the document.

Then we can follow with:

Tutorials tutorials = new Tutorials();
tutorials.setTutorial(new ArrayList<>());
Tutorial tut = new Tutorial();
tut.setTutId("01");
...
tutorials.getTutorial().add(tut);
JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(tutorials, file);

As you can see, binding XML file to Java objects is the easiest way to work this kind of files.

8. XPath Expression Support

To create complex XPath expressions, we can use Jaxen. This is an open source XPath library adaptable to many different object models, including DOM, XOM, DOM4J, and JDOM.

We can create XPath expressions and compile them against many supported documents.

String expression = "/tutorials/tutorial";
XPath path = new DOMXPath(expression);
List result = path.selectNodes(xmlDocument);

To make it work we’ll need to add this dependency to our project.

9. Conclusion

As you can see there are many options for working with XML, depending on the requirements of your application, you could work with any of them or you may have to choose between efficiency and simplicity.

You can find the full working samples for this article in our git repository here.

Keep Track of Logged In Users with Spring Security

$
0
0

I just released the Starter Class of "Learn Spring Security":

>> CHECK OUT THE COURSE

1. Overview

In this quick tutorial, we’re going to show an example of how we can track the currently logged in users in an application using Spring Security.

For this purpose, we’re going to keep track of a list of logged in users by adding the user when they log in and removing them when they log out.

We’ll leverage the HttpSessionBindingListener to update the list of logged in users whenever user information is added to the session or removed from the session based on user logs into the system or logs out from the system.

2. Active User Store

For simplicity, we will define a class that acts as an in memory store for the logged in users:

public class ActiveUserStore {

    public List<String> users;

    public ActiveUserStore() {
        users = new ArrayList<String>();
    }

    // standard getter and setter
}

We’ll define this as a standard bean in the Spring context:

@Bean
public ActiveUserStore activeUserStore(){
    return new ActiveUserStore();
}

3. The HTTPSessionBindingListener

Now, we’re going to make use of the HTTPSessionBindingListener interface and create a wrapper class to represent a user that is currently logged in.

This will basically listen to events of type HttpSessionBindingEvent, which are triggered whenever a value is set or removed, or, in other words, bound or unbound, to the HTTP session:

@Component
public class LoggedUser implements HttpSessionBindingListener {

    private String username; 
    private ActiveUserStore activeUserStore;
    
    public LoggedUser(String username, ActiveUserStore activeUserStore) {
        this.username = username;
        this.activeUserStore = activeUserStore;
    }
    
    public LoggedUser() {}

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        List<String> users = activeUserStore.getUsers();
        LoggedUser user = (LoggedUser) event.getValue();
        if (!users.contains(user.getUsername())) {
            users.add(user.getUsername());
        }
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        List<String> users = activeUserStore.getUsers();
        LoggedUser user = (LoggedUser) event.getValue();
        if (users.contains(user.getUsername())) {
            users.remove(user.getUsername());
        }
    }

    // standard getter and setter
}

The listener has two methods that need to be implemented, valueBound() and valueUnbound() for the two types of actions that trigger the event it is listening for. Whenever a value of the type that implements the listener is set or removed from the session, or the session is invalidated, these two methods will be invoked.

In our case, the valueBound() method will be called when the user logs in and the valueUnbound() method will be called when the user logs out or when the session expires.

In each of the methods we retrieve the value associated with the event, then add or remove the username from our list of logged in users, depending on whether the value was bound or unbound from the session.

4. Tracking Login and Logout

Now we need to keep track of when the user is successfully logged in or logged out so that we can add or remove active user from the session. In a Spring Security application, this can be achieved by implementing the AuthenticationSuccessHandler and LogoutSuccessHandler interfaces.

4.1. Implementing AuthenticationSuccessHandler

For the login action, we will set the username of the user logging in as an attribute on the session by overriding the onAuthenticationSuccess() method which provides us access to the session and authentication objects:

@Component("myAuthenticationSuccessHandler")
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    ActiveUserStore activeUserStore;
    
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication) 
      throws IOException {
        HttpSession session = request.getSession(false);
        if (session != null) {
            LoggedUser user = new LoggedUser(authentication.getName(), activeUserStore);
            session.setAttribute("user", user);
        }
    }
}

4.2. Implementing LogoutSuccessHandler

For the logout action, we will remove the user attribute by override the onLogoutSuccess() method of the LogoutSuccessHandler interface:

@Component("myLogoutSuccessHandler")
public class MyLogoutSuccessHandler implements LogoutSuccessHandler{
    @Override
    public void onLogoutSuccess(HttpServletRequest request, 
      HttpServletResponse response, Authentication authentication)
      throws IOException, ServletException {
        HttpSession session = request.getSession();
        if (session != null){
            session.removeAttribute("user");
        }
    }
}

5. Controller and View

In order to see all the above in action, we will create a controller mapping for the url “/users” that will retrieve the list of users, add it as a model attribute and return the users.html view:

5.1. Controller

@Controller
public class UserController {
    
    @Autowired
    ActiveUserStore activeUserStore;

    @RequestMapping(value = "/loggedUsers", method = RequestMethod.GET)
    public String getLoggedUsers(Locale locale, Model model) {
        model.addAttribute("users", activeUserStore.getUsers());
        return "users";
    }
}

5.2. Users.html

<html>
<body>
    <h2>Currently logged in users</h2>
    <div th:each="user : ${users}">
        <p th:text="${user}">user</p>
    </div>
</body>
</html>

6. Conclusion

In this article, we have demonstrated how we can determine who the currently logged in users are in a Spring Security application.

The implementation of this tutorial can be found in the github project – this is an Maven based project, so it should be easy to import and run as it is.

Get the early-bird price (20% Off) of my upcoming "Learn Spring Security" Course:

>> CHECK OUT THE COURSE

Viewing all 3702 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>