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

Guide to Guava MinMaxPriorityQueue and EvictingQueue

$
0
0

1. Overview

In this article, we’ll be looking at the EvictingQueue, and MinMaxPriorityQueue constructs from the Guava library. The EvictingQueue is an implementation of the circular buffer concept. The MinMaxPriorityQueue gives us an access to its lowest and greatest element using the supplied Comparator.

2. EvictingQueue

Let’s start with construction – when constructing an instance of the queue, we need to supply the maximum queue size as an argument.

When we want to add a new item to the EvictingQueue, and the queue is full, it automatically evicts an element from its head.

When comparing to the standard queue behavior, adding an element to the full queue does not block but removes the head element and adds a new item to the tail.

We can imagine the EvictingQueue as a ring to which we are inserting elements in the append-only fashion. If there is an element on the position on which we want to add a new element, we just override the existing element at the given position.

Let’s construct an instance of the EvictingQueue with the maximum size of 10. Next, we will add 10 elements to it:

Queue<Integer> evictingQueue = EvictingQueue.create(10);

IntStream.range(0, 10)
  .forEach(evictingQueue::add);

assertThat(evictingQueue)
  .containsExactly(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

If we had the standard queue implementation, adding a new item to the full queue would block the producer.

That is not a case with the EvictingQueue implementation. Adding a new element to it will cause the head to be removed from it, and the new element will be added to the tail:

evictingQueue.add(100);

assertThat(evictingQueue)
  .containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 100);

By using the EvictingQueue as the circular buffer, we can create very efficient concurrent programs.

3. MinMaxPriorityQueue

The MinMaxPriorityQueue provides constant-time access to its least and greatest elements.

To get the least element, we need to call the peekFirst() method. To get the greatest element we can call the peekLast() method. Note that these do not remove elements from a queue, they only retrieve it.

The ordering of elements is done by the Comparator that needs to be passed to the constructor of this queue.

Let’s say that we have a CustomClass class that has a value field of the integer type:

class CustomClass {
    private Integer value;

    // standard constructor, getters and setters
}

Let’s create a MinMaxPriorityQueue that will be using the comparator on int types. Next, we will add 10 objects of the CustomClass type to the queue:

MinMaxPriorityQueue<CustomClass> queue = MinMaxPriorityQueue
  .orderedBy(Comparator.comparing(CustomClass::getValue))
  .maximumSize(10)
  .create();

IntStream
  .iterate(10, i -> i - 1)
  .limit(10)
  .forEach(i -> queue.add(new CustomClass(i)));

Due to the characteristics of the MinMaxPriorityQueue and passed Comparator, the element at the head of the queue will be equal to 1 and the element at the tail of the queue will be equal to 10:

assertThat(
  queue.peekFirst().getValue()).isEqualTo(1);
assertThat(
  queue.peekLast().getValue()).isEqualTo(10);

As the capacity of our queue is 10, and we added 10 elements, the queue is full. Adding a new element to it will cause the last element in the queue to be removed. Let’s add a CustomClass with the value equal to -1:

queue.add(new CustomClass(-1));

After that action, the last element in the queue will be deleted and the new item at the tail of it will be equal to 9. The new head will be -1 as this is the new least element according to the Comparator that we passed when constructed our queue:

assertThat(
  queue.peekFirst().getValue()).isEqualTo(-1);
assertThat(
  queue.peekLast().getValue()).isEqualTo(9);

According to the specification of the MinMaxPriorityQueue, in case the queue is full, adding an element that is greater than the currently greatest element will remove that same element – effectively ignoring it.

Let’s add a 100 number and test if that item is in the queue after that operation:

queue.add(new CustomClass(100));
assertThat(queue.peekFirst().getValue())
  .isEqualTo(-1);
assertThat(queue.peekLast().getValue())
  .isEqualTo(9);

As we see the first element in the queue is still equal to -1 and last is equal to 9. Therefore, adding an integer was ignored as it is greater that already greatest element in the queue.

4. Conclusion

In this article, we had a look at the EvictingQueue and MinMaxPriorityQueue construct from the Guava library.

We saw how to use the EvictingQueue as the circular buffer to implement very efficient programs.

We used the MinMaxPriorityQueue combined with the Comparator to have the constant-time access to its least and greatest element.

It is important to remember the characteristics of both presented queues, as adding a new element to them will override an element that is already in the queue. This is contrary to the standard queue implementations, where adding a new element to the full queue will block the producer thread or throw an exception.

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


Split a String in Java

$
0
0

1. Introduction

Splitting Strings is a very frequent operation; this quick tutorial is focused on some of the API we can use to do this simply in Java.

2. String.split()

Let’s start with the core library – the String class itself offers a split() method – which is very convenient and sufficient for most scenarios. It simply splits the given String based on the delimiter, returning an array of Strings.

Let us look at some examples. We’ll start with splitting by a comma:

String[] splitted = "peter,james,thomas".split(",");

Let’s split by a whitespace:

String[] splitted = "car jeep scooter".split(" ");

Let’s also split by a dot:

String[] splitted = "192.168.1.178".split("\\.")

Let’s now split by multiple characters – a comma, space, and hyphen through regex:

String[] splitted = "b a, e, l.d u, n g".split("\\s+|,\\s*|\\.\\s*"));

3. StringUtils.split()

Apache’s common lang package provides a StringUtils class – which contains a null safe split() method, that splits using whitespace as the default delimiter:

String[] splitted = StringUtils.split("car jeep scooter");

Furthermore, it ignores extra spaces:

String[] splitted = StringUtils.split("car jeep scooter");

4. Splitter.split()

Finally, there’s a nice Splitter fluent API in Guava as well:

Iterable<String> result = Splitter.on(',')
  .trimResults()
  .omitEmptyStrings()
  .split("car,jeep,, scooter");
 
List<String> resultList = Lists.newArrayList(result);

5. Conclusion

String.split() is generally enough. However, for more complex cases we can utilize Apache’s commons-lang based StringUtils class, or the clean and flexible Guava APIs.

And, as always, the code for the article is available over on GitHub.

Introduction to Java Serialization

$
0
0

1. Introduction

Serialization is the conversion of the state of an object into a byte stream; deserialization does the opposite. Stated differently, serialization is the conversion of a Java object into a static stream (sequence) of bytes which can then be saved to a database or transferred over a network.

2. Serialization and Deserialization

The serialization process is instance-independent, i.e. objects can be serialized on one platform and deserialized on another. Classes that are eligible for serialization need to implement a special marker interface Serializable.

Both ObjectInputStream and ObjectOutputStream are high level classes that extend java.io.InputStream and java.io.OutputStream respectively. ObjectOutputStream can write primitive types and graphs of objects to an OutputStream as a stream of bytes. These streams can subsequently be read using ObjectInputStream.

The most important method in ObjectOutputStream is:

public final void writeObject(Object o) throws IOException;

Which takes a serializable object and converts it into a sequence (stream) of bytes. Similarly, the most important method in ObjectInputStream is:

public final Object readObject() 
  throws IOException, ClassNotFoundException;

Which can read a stream of bytes and convert it back into a Java object. This can then be cast back to the original object.

Let’s illustrate serialization with a Person class. Note that static fields belong to a class (as opposed to an object) and are not serialized. Also, note that we can use the keyword transient to ignore class fields during serialization:

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    static String country = "ITALY";
    private int age;
    private String name;
    transient int height;

    // getters and setters
}

The test below shows an example of saving an object of type Person to a local file then read this value back in:

@Test 
public void whenSerializingAndDeserializing_ThenObjectIsTheSame() () 
  throws IOException, ClassNotFoundException { 
    Person person = new Person();
    person.setAge(20);
    person.setName("Joe");
    
    FileOutputStream fileOutputStream
      = new FileOutputStream("yourfile.txt");
    ObjectOutputStream objectOutputStream 
      = new ObjectOutputStream(fileOutputStream);
    objectOutputStream.writeObject(person);
    objectOutputStream.flush();
    objectOutputStream.close();
    
    FileInputStream fileInputStream
      = new FileInputStream("yourfile.txt");
    ObjectInputStream objectInputStream
      = new ObjectInputStream(fileInputStream);
    Person p2 = (Person) objectInputStream.readObject();
    objectInputStream.close(); 
 
    assertTrue(p2.getAge() == p.getAge());
    assertTrue(p2.getName().equals(p.getName()));
}

We used ObjectOutputStream for saving the state of this object to a file using FileOutputStream. The file “yourfile.txt” is created in the project directory. This file is then loaded using FileInputStream. ObjectInputStream picks this stream up and converts it into a new object called p2.

Finally, we test the state of the loaded object, and it matches the state of the original object.

Notice that the loaded object has to be explicitly cast to a Person type.

3. Java Serialization Caveats

There are some caveats which concern the serialization in Java.

3.1. Inheritance and Composition

When a class implements the java.io.Serializable interface, all its sub-classes are serializable as well. On the contrary, when an object has a reference to another object, these objects must implement the Serializable interface separately, or else a NotSerializableException will be thrown:

public class Person implements Serializable {
    private int age;
    private String name;
    private Address country; // must be serializable too
}

If one of the fields in a serializable object consists of an array of objects, then all these objects must be serializable as well, or else a NotSerializableException will be thrown.

3.2. Serial Version UID

The JVM associates a version (long) number with each serializable class. It is used to verify that the saved and loaded objects have the same attributes and thus are compatible on serialization.

This number can be generated automatically by most IDEs and is based on the class name, its attributes and associated access modifiers. Any changes result in a different number and can cause an InvalidClassException.

If a serializable class doesn’t declare a serialVersionUID, the JVM will generate one automatically at run-time. However, it is highly recommended that each class declares its serialVersionUID as the generated one is compiler dependent and thus may result in unexpected InvalidClassExceptions.

3.3. Custom Serialization in Java

Java specifies a default way in which objects can be serialized. Java classes can override this default behavior. Custom serialization can be particularly useful when trying to serialize an object that has some unserializable attributes. This can be done by providing two methods inside the class that we want to serialize:

private void writeObject(ObjectOutputStream out) throws IOException;

and

private void readObject(ObjectInputStream in) 
  throws IOException, ClassNotFoundException;

With these methods, we can serialize those unserializable attributes into other forms that can be serialized:

public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    private transient Address address;
    private Person person;

    // setters and getters

    private void writeObject(ObjectOutputStream oos) 
      throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(address.getHouseNumber());
    }

    private void readObject(ObjectInputStream ois) 
      throws ClassNotFoundException, IOException {
        ois.defaultReadObject();
        Integer houseNumber = (Integer) ois.readObject();
        Address a = new Address();
        a.setHouseNumber(houseNumber);
        this.setAddress(a);
    }
}
public class Address {
    private int houseNumber;

    // setters and getters
}

The following unit test tests this custom serialization:

@Test
public void whenCustomSerializingAndDeserializing_ThenObjectIsTheSame() 
  throws IOException, ClassNotFoundException {
    Person p = new Person();
    p.setAge(20);
    p.setName("Joe");

    Address a = new Address();
    a.setHouseNumber(1);

    Employee e = new Employee();
    e.setPerson(p);
    e.setAddress(a);

    FileOutputStream fileOutputStream
      = new FileOutputStream("yourfile2.txt");
    ObjectOutputStream objectOutputStream 
      = new ObjectOutputStream(fileOutputStream);
    objectOutputStream.writeObject(e);
    objectOutputStream.flush();
    objectOutputStream.close();

    FileInputStream fileInputStream 
      = new FileInputStream("yourfile2.txt");
    ObjectInputStream objectInputStream 
      = new ObjectInputStream(fileInputStream);
    Employee e2 = (Employee) objectInputStream.readObject();
    objectInputStream.close();

    assertTrue(
      e2.getPerson().getAge() == e.getPerson().getAge());
    assertTrue(
      e2.getAddress().getHouseNumber() == e.getAddress().getHouseNumber());
}

In this code, we see how to save some unserializable attributes by serializing Address with custom serialization. Note that we must mark the unserializable attributes as transient to avoid the NotSerializableException.

4. Conclusion

In this quick tutorial, we’ve reviewed Java serialization, discussed important things to keep in mind and have shown how to do custom serialization.

As always, the source code used in this tutorial is available over on GitHub.

Guide to Mathematical Operations with Guava

$
0
0

1. Overview

In this article, we will see some useful Mathematical Operations available in the Guava Library.

There are four maths utility classes available with Guava:

  1. IntMath – operation on int values
  2. LongMath – operations on long values
  3. BigIntegerMath – operations on BigIntegers
  4. DoubleMath – operations on double values

2. IntMath Utility

IntMath is used to perform mathematical operations on Integer values. We’ll go through the available method list explaining each of their behavior.

2.1. binomial(int n, int k)

This function calculates the binomial coefficient of n and k. It makes sure that the result is within the integer range. Otherwise, it gives the Integer.MAX_VALUE. The answer can be derived using the formula n/k(n-k):

@Test
public void whenBinomialOnTwoInt_shouldReturnResultIfUnderInt() {
    int result = IntMath.binomial(6, 3);
 
    assertEquals(20, result);
}

@Test
public void whenBinomialOnTwoInt_shouldReturnIntMaxIfOVerflowInt() {
    int result = IntMath.binomial(Integer.MAX_VALUE, 3);
 
    assertEquals(Integer.MAX_VALUE, result);
}

2.2. ceilingPowerOfTwo(int x)

This calculates the value of the smallest power of two which is greater than or equal to x. The result n is such that 2^(n-1) < x < 2 ^n:

@Test
public void whenCeilPowOfTwoInt_shouldReturnResult() {
  int result = IntMath.ceilingPowerOfTwo(20);
 
  assertEquals(32, result);
}

2.3. checkedAdd(int a, int b) and Others

This function calculates the sum of the two parameters. This one provides an additional check which Throws ArithmeticException if the result overflows:

@Test
public void whenAddTwoInt_shouldReturnTheSumIfNotOverflow() {
    int result = IntMath.checkedAdd(1, 2);
 
    assertEquals(3, result);
}

@Test(expected = ArithmeticException.class)
public void whenAddTwoInt_shouldThrowArithmeticExceptionIfOverflow() {
    IntMath.checkedAdd(Integer.MAX_VALUE, 100);
}

Guava has checked methods for three other operators which can overflow: checkedMultiplycheckedPow, and checkedSubtract.

2.4. divide(int p, int q, RoundingMode mode)

This is a simple divide but allows us to define a rounding mode:

@Test
public void whenDivideTwoInt_shouldReturnTheResultForCeilingRounding() {
    int result = IntMath.divide(10, 3, RoundingMode.CEILING);
 
    assertEquals(4, result);
}
    
@Test(expected = ArithmeticException.class)
public void whenDivideTwoInt_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
    IntMath.divide(10, 3, RoundingMode.UNNECESSARY);
}

2.5. factorial(int n)

Calculates the factorial value of n. i.e the product of the first n positive integers. Returns 1 if n = 0 and returns Integer.MAX_VALUE if the result does not fit in for int range. The result can be obtained by n x (n-1) x (n-2) x ….. x 2 x 1:

@Test
public void whenFactorialInt_shouldReturnTheResultIfInIntRange() {
    int result = IntMath.factorial(5);
 
    assertEquals(120, result);
}

@Test
public void whenFactorialInt_shouldReturnIntMaxIfNotInIntRange() {
    int result = IntMath.factorial(Integer.MAX_VALUE);
 
    assertEquals(Integer.MAX_VALUE, result);
}

2.6. floorPowerOfTwo(int x)

Returns the largest power of two, of which the results is less than or equal to x. The result n is such that 2^n < x < 2 ^(n+1):

@Test
public void whenFloorPowerOfInt_shouldReturnValue() {
    int result = IntMath.floorPowerOfTwo(30);
 
    assertEquals(16, result);
}

2.7. gcd(int a, int b)

This function gives us the greatest common divisor of a and b:

@Test
public void whenGcdOfTwoInt_shouldReturnValue() {
    int result = IntMath.gcd(30, 40);
    assertEquals(10, result);
}

2.8. isPowerOfTwo(int x)

Returns whether x is a power of two or not. Returns true if the value is a power of two and false otherwise:

@Test
public void givenIntOfPowerTwo_whenIsPowOfTwo_shouldReturnTrue() {
    boolean result = IntMath.isPowerOfTwo(16);
 
    assertTrue(result);
}

@Test
public void givenIntNotOfPowerTwo_whenIsPowOfTwo_shouldReturnFalse() {
    boolean result = IntMath.isPowerOfTwo(20);
 
    assertFalse(result);
}

2.9. isPrime(int n)

This function will tell us if the number passed is prime or not:

@Test
public void givenNonPrimeInt_whenIsPrime_shouldReturnFalse() {
    boolean result = IntMath.isPrime(20);
 
    assertFalse(result);
}

2.10. log10(int x, RoundingMode mode)

This API calculates the base-10 logarithm of the given number. The result is rounded using the provided rounding mode:

@Test
public void whenLog10Int_shouldReturnTheResultForCeilingRounding() {
    int result = IntMath.log10(30, RoundingMode.CEILING);
 
    assertEquals(2, result);
}

@Test(expected = ArithmeticException.class)
public void whenLog10Int_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
    IntMath.log10(30, RoundingMode.UNNECESSARY);
}

2.11. log2(int x, RoundingMode mode)

Returns the base-2 logarithm of the given number. The result is rounded using the provided rounding mode:

@Test
public void whenLog2Int_shouldReturnTheResultForCeilingRounding() {
    int result = IntMath.log2(30, RoundingMode.CEILING);
 
    assertEquals(5, result);
}

@Test(expected = ArithmeticException.class)
public void whenLog2Int_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
    IntMath.log2(30, RoundingMode.UNNECESSARY);
}

2.12. mean(int x, int y)

With this function we can calculate the mean of two values:

@Test
public void whenMeanTwoInt_shouldReturnTheResult() {
    int result = IntMath.mean(30, 20);
 
    assertEquals(25, result);
}

2.13. mod(int x, int m)

Returns the remainder of integer division of one number by the other:

@Test
public void whenModTwoInt_shouldReturnTheResult() {
    int result = IntMath.mod(30, 4);
    assertEquals(2, result);
}

2.14. pow(int b, int k)

Returns the value of b to the power of k:

@Test
public void whenPowTwoInt_shouldReturnTheResult() {
    int result = IntMath.pow(6, 4);
 
    assertEquals(1296, result);
}

2.15. saturatedAdd(int a, int b) and Others

A sum function with the benefit of controlling any overflows or underflows by returning the value Integer.MAX_VALUE or Integer.MIN_VALUE respectively when it occurs:

@Test:
public void whenSaturatedAddTwoInt_shouldReturnTheResult() {
    int result = IntMath.saturatedAdd(6, 4);
 
    assertEquals(10, result);
}

@Test
public void whenSaturatedAddTwoInt_shouldReturnIntMaxIfOverflow() {
    int result = IntMath.saturatedAdd(Integer.MAX_VALUE, 1000);
 
    assertEquals(Integer.MAX_VALUE, result);
}

There are three other saturated APIs: saturatedMultiplysaturatedPow and saturatedSubtract.

2.16. sqrt(int x, RoundingMode mode)

Returns the square root of the given number. The result is rounded using the provided rounding mode:

@Test
public void whenSqrtInt_shouldReturnTheResultForCeilingRounding() {
    int result = IntMath.sqrt(30, RoundingMode.CEILING);
 
    assertEquals(6, result);
}

@Test(expected = ArithmeticException.class)
public void whenSqrtInt_shouldThrowArithmeticExIfRoundNotDefinedButNeded() {
    IntMath.sqrt(30, RoundingMode.UNNECESSARY);
}

3. LongMath Utility

LongMath has utilities for Long values. Most operations are similar to the IntMath utility, with an exceptional few described here.

3.1. mod(long x, int m) and mod(long x, long m)

Returns the x mod m. The remainder of integer division of x by m:

@Test
public void whenModLongAndInt_shouldModThemAndReturnTheResult() {
    int result = LongMath.mod(30L, 4);
 
    assertEquals(2, result);
}
@Test
public void whenModTwoLongValues_shouldModThemAndReturnTheResult() {
    long result = LongMath.mod(30L, 4L);
 
    assertEquals(2L, result);
}

4. BigIntegerMath Utility

BigIntegerMath is used to perform mathematical operations on type BigInteger.

This utility has some methods similar to the IntMath.

5. DoubleMath Utility

DoubleMath utility is used to perform an operation on double values.

Similar to the BigInteger utility, the number of available operations is limited and share similarity with IntMath utility. We will list some exceptional functions available only to this utility class.

5.1. isMathematicalInteger(double x)

Returns whether x is a mathematical integer. It checks if the number can be represented as an integer without a data loss:

@Test
public void givenInt_whenMathematicalDouble_shouldReturnTrue() {
    boolean result = DoubleMath.isMathematicalInteger(5);
 
    assertTrue(result);
}

@Test
public void givenDouble_whenMathematicalInt_shouldReturnFalse() {
    boolean result = DoubleMath.isMathematicalInteger(5.2);
 
    assertFalse(result);
}

5.2. log2(double x)

Calculates the base-2 logarithm of x:

@Test
public void whenLog2Double_shouldReturnResult() {
    double result = DoubleMath.log2(4);
 
    assertEquals(2, result, 0);
}

6. Conclusion

In this quick tutorial, we explored some useful Guava maths utility functions.

As always, the source code can be found over on GitHub.

How to Remove the Last Character of a String?

$
0
0

1. Overview

In this quick article, we are going to check and discuss different techniques for removing the last character of a String.

2. Using String.substring() 

The easiest way is to use the built-in substring() method of the String class.

In order to remove the last character of a given String, we have to use two parameters: 0 as the starting index, and index of the penultimate character. We can achieve that by calling String‘s length() method and subtracting 1 from the result.

However, this method is not null-safe and if we use an empty string this is going to fail.

To overcome issues with null and empty strings, we can wrap the method in a helper class:

public static String removeLastChar(String s) {
    return (s == null || s.length() == 0)
      ? null 
      : (s.substring(0, s.length() - 1));
}

We can refactor the code and use Java 8:

public static String removeLastCharOptional(String s) {
    return Optional.ofNullable(s)
      .filter(str -> str.length() != 0)
      .map(str -> str.substring(0, str.length() - 1))
      .orElse(s);
    }

3. Using StringUtils.substring() 

Instead of reinventing the wheel, we can use StringUtils class from Apache Commons Lang3 library, that offers helpful String operations. One of them is a null-safe substring() method, which handles exceptions.

To include StringUtils we have to update our pom.xml file:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.0</version>
</dependency>

StringUtils.substring() requires three parameters: a given String, an index of the first character (in our case it will be 0 always) and index of the penultimate character. Again, we can simply use the length() method and subtract 1:

String TEST_STRING = "abcdef";

StringUtils.substring(TEST_STRING, 0, TEST_STRING.length() - 1);

Yet, this operation is not null-safe again. It will work with empty Strings fine though.

4. Using StringUtils.chop() 

StringUtils class provides the chop() method that works well with all edge scenarios: empty and null Strings.

It is very easy to use and requires only one parameter: the String. Its sole purpose is to remove the last character. Nothing more, nothing less:

StringUtils.chop(TEST_STRING);

5. Using Regular Expression

We can also remove the last character (or any number of characters) from a String by making good use of regular expressions.

For example, we can use the replaceAll() method of String class itself – which takes two parameters: regular expression and the replacement String:

TEST_STRING.replaceAll(".$", "");

Note that, because we’re calling a method on the String – the operation is, of course, not null-safe.

Also, replaceAll() and regex expression can be complex at first sight. You can read more about regex here, but to make the logic a bit more user-friendly, we can wrap it in a helper class:

public static String removeLastCharRegex(String s) {
    return (s == null) ? null : s.replaceAll(".$", "");
}

Note that if a String ends with a newline then the above method will fail as “.” in regex matches any character except for line terminators.

Finally, let’s re-write the implementation with Java 8:

public static String removeLastCharRegexOptional(String s) {
    return Optional.ofNullable(s)
      .map(str -> str.replaceAll(".$", ""))
      .orElse(s);
}

6. Conclusion

In this short article, we’ve discussed different ways of removing only the last character of a String – some manual, some ready out of the box.

And, if we need more flexibility and we need to remove more characters, we can the more advanced solution with regular expressions.

As always, the code used throughout the article can be found over on GitHub.

Difference Between “==” and “===” operators in Kotlin

$
0
0

1. Overview

In this article, we are going to talk about the difference between “==” and “===” operators in Kotlin.

In Kotlin, just like in Java, we have two different concepts of equality, Referential equality, and Structural equality.

2. Referential Equality

For referential equality, we use the === symbol which allows us to evaluate the reference of an object (if it’s pointing to the same object). This is an equivalent of “==” operator in Java.

Let’s say we have two integers defined:

val a = Integer(10)
val b = Integer(10)

and we check them both by doing a === b, which will return false because they’re two separate objects, each pointing to a different location in memory.

3. Structural Equality

Now for structural equality, we use the == symbol that evaluates if both values are the same (or equal). This is usually achieved by implementing equals() method in Java.

So, using the same Integers example, we just need to do a == b, and in this case, it will return true, since both variables have the same value.

4. Comparing Complex Objects

If we want to check equality on more complex objects, the symbols will behave the same. Let’s say we have a User, which has a list of hobbies:

data class User(val name: String, val age: Int, val hobbies: List<String>)

The === will check reference equality and by conveniently using a List<> we can take advantage that the == operator, which will check the object and the data contained on the list.

5. Arrays Equality

For Arrays, as of Kotlin 1.1, we can check structural equality by using the infix functions contentEquals and contentDeepEquals:

val hobbies = arrayOf("Hiking, Chess")
val hobbies2 = arrayOf("Hiking, Chess")

assertTrue(hobbies contentEquals hobbies2)

6. Conclusion

This quick tutorial, showcased the difference between referential and structural equality in Kotlin, through a very simple example.

As always, the implementation of all of these examples and snippets can be found over on GitHub.

Note that this is a Maven-based project so it should be easy to import and run as is.

Guide to Synchronized Keyword in Java

$
0
0

1. Overview

This quick article will be an intro to using the synchronized block in Java.

Simply put, in a multi-threaded environment, a race condition occurs when two or more threads attempt to update mutable shared data at the same time. Java offers a mechanism to avoid race conditions by synchronizing thread access to shared data. 

A piece of logic marked with synchronized becomes a synchronized block, allowing only one thread to execute at any given time.

2. Why Synchronization?

Let’s a consider a typical race condition where we calculate the sum and multiple threads execute the calculate()  method:

public class BaeldungSynchronizedMethods {

    private int sum = 0;

    public void calculate() {
        setSum(getSum() + 1);
    }

    // standard setters and getters
}

And let’s write a simple test:

@Test
public void givenMultiThread_whenNonSyncMethod() {
    ExecutorService service = Executors.newFixedThreadPool(3);
    SynchronizedMethods summation = new SynchronizedMethods();

    IntStream.range(0, 1000)
      .forEach(count -> service.submit(summation::calculate));
    service.shutdown();

    assertEquals(1000, summation.getSum());
}

We’re simply using an ExecutorService with a 3-threads pool to execute the calculate() 1000 times.

If we would execute this serially, the expected output would be 1000, but our multi-threaded execution fails almost every time with an inconsistent actual output e.g.:

java.lang.AssertionError: expected:<1000> but was:<965>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:834)
...

This result is of course not unexpected.

A simple way to avoid the race condition is to make the operation thread-safe by using the synchronized keyword.

3. The synchronized Keyword

The synchronized keyword can be used on different levels:

  • Instance methods
  • Static methods
  • Code blocks

When we use a synchronized block, internally Java uses a monitor also known as monitor lock or intrinsic lock, to provide synchronization. These monitors are bound to an object, thus all synchronized blocks of the same object can have only one thread executing them at the same time.

3.1. Synchronized Instance Methods

Simply add the synchronized keyword in the method declaration to make the method synchronized:

public synchronized void synchronisedCalculate() {
    setSum(getSum() + 1);
}

Notice that once we synchronize the method, the test case passes, with actual output as 1000:

@Test
public void givenMultiThread_whenMethodSync() {
    ExecutorService service = Executors.newFixedThreadPool(3);
    SynchronizedMethods method = new SynchronizedMethods();

    IntStream.range(0, 1000)
      .forEach(count -> service.submit(method::synchronisedCalculate));
    service.shutdown();

    assertEquals(1000, method.getSum());
}

Instance methods are synchronized over the instance of the class owning the method. Which means only one thread per instance of the class can execute this method.

3.2. Synchronized Static Methods

Static methods are synchronized just like instance methods:

 public static synchronized void syncStaticCalculate() {
     staticSum = staticSum + 1;
 }

These methods are synchronized on the Class object associated with the class and since only one Class object exists per JVM per class, only one thread can execute inside a static synchronized method per class, irrespective of the number of instances it has.

Let’s test it:

@Test
public void givenMultiThread_whenStaticSyncMethod() {
    ExecutorService service = Executors.newCachedThreadPool();

    IntStream.range(0, 1000)
      .forEach(count -> 
        service.submit(BaeldungSynchronizedMethods::syncStaticCalculate));
    service.awaitTermination(100, TimeUnit.MILLISECONDS);

    assertEquals(1000, BaeldungSynchronizedMethods.staticSum);
}

3.3. Synchronized Blocks within Methods

Sometimes we do not want to synchronize the entire method but only some instructions within it. This can be achieved by applying synchronized to a block:

public void performSynchrinisedTask() {
    synchronized (this) {
        setCount(getCount()+1);
    }
}

let us test the change:

@Test
public void givenMultiThread_whenBlockSync() {
    ExecutorService service = Executors.newFixedThreadPool(3);
    BaeldungSynchronizedBlocks synchronizedBlocks = new BaeldungSynchronizedBlocks();

    IntStream.range(0, 1000)
      .forEach(count -> 
        service.submit(synchronizedBlocks::performSynchronisedTask));
    service.awaitTermination(100, TimeUnit.MILLISECONDS);

    assertEquals(1000, synchronizedBlocks.getCount());
}

Notice, that we passed a parameter this to the synchronized block. This is the monitor object, the code inside the block get synchronized on the monitor object. Simply put, only one thread per monitor object can execute inside that block of code.

In case the method is static, we would pass class name in place of the object reference. And the class would be a monitor for synchronization of the block:

public static void performStaticSyncTask(){
    synchronized (SynchronisedBlocks.class) {
        setStaticCount(getStaticCount() + 1);
    }
}

Let’s test the block inside the static method:

@Test
public void givenMultiThread_whenStaticSyncBlock() {
    ExecutorService service = Executors.newCachedThreadPool();

    IntStream.range(0, 1000)
      .forEach(count -> 
        service.submit(BaeldungSynchronizedBlocks::performStaticSyncTask));
    service.awaitTermination(100, TimeUnit.MILLISECONDS);

    assertEquals(1000, BaeldungSynchronizedBlocks.getStaticCount());
}

5. Conclusion

In this quick article, we have seen different ways of using the synchronized keyword to achieve thread synchronization.

We also explored how a race condition can impact our application, and how synchronization helps us avoid that. For more about thread safety using locks in Java refer to our java.util.concurrent.Locks article.

The complete code for this tutorial is available over on GitHub.

Introduction to Drools

$
0
0

1. Overview

Drools is a Business Rule Management System (BRMS) solution. It provides a rule engine which processes facts and produces output as a result of rules and facts processing. Centralization of business logic makes it possible to introduce changes fast and cheap.

It also bridges the gap between the Business and Technical teams by providing a facility for writing the rules in a format which is easy to understand.

2. Maven Dependencies

To get started with Drools, we need to first add a couple of dependencies in our pom.xml:

<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-ci</artifactId>
    <version>7.1.0.Beta1</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>7.1.0.Beta1</version>
</dependency>

The latest version of both dependencies is available on Maven Central Repository as kie-ci and drools-decisiontables.

 3. Drools Basics

We are going to look at basic concepts of Drools:

  • Facts – represents data that serves as input for rules
  • Working Memory –  a storage with Facts, where they are used for pattern matching and can be modified, inserted and removed
  • Rule – represents a single rule which associates Facts with matching actions. It can be written in Drools Rule Language in the .drl files or as Decision Table in an excel spreadsheet
  • Knowledge Session – it holds all the resources required for firing rules; all Facts are inserted into session, and then matching rules are fired
  • Knowledge Base – represents the knowledge in the Drools ecosystem, it has the information about the resources where Rules are found, and also it creates the Knowledge Session
  • Module – A module holds multiple Knowledge Bases which can hold different sessions

4. Java Configuration 

To fire rules on a given data, we need to instantiate the framework provided classes with information about the location of rule files and the Facts:

4.1. KieFileSystem

First, we need to set the KieFileSystem bean; this is an in-memory file system provided by the framework. Following code provides the container to define the Drools resources like rules files, decision tables, programmatically:

public KieFileSystem kieFileSystem() throws IOException {
    KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
        for (Resource file : getRuleFiles()) {
            kieFileSystem.write(
              ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8"));
        }
        return kieFileSystem;
}

Here RULES_PATH denotes the location of rule files on the file system. Here we are reading the files from classpath which is typically /src/main/resources in case of a Maven project.

4.2. KieContainer

Next, we need to set the KieContainer which is a placeholder for all the KieBases for particular KieModule. KieContainer is built with the help of other beans including KieFileSystem, KieModule, and KieBuilder.

The buildAll() method invoked on KieBuilder builds all the resources and ties them to KieBase. It executes successfully only when it’s able to find and validate all of the rule files:

public KieContainer kieContainer() throws IOException {
    KieRepository kieRepository = getKieServices().getRepository();

    kieRepository.addKieModule(new KieModule() {
        public ReleaseId getReleaseId() {
            return kieRepository.getDefaultReleaseId();
        }
    });

    KieBuilder kieBuilder = getKieServices()
      .newKieBuilder(kieFileSystem())
      .buildAll();
    

    return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}

4.3. KieSession

The rules are fired by opening a KieSession bean – which can be retrieved from KieContainer:

public KieSession kieSession() throws IOException {
    return kieContainer().newKieSession();
}

5. Implementing Rules

Now that we’re done with the setup, let’s have a look at a couple of options for creating rules.

We’ll explore the rule implementation by an example of categorizing an applicant for a specific role, based on his current salary and number of years of experience he has.

5.1. Drools Rule File (.drl)

Simply put, the Drools rule file contains all business rules.

A rule includes a When-Then construct, here the When section lists the condition to be checked, and Then section lists the action to be taken if the condition is met:

package com.baeldung.drools.rules;

import com.baeldung.drools.model.Applicant;

global com.baeldung.drools.model.SuggestedRole suggestedRole;

dialect  "mvel"

rule "Suggest Manager Role"
    when
        Applicant(experienceInYears > 10)
        Applicant(currentSalary > 1000000 && currentSalary <= 
         2500000)
    then
        suggestedRole.setRole("Manager");
end

This rule can be fired by inserting the Applicant and SuggestedRole facts in KieSession:

public SuggestedRole suggestARoleForApplicant(
    Applicant applicant,SuggestedRole suggestedRole){
    KieSession kieSession = kieContainer.newKieSession();
    kieSession.insert(applicant);
    kieSession.setGlobal("suggestedRole",suggestedRole);
    kieSession.fireAllRules();
    // ...
}

It tests two conditions on Applicant instance and then based on the fulfillment of both conditions it sets the Role field in the SuggestedRole object.

This can be verified by executing the test:

@Test
public void whenCriteriaMatching_ThenSuggestManagerRole(){
    Applicant applicant = new Applicant("David", 37, 1600000.0,11);
    SuggestedRole suggestedRole = new SuggestedRole();
        
    applicantService.suggestARoleForApplicant(applicant, suggestedRole);
 
    assertEquals("Manager", suggestedRole.getRole());
}

In this example, we’ve used few Drools provided keywords. Let’s understand their use:

  • package – this is the package name we specify in the kmodule.xml, the rule file is located inside this package
  • import – this is similar to Java import statement, here we need to specify the classes which we are inserting in the KnowledgeSession
  • global – this is used to define a global level variable for a session; this can be used to pass input parameter or to get an output parameter to summarize the information for a session
  • dialect – a dialect specifies the syntax employed in the expressions in the condition section or action section. By default the dialect is Java. Drools also support dialect mvel; it is an expression language for Java-based applications. It supports the field and method/getter access
  • rule – this defines a rule block with a rule name
  • when – this specifies a rule condition, in this example the conditions which are checked are Applicant having experienceInYears more than ten years and currentSalary in a certain range
  • then – this block executes the action when the conditions in the when block met. In this example, the Applicant role is set as Manager

5.2. Decision Tables

A decision table provides the capability of defining rules in a pre-formatted Excel spreadsheet. The advantage with Drools provided Decision Table is that they are easy to understand even for a non-technical person.

Also, it is useful when there are similar rules, but with different values, in this case, it is easier to add a new row on excel sheet in contrast to writing a new rule in .drl files. Let’s see what the structure of a decision table with an example of applying the label on a product based on the product type:

The Decision Table is grouped in different sections the top one is like a header section where we specify the RuleSet (i.e. package where rule files are located), Import (Java classes to be imported) and Notes (comments about the purpose of rules).

The central section where we define rules is called RuleTable which groups the rules which are applied to the same domain object.

In the next row, we have column types CONDITION and ACTION. Within these columns, we can access the properties of the domain object mentioned in one row and their values in the subsequent rows.

The mechanism to fire the rules is similar to what we have seen with .drl files.

We can verify the outcome of applying these rules by executing the test:

@Test
public void whenProductTypeElectronic_ThenLabelBarcode() {
    Product product = new Product("Microwave", "Electronic");
    product = productService.applyLabelToProduct(product);
    
    assertEquals("BarCode", product.getLabel());
}

6. Conclusion

In this quick article, we have explored making use of Drools as a business rule engine in our application. We’ve also seen the multiple ways by which we can write the rules in the Drools rule language as well as in easy to understand the language in spreadsheets.

As always, the complete code for this article is available over on GitHub.


Java Web Weekly, Issue 177

$
0
0

Lots of interesting writeups on Java 9 this week.

Here we go…

1. Spring and Java

>> Is Jigsaw Dead? Not quite. [tomitribe.com]

A very needed clarification of the JCP process and what has actually happened to Jigsaw recently.

>> Ordering vs Sorting with Hibernate – What should you use? [thoughts-on-java.org]

One might think that ordering and sorting is the same operation but it turns out there are slight differences in Hibernate 🙂

>> Reactor Bismuth release train first milestone available [spring.io]

An important milestone for the Reactor project, with some very interesting new functionality.

Also worth reading:

Webinars and presentations:

Time to upgrade:

2. Technical and Musings

>> Why are you testing your software? [frankel.ch]

Sometimes it makes sense to take a step back and rethink if it’s absolutely necessary to achieve the coverage of 100%.

>> Event Logs [techblog.bozho.net]

Audit logs and event logs are definitely not the same thing. And, if you’re’ doing Event Sourcing, you may need some extra functionality to get a proper audit log out of the Event Store.

>> When Subclasses Are Ready To Die [thecodewhisperer.com]

Some back-to-basics and timeless design priciples here.

>> How Much Code Should My Developers Be Responsible For? [daedtech.com]

There is no universal answer to this question but it is a good idea to keep the “bus factor” concept in mind

Also worth reading:

3. Comics

And my favorite Dilberts of the week:

>> You can’t make an omelet without breaking some eggs [dilbert.com]

>> I’m an awesome leader, therefore I must be hilarious [dilbert.com]

>> Each engineer cost us one million dollars [dilbert.com]

4. Pick of the Week

This week I’ve been both super busy but also excited to finally launch the new Certification Classes in each of my 2 courses:

>> The new “Certification Class” in REST With Spring

>> The new “Certification Class” in Learn Spring Security

Software Transactional Memory in Java Using Multiverse

$
0
0

1. Overview

In this article, we’ll be looking at the Multiverse library – which helps us to implement the concept of Software Transactional Memory in Java.

Using constructs out of this library, we can create a synchronization mechanism on shared state – which is more elegant and readable solution than the standard implementation with the Java core library.

2. Maven Dependency

To get started we’ll need to add the multiverse-core library into our pom:

<dependency>
    <groupId>org.multiverse</groupId>
    <artifactId>multiverse-core</artifactId>
    <version>0.7.0</version>
</dependency>

3. Multiverse API

Let’s start with some of the basics.

Software Transactional Memory (STM) is a concept ported from the SQL database world – where each operation is executed within transactions that satisfy ACID (Atomicity, Consistency, Isolation, Durability) properties. Here, only Atomicity, Consistency and Isolation are satisfied because the mechanism runs in-memory.

The main interface in the Multiverse library is the TxnObject – each transactional object needs to implement it, and the library provides us with a number of specific subclasses we can use.

Each operation that needs to be placed within a critical section, accessible by only one thread and using any transactional object – needs to be wrapped within the StmUtils.atomic() method. A critical section is a place of a program that cannot be executed by more than one thread simultaneously, so access to it should be guarded by some synchronization mechanism.

If an action within a transaction succeeds, the transaction will be committed, and the new state will be accessible to other threads.  If some error occurs, the transaction will not be committed, and therefore the state will not change.

Finally, if two threads want to modify the same state within a transaction, only one will succeed and commit its changes. The next thread will be able to perform its action within its transaction.

4. Implementing Account Logic Using STM

Let’s now have a look at an example.

Let’s say that we want to create a bank account logic using STM provided by the Multiverse library. Our Account object will have the lastUpadate timestamp that is of a TxnLong type, and the balance field that stores current balance for a given account and is of the TxnInteger type.

The TxnLong and TxnInteger are classes from the Multiverse. They must be executed within a transaction. Otherwise, an exception will be thrown. We need to use the StmUtils to create new instances of the transactional objects:

public class Account {
    private TxnLong lastUpdate;
    private TxnInteger balance;

    public Account(int balance) {
        this.lastUpdate = StmUtils.newTxnLong(System.currentTimeMillis());
        this.balance = StmUtils.newTxnInteger(balance);
    }
}

Next, we’ll create the adjustBy() method – which will increment the balance by the given amount. That action needs to be executed within a transaction.

If any exception is thrown inside of it, the transaction will end without committing any change:

public void adjustBy(int amount) {
    adjustBy(amount, System.currentTimeMillis());
}

public void adjustBy(int amount, long date) {
    StmUtils.atomic(() -> {
        balance.increment(amount);
        lastUpdate.set(date);

        if (balance.get() <= 0) {
            throw new IllegalArgumentException("Not enough money");
        }
    });
}

If we want to get the current balance for the given account, we need to get the value from the balance field, but it also needs to be invoked with atomic semantics:

public Integer getBalance() {
    return balance.atomicGet();
}

5. Testing the Account 

Let’s test our Account logic. First, we want to decrement balance from the account by the given amount simply:

@Test
public void givenAccount_whenDecrement_thenShouldReturnProperValue() {
    Account a = new Account(10);
    a.adjustBy(-5);

    assertThat(a.getBalance()).isEqualTo(5);
}

Next, let’s say that we withdraw from the account making the balance negative. That action should throw an exception, and leave the account intact because the action was executed within a transaction and was not committed:

@Test(expected = IllegalArgumentException.class)
public void givenAccount_whenDecrementTooMuch_thenShouldThrow() {
    // given
    Account a = new Account(10);

    // when
    a.adjustBy(-11);
}

Let’s now test a concurrency problem that can arise when two threads want to decrement a balance at the same time.

If one thread wants to decrement it by 5 and the second one by 6, one of those two actions should fail because the current balance of the given account is equal to 10.

We’re going to submit two threads to the ExecutorService, and use the CountDownLatch to start them at the same time:

ExecutorService ex = Executors.newFixedThreadPool(2);
Account a = new Account(10);
CountDownLatch countDownLatch = new CountDownLatch(1);
AtomicBoolean exceptionThrown = new AtomicBoolean(false);

ex.submit(() -> {
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    try {
        a.adjustBy(-6);
    } catch (IllegalArgumentException e) {
        exceptionThrown.set(true);
    }
});
ex.submit(() -> {
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    try {
        a.adjustBy(-5);
    } catch (IllegalArgumentException e) {
        exceptionThrown.set(true);
    }
});

After staring both actions at the same time, one of them will throw an exception:

countDownLatch.countDown();
ex.awaitTermination(1, TimeUnit.SECONDS);
ex.shutdown();

assertTrue(exceptionThrown.get());

6. Transferring from One Account to Another

Let’s say that we want to transfer money from one account to the other. We can implement the transferTo() method on the Account class by passing the other Account to which we want to transfer the given amount of money:

public void transferTo(Account other, int amount) {
    StmUtils.atomic(() -> {
        long date = System.currentTimeMillis();
        adjustBy(-amount, date);
        other.adjustBy(amount, date);
    });
}

All logic is executed within a transaction. This will guarantee that when we want to transfer an amount that is higher than the balance on the given account, both accounts will be intact because the transaction will not commit.

Let’s test transferring logic:

Account a = new Account(10);
Account b = new Account(10);

a.transferTo(b, 5);

assertThat(a.getBalance()).isEqualTo(5);
assertThat(b.getBalance()).isEqualTo(15);

We simply create two accounts, we transfer the money from one to the other, and everything works as expected. Next, let’s say that we want to transfer more money than is available on the account. The transferTo() call will throw the IllegalArgumentException, and the changes will not be committed:

try {
    a.transferTo(b, 20);
} catch (IllegalArgumentException e) {
    System.out.println("failed to transfer money");
}

assertThat(a.getBalance()).isEqualTo(5);
assertThat(b.getBalance()).isEqualTo(15);

Note that the balance for both a and accounts is the same as before the call to the transferTo() method.

7. STM is Deadlock Safe

When we’re using the standard Java synchronization mechanism, our logic can be prone to deadlocks, with no way to recover from them.

The deadlock can occur when we want to transfer the money from account a to account b. In standard Java implementation, one thread needs to lock the account a, then account b. Let’s say that, in the meantime, the other thread wants to transfer the money from account b to account a. The other thread locks account b waiting for an account a to be unlocked.

Unfortunately, the lock for an account a is held by the first thread, and the lock for account b is held by the second thread. Such situation will cause our program to block indefinitely.

Fortunately, when implementing transferTo() logic using STM, we do not need to worry about deadlocks as the STM is Deadlock Safe. Let’s test that using our transferTo() method.

Let’s say that we have two threads. First thread wants to transfer some money from account a to account b, and the second thread wants to transfer some money from account b to account a. We need to create two accounts and start two threads that will execute the transferTo() method in the same time:

ExecutorService ex = Executors.newFixedThreadPool(2);
Account a = new Account(10);
Account b = new Account(10);
CountDownLatch countDownLatch = new CountDownLatch(1);

ex.submit(() -> {
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    a.transferTo(b, 10);
});
ex.submit(() -> {
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    b.transferTo(a, 1);

});

After starting processing, both accounts will have the proper balance field:

countDownLatch.countDown();
ex.awaitTermination(1, TimeUnit.SECONDS);
ex.shutdown();

assertThat(a.getBalance()).isEqualTo(1);
assertThat(b.getBalance()).isEqualTo(19);

8. Conclusion

In this tutorial, we had a look at the Multiverse library and at how we can use that to create lock-free and thread safe logic utilizing concepts in the Software Transactional Memory.

We tested the behavior of the implemented logic and saw that the logic that uses the STM is deadlock-free.

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

Introduction to HikariCP

$
0
0

1. Overview

In this introductory article, we’ll learn about the HikariCP JDBC connection pool project. This is a very lightweight (at roughly 130Kb) and lightning fast JDBC connection pooling framework developed by Brett Wooldridge around 2012.

2. Introduction

There are several benchmark results available to compare the performance of HikariCP with other connection pooling frameworks such as c3p0, dbcp2, tomcat, and vibur. For example, the HikariCP team published below benchmarks (original results available here):

The framework so is fast because the following techniques have been applied:

  • Bytecode-level engineering – some extreme bytecode level engineering (including assembly level native coding) has been done
  • Micro-optimizations – although barely measurable, these optimizations combined boost the overall performance
  • Intelligent use of the Collections framework – the ArrayList<Statement> was replaced with a custom class FastList that eliminates range checking and performs removal scans from tail to head

3. Maven Dependency

Let’s build a sample application to highlight its usage. HikariCP comes with the support for all the main versions of JVM. Each version requires its dependency; for Java 9 we have:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP-java9ea</artifactId>
    <version>2.6.1</version>
</dependency>

And for Java 8:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>2.6.1</version>
</dependency>

Older JDK versions like 6 and 7 are also supported. The appropriate versions can be found here and here. Also, we can check the latest versions in the Central Maven Repository.

4. Usage

Let’s now create a demo application. Please note that we need to include a suitable JDBC driver class dependency in the pom.xml. If no dependencies are provided, the application will throw a ClassNotFoundException.

4.1. Creating a DataSource

We will use HikariCP’s DataSource to create a single instance of a data source for our application:

public class DataSource {

    private static HikariConfig config = new HikariConfig();
    private static HikariDataSource ds;

    static {
        config.setJdbcUrl( "jdbc_url" );
        config.setUsername( "database_username" );
        config.setPassword( "database_password" );
        config.addDataSourceProperty( "cachePrepStmts" , "true" );
        config.addDataSourceProperty( "prepStmtCacheSize" , "250" );
        config.addDataSourceProperty( "prepStmtCacheSqlLimit" , "2048" );
        ds = new HikariDataSource( config );
    }

    private DataSource() {}

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }
}

Point to note here is the initialization in the static block.

HikariConfig is the configuration class used to initialize a data source. It comes with four well-known must-used parameters username, password, jdbcUrl, dataSourceClassName.

Out of jdbcUrl and dataSourceClassName, either one is to be used at a time. However, when using this property with older drivers, we may need to set both properties.

In addition to these properties, there are several other properties available that may not all be offered by other pooling frameworks:

  • autoCommit
  • connectionTimeout
  • idleTimeout
  • maxLifetime
  • connectionTestQuery
  • connectionInitSql
  • validationTimeout
  • maximumPoolSize
  • poolName
  • allowPoolSuspension
  • readOnly
  • transactionIsolation
  • leakDetectionThreshold

HikariCP stands out because of these database properties. It’s advanced enough to even detect connection leaks by itself!

A detailed description of these properties can be found here.

We can also initialize HikariConfig with a properties file placed in the resources directory:

private static HikariConfig config = new HikariConfig(
    "datasource.properties" );

The properties file should look something like this:

dataSourceClassName= //TBD
dataSource.user= //TBD
//other properties name should start with dataSource as shown above

We can use java.util.Properties-based configuration as well:

Properties props = new Properties();
props.setProperty( "dataSourceClassName" , //TBD );
props.setProperty( "dataSource.user" , //TBD );
//setter for other required properties
private static HikariConfig config = new HikariConfig( props );

Alternatively, we can initialize a data source directly:

ds.setJdbcUrl( //TBD  );
ds.setUsername( //TBD );
ds.setPassword( //TBD );

4.2. Using a Data Source

Now that we have defined the data source, we can use it to obtain a connection from the configured connection pool and perform JDBC related actions.

Suppose we have two table named dept and emp to simulate an employee-department use case. We will write a class to fetch those details from the database using HikariCP.

Below we list the SQL statements necessary to create the sample data:

create table dept(
  deptno numeric,
  dname  varchar(14),
  loc    varchar(13),
  constraint pk_dept primary key ( deptno )
);
 
create table emp(
  empno    numeric,
  ename    varchar(10),
  job      varchar(9),
  mgr      numeric,
  hiredate date,
  sal      numeric,
  comm     numeric,
  deptno   numeric,
  constraint pk_emp primary key ( empno ),
  constraint fk_deptno foreign key ( deptno ) references dept ( deptno )
);

insert into dept values( 10, 'ACCOUNTING', 'NEW YORK' );
insert into dept values( 20, 'RESEARCH', 'DALLAS' );
insert into dept values( 30, 'SALES', 'CHICAGO' );
insert into dept values( 40, 'OPERATIONS', 'BOSTON' );
 
insert into emp values(
 7839, 'KING', 'PRESIDENT', null,
 to_date( '17-11-1981' , 'dd-mm-yyyy' ),
 7698, null, 10
);
insert into emp values(
 7698, 'BLAKE', 'MANAGER', 7839,
 to_date( '1-5-1981' , 'dd-mm-yyyy' ),
 7782, null, 20
);
insert into emp values(
 7782, 'CLARK', 'MANAGER', 7839,
 to_date( '9-6-1981' , 'dd-mm-yyyy' ),
 7566, null, 30
);
insert into emp values(
 7566, 'JONES', 'MANAGER', 7839,
 to_date( '2-4-1981' , 'dd-mm-yyyy' ),
 7839, null, 40
);

Please note if we use some in-memory database such as H2, we need to automatically load the database script before running the actual code to fetch the data. Thankfully, H2 comes with an INIT parameter which can load the database script from classpath at runtime. The JDBC URL should look like:

jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'

We need to create a method to fetch these data from the database:

public static List<Employee> fetchData() throws SQLException {
    String SQL_QUERY = "select * from emp";
    List<Employee> employees = null;
    try (Connection con = DataSource.getConnection();
        PreparedStatement pst = con.prepareStatement( SQL_QUERY );
        ResultSet rs = pst.executeQuery();) {
            employees = new ArrayList<>();
            Employee employee;
            while ( rs.next() ) {
                employee = new Employee();
                employee.setEmpNo( rs.getInt( "empno" ) );
                employee.setEname( rs.getString( "ename" ) );
                employee.setJob( rs.getString( "job" ) );
                employee.setMgr( rs.getInt( "mgr" ) );
                employee.setHiredate( rs.getDate( "hiredate" ) );
                employee.setSal( rs.getInt( "sal" ) );
                employee.setComm( rs.getInt( "comm" ) );
                employee.setDeptno( rs.getInt( "deptno" ) );
                employees.add( employee );
            }
	} 
    return employees;
}

Now, we can need to create a JUnit method to test it. Since we know the number of rows in the table emp, we can expect that the size of the returned list should be equal to the number of rows:

@Test
public void givenConnection_thenFetchDbData() throws SQLException {
    HikariCPDemo.fetchData();
 
    assertEquals( 4, employees.size() );
}

5. Conclusion

In this quick tutorial, we learned about the benefits of using HikariCP and its configuration.

As always, the full source code is available over on GitHub.

Guide to Spring Web Flow

$
0
0

1. Overview

Spring Web Flow builds on Spring MVC and allows implementing flows within a web application. It’s generally used for creating sequences of steps that guide users through a process or some business logic.

In this quick tutorial, we’ll go through a simple example of a user activation flow. The user is presented with a page and clicks on the Activate button to proceed or on the Cancel button to cancel activation.

Not that the assumption here is that we have an already set-up Spring MVC web application.

2. Setup

Let’s start by adding the Spring Web Flow dependency into the pom.xml:

<dependency>
    <groupId>org.springframework.webflow</groupId>
    <artifactId>spring-webflow</artifactId>
    <version>2.4.4.RELEASE</version>
</dependency>

The latest version of Spring Web Flow can be found in the Central Maven Repository.

3. Creating a Flow

Let’s now create a simple flow. As stated earlier, a flow is a sequence of steps that guides a user through a process. Currently, this can only be done using XML-based config.

Each step in the flow is called a state.

For this simple example, we’ll be using a view-state. A view-state is a step in the flow that renders a matching view. The view-state refers to a page in the app (WEB-INF/view), with the id of the view-state being the name of the page to which it refers.

We will also be using a transition element. A transition element is used for handling events that occur within a particular state.

For this example flow, we’ll set up three view-states – the activation, success, and failure.

The process for this flow is pretty straightforward. The starting point is the activation view. If an activate event is triggered, it should transition to the success view. If the cancel event is triggered, it should transition to the failure view. The transition element handles the button click event that happens in the view-state:

<view-state id="activation">
    <transition on="activate" to="success"/>
    <transition on="cancel" to="failure"/>
</view-state>

<view-state id="success" />

<view-state id="failure" />

The initial activation page, which is referred to by the id activation and located in WEB-INF/view/activation.jsp, is a simple page that has two buttons, activate and cancel. Clicking the buttons with trigger our transitions to either send the user to the success view-state (WEB-INF/view/success.jsp) or the failure view-state (WEB-INF/view/failure.jsp):

<body>
    <h2>Click to activate account</h2>

    <form method="post" action="${flowExecutionUrl}">
        <input type="submit" name="_eventId_activate" value="activate" />
        <input type="submit" name="_eventId_cancel" value="cancel" />
    </form>
</body>

We’re using the flowExecutionUrl to access the context-relative URI for the current flow execution view-state.

4. Configuring the Flow

Next, we will configure Spring Web Flow into our web environment.  We will do this by setting up a Flow Registry and Flow Builder Service.

The Flow Registry allows us to specify the location of our flows and also specify a Flow Builder Service if one is being used.

The Flow Builder Service helps us customize services and settings used to build flows.

One of the services we can customize is the view-factory-creator. The view-factory-creator allows us to customize the ViewFactoryCreator used by Spring Web Flow. Since we are using Spring MVC, we can configure Spring Web Flow to use the view resolver in our Spring MVC configurations.

Here is how we’ll configure Spring Web Flow for our example:

@Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {

    @Autowired
    private WebMvcConfig webMvcConfig;

    @Bean
    public FlowDefinitionRegistry flowRegistry() {
        return getFlowDefinitionRegistryBuilder(flowBuilderServices())
          .addFlowLocation("/WEB-INF/flows/activation-flow.xml", "activationFlow")
          .build();
    }

    @Bean
    public FlowExecutor flowExecutor() {
        return getFlowExecutorBuilder(flowRegistry()).build();
    }

    @Bean
    public FlowBuilderServices flowBuilderServices() {
        return getFlowBuilderServicesBuilder()
          .setViewFactoryCreator(mvcViewFactoryCreator())
          .setDevelopmentMode(true).build();
    }

    @Bean
    public MvcViewFactoryCreator mvcViewFactoryCreator() {
        MvcViewFactoryCreator factoryCreator = new MvcViewFactoryCreator();
        factoryCreator.setViewResolvers(
          Collections.singletonList(this.webMvcConfig.viewResolver()));
        factoryCreator.setUseSpringBeanBinding(true);
        return factoryCreator;
    }
}

We can also use XML for that configuration:

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
    <property name="flowRegistry" ref="activationFlowRegistry"/>
</bean>

<flow:flow-builder-services id="flowBuilderServices"
  view-factory-creator="mvcViewFactoryCreator"/>

<bean id="mvcViewFactoryCreator" 
  class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
    <property name="viewResolvers" ref="jspViewResolver"/>
</bean>

<flow:flow-registry id="activationFlowRegistry" 
  flow-builder-services="flowBuilderServices">
    <flow:flow-location id="activationFlow" path="/WEB-INF/flows/activation-flow.xml"/>
</flow:flow-registry>

<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
    <property name="flowExecutor" ref="activationFlowExecutor"/>
</bean>
<flow:flow-executor id="activationFlowExecutor" 
  flow-registry="activationFlowRegistry"/>

5. Navigating the Flows

To navigate through the flows, start up the web app and go to http://localhost:8080/{context-path}/activationFlow. This sends us to the initial page of the flow, which is the activation page specified in our flow configuration.

You can click on the activate button to go the success page:

 

Or the cancel button to go to the failure page:

 

6. Conclusion

In this article, we used a simple example as a guide on how to use Spring Web Flow.

You can find the complete source code and all code snippets for this article over on GitHub.

Comparing getPath(), getAbsolutePath(), and getCanonicalPath() in Java

$
0
0

1. Overview

The java.io.File class has three methods — getPath(),  getAbsolutePath() and getCanonicalPath() — to obtain the filesystem path.

In this article, we’ll have a quick look at the differences between them and discuss a use case where you may choose to use one over the others.

2. Method Definitions and Examples

Let’s start by goiung over the definitions of the three methods, along with examples based on having the following directory structure present in the user’s home directory:

|-- baeldung
    |-- baeldung.txt
    |-- foo
    |   |-- foo-one.txt
    |   \-- foo-two.txt
    \-- bar
        |-- bar-one.txt
        |-- bar-two.txt
        \-- baz
            |-- baz-one.txt
            \-- baz-two.txt

2.1. getPath()

Simply put, getPath() returns the String representation of the file’s abstract pathname. This is essentially the pathname passed to the File constructor.

So, if the File object was created using a relative path, the returned value from getPath() method would also be a relative path.

If we invoke the following code from the {user.home}/baeldung directory:

File file = new File("foo/foo-one.txt");
String path = file.getPath();

The path variable would have the value:

foo/foo-one.txt  // on Unix systems
foo\foo-one.txt  // on Windows systems

Notice that for the Windows system, the name-separator character has changed from the forward slash(/) character, which was passed to the constructor, to the backslash (\) character. This is because the returned String always uses the platform’s default name-separator character.

2.2. getAbsolutePath()

The getAbsolutePath() method returns the pathname of the file after resolving the path for the current user directory — this is called an absolute pathname. So, for our previous example, file.getAbsolutePath() would return:

/home/username/baeldung/foo/foo-one.txt     // on Unix systems
C:\Users\username\baeldung\foo\foo-one.txt  // on Windows systems

This method only resolves the current directory for a relative path. Shorthand representations (such as “.” and “..”) are not resolved further. Hence when we execute the following code from the directory {user.home}/baeldung:

File file = new File("bar/baz/../bar-one.txt");
String path = file.getAbsolutePath();

The value of the variable path would be:

/home/username/baeldung/bar/baz/../bar-one.txt      // on Unix systems
C:\Users\username\baeldung\bar\baz\..\bar-one.txt   // on Windows systems

2.3. getCanonicalPath()

The getCanonicalPath() method goes a step further and resolves the absolute pathname as well as the shorthands or redundant names like “.” and “.. as per the directory structure. It also resolves symbolic links on Unix systems and converts the drive letter to a standard case on Windows systems.

So for the previous example, getCanonicalPath() method would return:

/home/username/baeldung/bar/bar-one.txt     // on Unix systems
C:\Users\username\baeldung\bar\bar-one.txt  // on Windows systems

Let’s take another example. Given current directory as ${user.home}/baeldung and File object created using the parameter new File(“bar/baz/./baz-one.txt”), the output for getCanonicalPath() would be:

/home/username/baeldung/bar/baz/baz-one.txt     // on Unix systems
C:\Users\username\baeldung\bar\baz\baz-one.txt  // on Windows Systems

It’s worth mentioning that a single file on the filesystem can have an infinite number of absolute paths since there’s an infinite number of ways shorthand representations can be used. However, the canonical path will always be unique since all such representations are resolved.

Unlike the last two methods, getCanonicalPath() may throw IOException because it requires filesystem queries.

For example, on Windows systems, if we create a File object with one of the illegal characters, resolving the canonical path will throw an IOException:

new File("*").getCanonicalPath();

3. Use Case

Let’s say we’re writing a method that takes in a File object as a parameter and saves its fully qualified name into a database. We don’t know whether the path is relative or contains shorthands. In this case, we may want to use getCanonicalPath().

However, since getCanonicalPath() reads the filesystem, it comes at a performance cost. If we are sure that there are no redundant names or symbolic links and drive letter case is standardized (if using a Windows OS), then we should prefer using getAbsoultePath().

4. Conclusion

In this quick tutorial, we covered the differences between the three File methods to get filesystem path. We have also shown a use case where one method may be preferred over the other.

A Junit test class demonstrating the examples of this article can be found over on GitHub.

Introduction to Mustache

$
0
0

1. Overview

In this article, we’ll focus on Mustache templates and use one of its Java APIs for producing dynamic HTML content.

Mustache is a logicless template engine for creating dynamic content like HTML, configuration files among other things.

2. Introduction

Simply put, the engine is classified as logicless because it doesn’t have constructs that support if-else statements and for loops.

The Mustache templates consist of tag names surrounded by { { } } (which resemble mustaches – hence the name) and are backed by a model object containing the data for the template.

3. Maven Dependency

Compiling and execution of the templates is supported by multiple languages – both client side and server side.

To be able to process the templates from Java we make use of its Java library which can be added as a Maven dependency.

Java 8+:

<dependency>
    <groupId>com.github.spullara.mustache.java</groupId>
    <artifactId>compiler</artifactId>
    <version>0.9.4</version>
</dependency>

Java 6/7:

<dependency>
    <groupId>com.github.spullara.mustache.java</groupId>
    <artifactId>compiler</artifactId>
    <version>0.8.18</version>
</dependency>

We can check the latest versions of the library in the Central Maven Repository.

4. Usage

Let’s look at a simple scenario which shows how to:

  1. Write a simple template
  2. Compile the template using Java API
  3. Execute it by providing the necessary data

4.1. A Simple Mustache Template

We’re going to create a simple template for displaying the details of a todo task:

<h2>{{title}}</h2>
<small>Created on {{createdOn}}</small>
<p>{{text}}</p>

In the above template the fields within the curly braces ({{}}) can be:

  • methods and properties of a Java class
  • keys of a Map object

4.2. Compiling the Mustache Template

We can compile the template as shown below:

MustacheFactory mf = new DefaultMustacheFactory();
Mustache m = mf.compile("todo.mustache");

MustacheFactory searches for the given template in the classpath. In our example, we place todo.mustache under src/main/resources.

4.3. Executing the Mustache Template

The data provided to the template will be an instance of the Todo class which definition is:

public class Todo {
    private String title;
    private String text;
    private boolean done;
    private Date createdOn;
    private Date completedOn;
    
    // constructors, getters and setters
}

The compiled template can be executed to get HTML as shown below:

Todo todo = new Todo("Todo 1", "Description");
StringWriter writer = new StringWriter();
m.execute(writer, todo).flush();
String html = writer.toString();

5. Mustache Sections and Iterations

Let’s now have a look at how to list the todos. For iterating over a list data, we make use of Mustache sections.

A section is a block of code which is repeated one or more times depending on the value of the key in the current context.

It looks something like:

{{#todo}}
<!-- Other code -->
{{/todo}}

A section begins with a pound (#) and ends with a slash (/), where each of the signs is followed by the key whose value is used as the basis for rendering the section.

Following are the scenarios that can occur depending on the value of the key:

5.1. Section with Non-Empty List or Non-False Value

Let’s create a template todo-section.mustache which uses a section:

{{#todo}}
<h2>{{title}}</h2>
<small>Created on {{createdOn}}</small>
<p>{{text}}</p>
{{/todo}}

Let’s look at this template in action:

@Test
public void givenTodoObject_whenGetHtml_thenSuccess() 
  throws IOException {
 
    Todo todo = new Todo("Todo 1", "Todo description");
    Mustache m = MustacheUtil.getMustacheFactory()
      .compile("todo.mustache");
    Map<String, Object> context = new HashMap<>();
    context.put("todo", todo);
 
    String expected = "<h2>Todo 1</h2>";
    assertThat(executeTemplate(m, todo)).contains(expected);
}

Let’s create another template todos.mustache for listing the todos:

{{#todos}}
<h2>{{title}}</h2>
{{/todos}}

And create a listing of todos using it:

@Test
public void givenTodoList_whenGetHtml_thenSuccess() 
  throws IOException {
 
    Mustache m = MustacheUtil.getMustacheFactory()
      .compile("todos.mustache");
 
    List<Todo> todos = Arrays.asList(
      new Todo("Todo 1", "Todo description"),
      new Todo("Todo 2", "Todo description another"),
      new Todo("Todo 3", "Todo description another")
    );
    Map<String, Object> context = new HashMap<>();
    context.put("todos", todos);
 
    assertThat(executeTemplate(m, context))
      .contains("<h2>Todo 1</h2>")
      .contains("<h2>Todo 2</h2>")
      .contains("<h2>Todo 3</h2>");
}

5.2. Section With Empty List or False or Null Value

Let’s test the todo-section.mustache with a null value:

@Test
public void givenNullTodoObject_whenGetHtml_thenEmptyHtml() 
  throws IOException {
    Mustache m = MustacheUtil.getMustacheFactory()
      .compile("todo-section.mustache");
    Map<String, Object> context = new HashMap<>();
    assertThat(executeTemplate(m, context)).isEmpty();
}

And likewise, test todos.mustache with an empty list:

@Test
public void givenEmptyList_whenGetHtml_thenEmptyHtml() 
  throws IOException {
    Mustache m = MustacheUtil.getMustacheFactory()
      .compile("todos.mustache");
 
    Map<String, Object> context = new HashMap<>();
    assertThat(executeTemplate(m, context)).isEmpty();;
}

6. Inverted Sections

Inverted sections are those which are rendered only once based on the non-existence of the key or false or null value or an empty list. In other words, these are rendered when a section is not rendered.

These start with a caret (^) and end with a slash (/) as shown below:

{{#todos}}
<h2>{{title}}</h2>
{{/todos}}
{{^todos}}
<p>No todos!</p>
{{/todos}}

The above template when provided with an empty list:

@Test
public void givenEmptyList_whenGetHtmlUsingInvertedSection_thenHtml() 
  throws IOException {
 
    Mustache m = MustacheUtil.getMustacheFactory()
      .compile("todos-inverted-section.mustache");
  
    Map<String, Object> context = new HashMap<>();
    assertThat(executeTemplate(m, context).trim())
      .isEqualTo("<p>No todos!</p>");
}

7. Lambdas

The values for keys of a mustache section can be a function or a lambda expression. In such case, the complete lambda expression is invoked by passing in the text within the section as a parameter to the lambda expression.

Let’s look at a template todos-lambda.mustache:

{{#todos}}
<h2>{{title}}{{#handleDone}}{{doneSince}}{{/handleDone}}</h2>
{{/todos}}

The handleDone key resolves to a Java 8 lambda expression as shown below:

public Function<Object, Object> handleDone() {
    return (obj) -> done ? 
      String.format("<small>Done %s minutes ago<small>", obj) : "";
}

The HTML generated by executing the above template is:

<h2>Todo 1</h2>
<h2>Todo 2</h2>
<h2>Todo 3<small>Done 5 minutes ago<small></h2>

8. Conclusion

In this introductory article, we looked at creating mustache templates with sections, inverted sections, and lambdas. And we used the Java API to compile and execute the templates by providing relevant data.

There are few more advanced features of Mustache that are worth exploring – such as:

  • providing a callable as a value which results in a concurrent evaluation
  • using DecoratedCollection to get first, last and index of collection elements
  • invert API which gives the data given the text and the template

And, as always, the complete source code for this is available over on Github.

Multiple Authentication Providers in Spring Security

$
0
0

1. Overview

In this quick article, we’re going to focus on using multiple mechanisms to authenticate users in Spring Security.

We’ll do that by configuring multiple authentication providers.

2. Authentication Providers

An AuthenticationProvider is an abstraction for fetching user information from a specific repository (like a database, LDAP, custom third party source, etc. ). It uses the fetched user information to validate the supplied credentials.

Simply put, when multiple authentication providers are defined, the providers will be queried in the order they’re declared.

For a quick demonstration, we’ll configure two authentication providers – a custom authentication provider and an in-memory authentication provider.

3. Maven Dependencies

Let’s first add the necessary Spring Security dependencies into our web application:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

And, without Spring Boot:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>4.2.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>4.2.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>4.2.2.RELEASE</version>
</dependency>

The latest version of these dependencies can be found at spring-security-web, spring-security-cor, and spring-security-config.

4. Custom Authentication Provider

Let’s now create a custom authentication provider by implementing the AuthneticationProvider interface.

We’re going to implement the authenticate method – which attempts the authentication. The input Authentication object contains the username and password credentials supplied by the user.

The authenticate method returns a fully populated Authentication object if the authentication is successful. If authentication fails, it throws an exception of type AuthenticationException:

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication auth) 
      throws AuthenticationException {
        String username = auth.getName();
        String password = auth.getCredentials()
            .toString();

        if ("externaluser".equals(username) && "pass".equals(password)) {
            return new UsernamePasswordAuthenticationToken
              (username, password, Collections.emptyList());
        } else {
            throw new 
              BadCredentialsException("External system authentication failed");
        }
    }

    @Override
    public boolean supports(Class<?> auth) {
        return auth.equals(UsernamePasswordAuthenticationToken.class);
    }
}

Naturally, this is a simple implementation for the purpose of our example here.

5. Configuring Multiple Authentication Providers

Let’s now add the CustomAuthenticationProvider and an in-memory authentication provider to our Spring Security configuration.

5.1. Java Configuration

In our configuration class, let’s now create and add the authentication providers using the AuthenticationManagerBuilder.

First, the CustomAuthenticationProvider and then, an in-memory authentication provider by using inMemoryAuthentication().

We are also making sure that access to the URL pattern “/api/**” needs to be authenticated:

@EnableWebSecurity
public class MultipleAuthProvidersSecurityConfig 
  extends WebSecurityConfigurerAdapter {
    @Autowired
    CustomAuthenticationProvider customAuthProvider;

    @Override
    public void configure(AuthenticationManagerBuilder auth) 
      throws Exception {

        auth.authenticationProvider(customAuthProvider);
        auth.inMemoryAuthentication()
            .withUser("memuser")
            .password("pass")
            .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
            .and()
            .authorizeRequests()
            .antMatchers("/api/**")
            .authenticated();
    }
}

5.2. XML Configuration

Alternatively, if we want to use XML configuration instead of Java configuration:

<security:authentication-manager>
    <security:authentication-provider>
        <security:user-service>
            <security:user name="memuser" password="pass" 
              authorities="ROLE_USER" />
        </security:user-service>
    </security:authentication-provider>
    <security:authentication-provider
      ref="customAuthenticationProvider" />
</security:authentication-manager>

<security:http>
    <security:http-basic />
    <security:intercept-url pattern="/api/**" 
      access="isAuthenticated()" />
</security:http>

6. The Application

Next, let’s create a simple REST endpoint that is secured by our two authentication providers.

To access this endpoint, a valid username and password must be supplied. Our authentication providers will validate the credentials and determine whether to allow access or not:

@RestController
public class MultipleAuthController {
    @RequestMapping("/api/ping")
    public String getPing() {
        return "OK";
    }
}

6. Testing

Finally, let’s now test the access to our secure application. Access will be allowed only if valid credentials are supplied:

@Autowired
private TestRestTemplate restTemplate;

@Test
public void givenMemUsers_whenGetPingWithValidUser_thenOk() {
    ResponseEntity<String> result 
      = makeRestCallToGetPing("memuser", "pass");

    assertThat(result.getStatusCodeValue()).isEqualTo(200);
    assertThat(result.getBody()).isEqualTo("OK");
}

@Test
public void givenExternalUsers_whenGetPingWithValidUser_thenOK() {
    ResponseEntity<String> result 
      = makeRestCallToGetPing("externaluser", "pass");

    assertThat(result.getStatusCodeValue()).isEqualTo(200);
    assertThat(result.getBody()).isEqualTo("OK");
}

@Test
public void givenAuthProviders_whenGetPingWithNoCred_then401() {
    ResponseEntity<String> result = makeRestCallToGetPing();

    assertThat(result.getStatusCodeValue()).isEqualTo(401);
}

@Test
public void givenAuthProviders_whenGetPingWithBadCred_then401() {
    ResponseEntity<String> result 
      = makeRestCallToGetPing("user", "bad_password");

    assertThat(result.getStatusCodeValue()).isEqualTo(401);
}

private ResponseEntity<String> 
  makeRestCallToGetPing(String username, String password) {
    return restTemplate.withBasicAuth(username, password)
      .getForEntity("/api/ping", String.class, Collections.emptyMap());
}

private ResponseEntity<String> makeRestCallToGetPing() {
    return restTemplate
      .getForEntity("/api/ping", String.class, Collections.emptyMap());
}

7. Conclusion

In this quick tutorial, we’ve seen how multiple authentication providers can be configured in Spring Security. We have secured a simple application using a custom authentication provider and an in-memory authentication provider.

We have secured a simple application using a custom authentication provider and an in-memory authentication provider.

And we’ve also written tests to verify that the access to our application requires credentials that can be validated by at least one of our authentication providers.

As always, the full source code of the implementation can be found over on GitHub.


How to Add a Single Element to a Stream

$
0
0

1. Overview

In this quick article, we’re going to take a look at how to add an element to a Java 8 Stream which is not as intuitive as adding an element to a normal collection.

2. Prepending

We can easily prepend a given element to a Stream by invoking the static Stream.concat() method:

@Test
public void givenStream_whenPrependingObject_thenPrepended() {
    Stream<Integer> anStream = Stream.of(1, 2, 3, 4, 5);

    Stream<Integer> newStream = Stream.concat(Stream.of(99), anStream);

    assertEquals(newStream.findFirst().get(), (Integer) 99);
}

3. Appending

Likewise, to append an element to the end of a Stream, we just need to invert the arguments.

Keep in mind that Streams can represent infinite sequences so there are scenarios when you might never get to your new element:

@Test
public void givenStream_whenAppendingObject_thenAppended() {
    Stream<String> anStream = Stream.of("a", "b", "c", "d", "e");

    Stream<String> newStream = Stream.concat(anStream, Stream.of("A"));

    List<String> resultList = newStream.collect(Collectors.toList());
 
    assertEquals(resultList.get(resultList.size() - 1), "A");
}

4. At a Specific Index

This operation is not fully supported by Stream API because essentially Streams are not collections and do not recognize the concept of indexes.

So, in order to do this, we need to convert the Stream to a list, then insert the element, and finally, get a Stream from that new list.

Keep in mind that this will give you the desired result, but you will also lose the laziness of a Stream because we need to consume it before inserting a new element.

Let’s create a utility method to do the heavy work:

public <T> Stream<T> insertInStream(Stream<T> stream, T elem, int index) {
    List<T> result = stream.collect(Collectors.toList());
    result.add(index, elem);
    return result.stream();
}

Now, let’s test our code to ensure everything is working as expected:

@Test
public void givenStream_whenInsertingObject_thenInserted() {
    Stream<Double> anStream = Stream.of(1.1, 2.2, 3.3);

    Stream<Double> newStream = insertInStream(anStream, 9.9, 3);

    List<Double> resultList = newStream.collect(Collectors.toList());
 
    assertEquals(resultList.get(3), (Double) 9.9);
}

5. Conclusion

In this short article, we’ve seen how to add a single element to a Stream, be it at the beginning, at the end, or at a given position.

Keep in mind that although prepending an element works for any Stream, adding it to the end or at a specific index only works for finite streams.

As always, complete source code can be found over on Github.

Serenity BDD with Spring and JBehave

$
0
0

1. Introduction

Previously, we have introduced the Serenity BDD framework.

In this article, we’ll introduce how to integrate Serenity BDD with Spring.

2. Maven Dependency

To enable Serenity in our Spring project, we need to add serenity-core and serenity-spring to the pom.xml:

<dependency>
    <groupId>net.serenity-bdd</groupId>
    <artifactId>serenity-core</artifactId>
    <version>1.4.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>net.serenity-bdd</groupId>
    <artifactId>serenity-spring</artifactId>
    <version>1.4.0</version>
    <scope>test</scope>
</dependency>

We also need to configure the serenity-maven-plugin, which is important for generating Serenity test reports:

<plugin>
    <groupId>net.serenity-bdd.maven.plugins</groupId>
    <artifactId>serenity-maven-plugin</artifactId>
    <version>1.4.0</version>
    <executions>
        <execution>
            <id>serenity-reports</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>aggregate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3. Spring Integration

Spring integration test needs to @RunWith SpringJUnit4ClassRunner. But we cannot use the test runner directly with Serenity, as Serenity tests need to be run by SerenityRunner.

For tests with Serenity, we can use SpringIntegrationMethodRule and SpringIntegrationClassRule to enable injection.

We’ll base our test on a simple scenario: given a number, when adding another number, then returns the sum.

3.1. SpringIntegrationMethodRule

SpringIntegrationMethodRule is a MethodRule applied to the test methods. The Spring context will be built before @Before and after @BeforeClass.

Suppose we have a property to inject in our beans:

<util:properties id="props">
    <prop key="adder">4</prop>
</util:properties>

Now let’s add SpringIntegrationMethodRule to enable the value injection in our test:

@RunWith(SerenityRunner.class)
@ContextConfiguration(locations = "classpath:adder-beans.xml")
public class AdderMethodRuleIntegrationTest {

    @Rule 
    public SpringIntegrationMethodRule springMethodIntegration 
      = new SpringIntegrationMethodRule();

    @Steps 
    private AdderSteps adderSteps;

    @Value("#{props['adder']}") 
    private int adder;

    @Test
    public void givenNumber_whenAdd_thenSummedUp() {
        adderSteps.givenNumber();
        adderSteps.whenAdd(adder);
        adderSteps.thenSummedUp(); 
    }
}

It also supports method level annotations of spring test. If some test method dirties the test context, we can mark @DirtiesContext on it:

@RunWith(SerenityRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = AdderService.class)
public class AdderMethodDirtiesContextIntegrationTest {

    @Steps private AdderServiceSteps adderServiceSteps;

    @Rule public SpringIntegrationMethodRule springIntegration = new SpringIntegrationMethodRule();

    @DirtiesContext
    @Test
    public void _0_givenNumber_whenAddAndAccumulate_thenSummedUp() {
        adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt());
        adderServiceSteps.whenAccumulate();
        adderServiceSteps.summedUp();

        adderServiceSteps.whenAdd();
        adderServiceSteps.sumWrong();
    }

    @Test
    public void _1_givenNumber_whenAdd_thenSumWrong() {
        adderServiceSteps.whenAdd();
        adderServiceSteps.sumWrong();
    }

}

In the example above, when we invoke adderServiceSteps.whenAccumulate(), the base number field of the @Service injected in adderServiceSteps will be changed:

@ContextConfiguration(classes = AdderService.class)
public class AdderServiceSteps {

    @Autowired
    private AdderService adderService;

    private int givenNumber;
    private int base;
    private int sum;

    public void givenBaseAndAdder(int base, int adder) {
        this.base = base;
        adderService.baseNum(base);
        this.givenNumber = adder;
    }

    public void whenAdd() {
        sum = adderService.add(givenNumber);
    }

    public void summedUp() {
        assertEquals(base + givenNumber, sum);
    }

    public void sumWrong() {
        assertNotEquals(base + givenNumber, sum);
    }

    public void whenAccumulate() {
        sum = adderService.accumulate(givenNumber);
    }

}

Specifically, we assign the sum to the base number:

@Service
public class AdderService {

    private int num;

    public void baseNum(int base) {
        this.num = base;
    }

    public int currentBase() {
        return num;
    }

    public int add(int adder) {
        return this.num + adder;
    }

    public int accumulate(int adder) {
        return this.num += adder;
    }
}

In the first test _0_givenNumber_whenAddAndAccumulate_thenSummedUp, the base number is changed, making the context dirty. When we try to add another number, we won’t get an expected sum.

Notice that even if we marked the first test with @DirtiesContext, the second test is still affected: after adding, the sum is still wrong. Why?

Now, while processing method level @DirtiesContext, Serenity’s Spring integration only rebuild the test context for the current test instance. The underlying dependency context in @Steps will not be rebuilt.

To work around this problem, we can inject the @Service in our current test instance, and make service as an explicit dependency of @Steps:

@RunWith(SerenityRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = AdderService.class)
public class AdderMethodDirtiesContextDependencyWorkaroundIntegrationTest {

    private AdderConstructorDependencySteps adderSteps;

    @Autowired private AdderService adderService;

    @Before
    public void init() {
        adderSteps = new AdderConstructorDependencySteps(adderService);
    }

    //...
}
public class AdderConstructorDependencySteps {

    private AdderService adderService;

    public AdderConstructorDependencySteps(AdderService adderService) {
        this.adderService = adderService;
    }

    // ...
}

Or we can put the condition initialisation step in the @Before section to avoid dirty context. But this kind of solution may not be available in some complex situations.

@RunWith(SerenityRunner.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = AdderService.class)
public class AdderMethodDirtiesContextInitWorkaroundIntegrationTest {

    @Steps private AdderServiceSteps adderServiceSteps;

    @Before
    public void init() {
        adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt());
    }

    //...
}

3.2. SpringIntegrationClassRule

To enable class level annotations, we should use SpringIntegrationClassRule. Say we have the following test classes; each dirties the context:

@RunWith(SerenityRunner.class)
@ContextConfiguration(classes = AdderService.class)
public static abstract class Base {

    @Steps AdderServiceSteps adderServiceSteps;

    @ClassRule public static SpringIntegrationClassRule springIntegrationClassRule = new SpringIntegrationClassRule();

    void whenAccumulate_thenSummedUp() {
        adderServiceSteps.whenAccumulate();
        adderServiceSteps.summedUp();
    }

    void whenAdd_thenSumWrong() {
        adderServiceSteps.whenAdd();
        adderServiceSteps.sumWrong();
    }

    void whenAdd_thenSummedUp() {
        adderServiceSteps.whenAdd();
        adderServiceSteps.summedUp();
    }
}
@DirtiesContext(classMode = AFTER_CLASS)
public static class DirtiesContextTest extends Base {

    @Test
    public void givenNumber_whenAdd_thenSumWrong() {
        super.whenAdd_thenSummedUp();
        adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt());
        super.whenAccumulate_thenSummedUp();
        super.whenAdd_thenSumWrong();
    }
}
@DirtiesContext(classMode = AFTER_CLASS)
public static class AnotherDirtiesContextTest extends Base {

    @Test
    public void givenNumber_whenAdd_thenSumWrong() {
        super.whenAdd_thenSummedUp();
        adderServiceSteps.givenBaseAndAdder(randomInt(), randomInt());
        super.whenAccumulate_thenSummedUp();
        super.whenAdd_thenSumWrong();
    }
}

In this example, all implicit injections will be rebuilt for class level @DirtiesContext.

3.3. SpringIntegrationSerenityRunner

There is a convenient class SpringIntegrationSerenityRunner that automatically adds both integration rules above. We can run tests above with this runner to avoid specifying the method or class test rules in our test:

@RunWith(SpringIntegrationSerenityRunner.class)
@ContextConfiguration(locations = "classpath:adder-beans.xml")
public class AdderSpringSerenityRunnerIntegrationTest {

    @Steps private AdderSteps adderSteps;

    @Value("#{props['adder']}") private int adder;

    @Test
    public void givenNumber_whenAdd_thenSummedUp() {
        adderSteps.givenNumber();
        adderSteps.whenAdd(adder);
        adderSteps.thenSummedUp();
    }
}

4. SpringMVC Integration

In cases when we only need to test SpringMVC components with Serenity, we can simply make use of RestAssuredMockMvc in rest-assured instead of the serenity-spring integration.

4.1. Maven Dependency

We need to add the rest-assured spring-mock-mvc dependency to the pom.xml:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>spring-mock-mvc</artifactId>
    <version>3.0.3</version>
    <scope>test</scope>
</dependency>

4.2. RestAssuredMockMvc In Action

Let’s now test the following controller:

@RequestMapping(value = "/adder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
public class PlainAdderController {

    private final int currentNumber = RandomUtils.nextInt();

    @GetMapping("/current")
    public int currentNum() {
        return currentNumber;
    }

    @PostMapping
    public int add(@RequestParam int num) {
        return currentNumber + num;
    }
}

We can take advantage of the MVC-mocking utilities of RestAssuredMockMvc like this:

@RunWith(SerenityRunner.class)
public class AdderMockMvcIntegrationTest {

    @Before
    public void init() {
        RestAssuredMockMvc.standaloneSetup(new PlainAdderController());
    }

    @Steps AdderRestSteps steps;

    @Test
    public void givenNumber_whenAdd_thenSummedUp() throws Exception {
        steps.givenCurrentNumber();
        steps.whenAddNumber(randomInt());
        steps.thenSummedUp();
    }
}

Then the rest part is no different from how we use rest-assured:

public class AdderRestSteps {

    private MockMvcResponse mockMvcResponse;
    private int currentNum;

    @Step("get the current number")
    public void givenCurrentNumber() throws UnsupportedEncodingException {
        currentNum = Integer.valueOf(given()
          .when()
          .get("/adder/current")
          .mvcResult()
          .getResponse()
          .getContentAsString());
    }

    @Step("adding {0}")
    public void whenAddNumber(int num) {
        mockMvcResponse = given()
          .queryParam("num", num)
          .when()
          .post("/adder");
        currentNum += num;
    }

    @Step("got the sum")
    public void thenSummedUp() {
        mockMvcResponse
          .then()
          .statusCode(200)
          .body(equalTo(currentNum + ""));
    }
}

5. Serenity, JBehave, and Spring

Serenity’s Spring integration support works seamlessly with JBehave. Let’s write our test scenario as a JBehave story:

Scenario: A user can submit a number to adder and get the sum
Given a number
When I submit another number 5 to adder
Then I get a sum of the numbers

We can implement the logics in a @Service and expose the actions via APIs:

@RequestMapping(value = "/adder", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
public class AdderController {

    private AdderService adderService;

    public AdderController(AdderService adderService) {
        this.adderService = adderService;
    }

    @GetMapping("/current")
    public int currentNum() {
        return adderService.currentBase();
    }

    @PostMapping
    public int add(@RequestParam int num) {
        return adderService.add(num);
    }
}

Now we can build Serenity-JBehave test with the help of RestAssuredMockMvc as follows:

@ContextConfiguration(classes = { 
  AdderController.class, AdderService.class })
public class AdderTest extends SerenityStory {

    @Autowired private AdderService adderService;

    @BeforeStory
    public void init() {
        RestAssuredMockMvc.standaloneSetup(new AdderController(adderService));
    }
}
public class AdderStory {

    @Steps AdderRestSteps restSteps;

    @Given("a number")
    public void givenANumber() throws Exception{
        restSteps.givenCurrentNumber();
    }

    @When("I submit another number $num to adder")
    public void whenISubmitToAdderWithNumber(int num){
        restSteps.whenAddNumber(num);
    }

    @Then("I get a sum of the numbers")
    public void thenIGetTheSum(){
        restSteps.thenSummedUp();
    }
}

We can only mark SerenityStory with @ContextConfiguration, then Spring injection is enabled automatically. This works quite the same as the @ContextConfiguration on @Steps.

6. Summary

In this article, we covered on how to integrate Serenity BDD with Spring. The integration is not quite perfect, but it’s definitely getting there.

As always, the full implementation can be found over on the GitHub project.

Iterating over Enum Values in Java

$
0
0

1. Overview

Enum in Java is a datatype that helps us assign a predefined set of constants to a variable.

In this quick article, we’ll see different ways in which we can iterate over an enum in Java.

2. Iterating over Enum Values

Let’s first define an enum class, which we’ll use in our examples:

public enum DaysOfWeekEnum {
    SUNDAY,
    MONDAY,
    TUESDAY, 
    WEDNESDAY, 
    THURSDAY, 
    FRIDAY, 
    SATURDAY
}

Enums do not have methods for iteration like forEach() or iterator(). Instead, it has a method called values() which returns the predefined values.

2.1. Iterate Using forEach()

In order to perform the iteration using forEach(), we need to convert the enum into a list or a set.

First, we use EnumSet, which is a specialized set implementation to use with Enum types:

EnumSet.allOf(DaysOfWeekEnum.class)
  .forEach(day -> System.out.println(day));

Similarly, we can use Arrays:

Arrays.asList(DaysOfWeekEnum.class)
  .forEach(day -> System.out.println(day));

Here, EnumSet and Arrays convert the enum into Set and List respectively.

2.2. Iterate Using Stream

We can also use java.util.stream if we want to perform any parallel aggregate operations.

Again, to create Stream we have two options, one using Stream.of:

Stream.of(DaysOfWeekEnum.values());

Another, using Arrays:

Arrays.stream(DaysOfWeekEnum.values());

Here, values() is an Enum method, which returns all the predefined values.

Now, let us extend the DaysOfWeekEnum class to create an example using Stream:

public enum DaysOfWeekEnum {
    SUNDAY("off"), 
    MONDAY("working"), 
    TUESDAY("working"), 
    WEDNESDAY("working"), 
    THURSDAY("working"), 
    FRIDAY("working"), 
    SATURDAY("off");

    private String typeOfDay;

    DaysOfWeekEnum(String typeOfDay) {
        this.typeOfDay = typeOfDay;
    }
}

Now we will write an example to return the non-working days:

public class EnumStreamExample {

    public static void main() {
        DaysOfWeekEnum.stream()
        .filter(d -> d.getTypeOfDay().equals("off"))
        .forEach(System.out::println);
    }

    public static Stream<DaysOfWeekEnum> stream() {
        return Stream.valueOf(DaysOfWeekEnum.values()); 
    }
}

The output we get when we run this:

SUNDAY
SATURDAY

2.3. Iterate Using for loop

Lastly, we can simply use the old-school for loop:

for (DaysOfWeekEnum day : DaysOfWeekEnum.values()) { 
    System.out.println(day); 
}

3. Conclusion

We saw various ways to iterate over an enum using forEach, Stream, and for loop in Java. If we need to perform any parallel operations, Stream would be a good option.

Otherwise, there is no restriction on which method to use.

As always, the code for all the examples explained here can be found over on GitHub.

Spring Remoting with JMS

$
0
0

1. Overview

We saw in a previous article how Spring Remoting could be used to provide RPC on top of an asynchronous channel as an AMQP queue. However, we can obtain the same result using JMS too.

In this article, we’ll, in fact, explore how to set up remote invocation using Spring Remoting JMS and Apache ActiveMQ as a messaging middleware.

2. Starting an Apache ActiveMQ Broker

Apache ActiveMQ is an open source message broker that enables applications to exchange information asynchronously, and it is entirely compatible with the Java Message Service API.

To run our experiment, we firstly need to set up a running instance of ActiveMQ. We can choose among several ways: following the steps described in the official guide, embedding it in a Java application or more simply spinning up a Docker container with the following command:

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3

This will start an ActiveMQ container that exposes on port 8081 a simple administration web GUI, through which we can check the available queues, connected clients, and other administrative information. JMS clients will need to use port 61616 to connect to the broker and exchange messages instead.

3. Maven Dependencies

As in the previous articles covering Spring Remoting, we are going to set up a server and a client Spring Boot applications to show how JMS Remoting works.

As usually we carefully choose the Spring Boot starter dependencies, as explained here:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

We explicitly excluded the spring-boot-starter-tomcat in order not to have the Tomcat related .jar files in the classpath.

This, in turn, will prevent the Spring Boot‘s autoconfiguration mechanism to launch an embedded web server when the application starts up since we don’t need it.

4. Server Application

4.1. Expose the Service

We’ll set up a server application that exposes the CabBookingService that clients will be able to invoke.

The first step is to declare a bean that implements the interface of the service we want to expose to the clients. This is the bean that will execute the business logic on the server:

@Bean 
CabBookingService bookingService() {
    return new CabBookingServiceImpl();
}

Let’s then define the queue from which the server will retrieve invocations, specifying its name in the constructor:

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

As we already know from the previous articles, one of the main concepts of Spring Remoting is the Service Exporter, the component that collects the invocation requests from some source, in this case, an ApacheMQ queue ─ and invokes the desired method on the service implementation.

To work with JMS, we define a JmsInvokerServiceExporter:

@Bean 
JmsInvokerServiceExporter exporter(CabBookingService implementation) {
    JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
    exporter.setServiceInterface(CabBookingService.class);
    exporter.setService(implementation);
    return exporter;
}

Finally, we need to define a listener that has the responsibility to consume messages. The listener acts as a bridge between ApacheMQ and the JmsInvokerServiceExporter, it listens to invocation messages available on the queue, forwards the invocation to the service exporter and serializes back the results:

@Bean SimpleMessageListenerContainer listener(
  ConnectionFactory factory, 
  JmsInvokerServiceExporter exporter) {
 
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.setDestinationName("remotingQueue");
    container.setConcurrentConsumers(1);
    container.setMessageListener(exporter);
    return container;
}

4.2. Configuration

Let’s remember to set up the application.properties file to allow Spring Boot to configure some basic objects, as for instance the ConnectionFactory needed by the listener. The values of the various parameters mainly depend on the way

The values of the various parameters mainly depend on the way ApacheMQ has been installed, and the following one is a reasonable configuration for our Docker container running on the same machine where we’ll run these examples:

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.baeldung.api

The spring.activemq.broker-url parameter is a reference to the AMQ port. A deeper explanation is needed for spring.activemq.packages.trusted parameter instead. Since version 5.12.2 ActiveMQ refuses by default any message of type

Starting with version 5.12.2 ActiveMQ refuses by default any message of type ObjectMessage, used to exchange serialized Java object, because it is considered a potential vector for a security attack in some contexts.

Anyhow, it is possible to instruct AMQ to accept serialized objects in specified packages. org.springframework.remoting.support is the package that contains the main messages that represent the invocation of a remote method and its result. The package

The package com.baeldung.api contains the parameters and the results of our service. java.lang is added because the object that represents the result of the cab booking references a String, so we need to serialize that too.

5. Client Application

5.1. Invoke the Remote Service

Let’s tackle the client now. Again, we need to define the queue where invocation messages will be written to. We need to double-check that both client and server use the same name.

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

We then need to set up an exporter:

@Bean 
FactoryBean invoker(ConnectionFactory factory, Queue queue) {
    JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean();
    factoryBean.setConnectionFactory(factory);
    factoryBean.setServiceInterface(CabBookingService.class);
    factoryBean.setQueue(queue);
    return factoryBean;
}

We can now use the remote service as if it was declared as a local bean:

CabBookingService service = context.getBean(CabBookingService.class);
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));

5.2. Run the Example

Also for the client application, we have to choose the values in the application properly.properties file. In a common setup, those would exactly match the ones used on the server side.

This should be enough to demonstrate the remote invocation through Apache AMQ. So, let’s first start ApacheMQ, then the server application, and finally the client application that will invoke the remote service.

6. Conclusion

In this quick tutorial, we saw how we could use Spring Remoting to provide RPC on top of a JMS system as AMQ.

Spring Remoting keeps on demonstrating how it is easy to quickly set up asynchronous call regardless of the underlying channel.

As usual, you’ll find the sources over on GitHub.

Testing with Google Truth

$
0
0

1. Overview

Truth is a fluent and flexible open-source testing framework designed to make test assertions and failure messages more readable.

In this article, we’ll explore the key features of the Truth framework and implement examples to showcase its capabilities.

2. Maven Dependencies

First, we need to add the truth and truth-java8-extension to our pom.xml:

<dependency>
    <groupId>com.google.truth</groupId>
    <artifactId>truth</artifactId>
    <version>0.32</version>
</dependency>
<dependency>
    <groupId>com.google.truth.extensions</groupId>
    <artifactId>truth-java8-extension</artifactId>
    <version>0.32</version>
    <scope>test</scope>
</dependency>

You can find the latest versions of truth and truth-java8-extension on Maven Central.

3. Introduction

Truth allows us to write readable assertions and failure messages for a variety of classes:

  • Standard Java – primitives, arrays, strings, objects, collections, throwables, classes, etc.
  • Java 8 – Optional and Stream instances
  • Guava – Optional, Multimap, Multiset, and Table objects
  • Custom types – by extending the Subject class, as we’ll see later

Through the Truth and Truth8 classes, the library provides utility methods for writing assertions that work on a subject, that’s the value or object under test.

Once the subject is known, Truth can reason at compile time about what propositions are known for that subject. This allows it to return wrappers around our value that declare proposition methods specific to that particular subject.

For example, when asserting on a list, Truth returns an IterableSubject instance defining methods like contains() and containsAnyOf(), among others. When asserting on a Map, it returns a MapSubject that declares methods like containsEntry() and containsKey().

4. Getting Started

To start writing assertions, let’s first import Truth‘s entry points:

import static com.google.common.truth.Truth.*;
import static com.google.common.truth.Truth8.*;

Now, let’s write a simple class that we’ll use in a few of the examples that follow:

public class User {
    private String name = "John Doe";
    private List<String> emails
      = Arrays.asList("contact@baeldung.com", "staff@baeldung.com");

    public boolean equals(Object obj) {
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }

        User other = (User) obj;
        return Objects.equals(this.name, other.name);
    }

    // standard constructors, getters and setters
}

Notice the custom equals() method, in which we state that two User objects are equal if their names are.

5. Standard Java Assertions

In this section, we’ll see detailed examples of how to write test assertions for standard Java types.

5.1. Object Assertions

Truth provides the Subject wrapper for performing assertions on objects. Subject is also the parent of all other wrappers in the library and declares methods for determining if an Object, in our case a User, is equal to another object:

@Test
public void whenComparingUsers_thenEqual() {
    User aUser = new User("John Doe");
    User anotherUser = new User("John Doe");

    assertThat(aUser).isEqualTo(anotherUser);
}

or if it’s equal to a given object in a list:

@Test
public void whenComparingUser_thenInList() {
    User aUser = new User();

    assertThat(aUser).isIn(Arrays.asList(1, 3, aUser, null));
}

or if it isn’t:

@Test
public void whenComparingUser_thenNotInList() {
    // ...

    assertThat(aUser).isNotIn(Arrays.asList(1, 3, "Three"));
}

if it’s null or not:

@Test
public void whenComparingUser_thenIsNull() {
    User aUser = null;

    assertThat(aUser).isNull();
}

@Test
public void whenComparingUser_thenNotNull() {
    User aUser = new User();

    assertThat(aUser).isNotNull();
}

or if it’s an instance of a particular class:

@Test
public void whenComparingUser_thenInstanceOf() {
    // ...

    assertThat(aUser).isInstanceOf(User.class);
}

There are other assertion methods in the Subject class. To discover them all, refer to the Subject documentation.

In the following sections, we are going to focus on the most relevant methods for each particular type Truth supports. However, keep in mind that all methods in the Subject class can also be applied.

5.2. Integer, Float, and Double Assertions

Integer, Float, and Double instances can be compared for equality:

@Test
public void whenComparingInteger_thenEqual() {
    int anInt = 10;

    assertThat(anInt).isEqualTo(10);
}

if they are bigger:

@Test
public void whenComparingFloat_thenIsBigger() {
    float aFloat = 10.0f;

    assertThat(aFloat).isGreaterThan(1.0f);
}

or smaller:

@Test
public void whenComparingDouble_thenIsSmaller() {
    double aDouble = 10.0f;

    assertThat(aDouble).isLessThan(20.0);
}

Furthermore, Float and Double instances can also be checked to see if they are within an expected precision or not:

@Test
public void whenComparingDouble_thenWithinPrecision() {
    double aDouble = 22.18;

    assertThat(aDouble).isWithin(2).of(23d);
}

@Test
public void whenComparingFloat_thenNotWithinPrecision() {
    float aFloat = 23.04f;

    assertThat(aFloat).isNotWithin(1.3f).of(100f);
}

5.3. BigDecimal Assertions

Besides the common assertions, this type can be compared ignoring its scale:

@Test
public void whenComparingBigDecimal_thenEqualIgnoringScale() {
    BigDecimal aBigDecimal = BigDecimal.valueOf(1000, 3);

    assertThat(aBigDecimal).isEqualToIgnoringScale(new BigDecimal(1.0));
}

5.4. Boolean Assertions

Only two relevant methods are provided, isTrue() and isFalse():

@Test
public void whenCheckingBoolean_thenTrue() {
    boolean aBoolean = true;

    assertThat(aBoolean).isTrue();
}

5.5. String Assertions

We can test whether a String starts with a particular text:

@Test
public void whenCheckingString_thenStartsWith() {
    String aString = "This is a string";

    assertThat(aString).startsWith("This");
}

In addition, we can check if the string contains a given String, if it ends with an expected value or whether it’s empty. Test cases for these and other methods are available in the source code.

5.6. Array Assertions

We can check Arrays to see if they are equal to other arrays:

@Test
public void whenComparingArrays_thenEqual() {
    String[] firstArrayOfStrings = { "one", "two", "three" };
    String[] secondArrayOfStrings = { "one", "two", "three" };

    assertThat(firstArrayOfStrings).isEqualTo(secondArrayOfStrings);
}

or if they are empty:

@Test
public void whenCheckingArray_thenEmpty() {
    Object[] anArray = {};

    assertThat(anArray).isEmpty();
}

5.7. Comparable Assertions

Besides testing whether a Comparable is greater than or less than another instance, we can check to see if they are at least a given value:

@Test
public void whenCheckingComparable_thenAtLeast() {
    Comparable<Integer> aComparable = 5;

    assertThat(aComparable).isAtLeast(1);
}

Also, we can test whether they are within a particular range:

@Test
public void whenCheckingComparable_thenInRange() {
    // ...

    assertThat(aComparable).isIn(Range.closed(1, 10));
}

or in a particular list:

@Test
public void whenCheckingComparable_thenInList() {
    // ...

    assertThat(aComparable).isIn(Arrays.asList(4, 5, 6));
}

We can also test if two Comparable instances are equivalent according to the class’s compareTo() method.

First, let’s modify our User class to implement the Comparable interface:

public class User implements Comparable<User> {
    // ...
    
    public int compareTo(User o) {
        return this.getName().compareToIgnoreCase(o.getName());
    }
}

Now, let’s assert that two users with the same name are equivalent:

@Test
public void whenComparingUsers_thenEquivalent() {
    User aUser = new User();
    aUser.setName("John Doe");

    User anotherUser = new User();
    anotherUser.setName("john doe");

    assertThat(aUser).isEquivalentAccordingToCompareTo(anotherUser);
}

5.8. Iterable Assertions

In addition to asserting the size of an Iterable instance, whether it’s empty or has no duplicates, most typical assertions on an Iterable are that it contains some element:

@Test
public void whenCheckingIterable_thenContains() {
    List<Integer> aList = Arrays.asList(4, 5, 6);

    assertThat(aList).contains(5);
}

that it contains any element of another Iterable:

@Test
public void whenCheckingIterable_thenContainsAnyInList() {
    List<Integer> aList = Arrays.asList(1, 2, 3);

    assertThat(aList).containsAnyIn(Arrays.asList(1, 5, 10));
}

and that the subject has the same elements, in the same order, like another:

@Test
public void whenCheckingIterable_thenContainsExactElements() {
    List<String> aList = Arrays.asList("10", "20", "30");
    List<String> anotherList = Arrays.asList("10", "20", "30");

    assertThat(aList)
      .containsExactlyElementsIn(anotherList)
      .inOrder();
}

and if it’s ordered using a custom comparator:

@Test
public void givenComparator_whenCheckingIterable_thenOrdered() {
    Comparator<String> aComparator
      = (a, b) -> new Float(a).compareTo(new Float(b));

    List<String> aList = Arrays.asList("1", "012", "0020", "100");

    assertThat(aList).isOrdered(aComparator);
}

5.9. Map Assertions

In addition to asserting that a Map instance is empty or not, or has a specific size; we can check if it has a specific entry:

@Test
public void whenCheckingMap_thenContainsEntry() {
    Map<String, Object> aMap = new HashMap<>();
    aMap.put("one", 1L);

    assertThat(aMap).containsEntry("one", 1L);
}

if it has a specific key:

@Test
public void whenCheckingMap_thenContainsKey() {
    // ...

    assertThat(map).containsKey("one");
}

or if it has the same entries as another Map:

@Test
public void whenCheckingMap_thenContainsEntries() {
    Map<String, Object> aMap = new HashMap<>();
    aMap.put("first", 1L);
    aMap.put("second", 2.0);
    aMap.put("third", 3f);

    Map<String, Object> anotherMap = new HashMap<>(aMap);

    assertThat(aMap).containsExactlyEntriesIn(anotherMap);
}

5.10. Exception Assertions

Only two methods of importance are provided for Exception objects.

We can write assertions addressed to the cause of the exception:

@Test
public void whenCheckingException_thenInstanceOf() {
    Exception anException
      = new IllegalArgumentException(new NumberFormatException());

    assertThat(anException)
      .hasCauseThat()
      .isInstanceOf(NumberFormatException.class);
}

or to its message:

@Test
public void whenCheckingException_thenCauseMessageIsKnown() {
    Exception anException
      = new IllegalArgumentException("Bad value");

    assertThat(anException)
      .hasMessageThat()
      .startsWith("Bad");
}

5.11. Class Assertions

There’s only one important method for Class assertions with which we can test whether a class is assignable to another:

@Test
public void whenCheckingClass_thenIsAssignable() {
    Class<Double> aClass = Double.class;

    assertThat(aClass).isAssignableTo(Number.class);
}

6. Java 8 Assertions

Optional and Stream are the only two Java 8 types that Truth supports.

6.1. Optional Assertions

There are three important methods to verify an Optional.

We can test whether it has a particular value:

@Test
public void whenCheckingJavaOptional_thenHasValue() {
    Optional<Integer> anOptional = Optional.of(1);

    assertThat(anOptional).hasValue(1);
}

if the value is present:

@Test
public void whenCheckingJavaOptional_thenPresent() {
    Optional<String> anOptional = Optional.of("Baeldung");

    assertThat(anOptional).isPresent();
}

or if the value is not present:

@Test
public void whenCheckingJavaOptional_thenEmpty() {
    Optional anOptional = Optional.empty();

    assertThat(anOptional).isEmpty();
}

6.2. Stream Assertions

Assertions for a Stream are very similar to the ones for an Iterable.

For example, we can test if a particular Stream contains all objects of an Iterable in the same order:

@Test
public void whenCheckingStream_thenContainsInOrder() {
    Stream<Integer> anStream = Stream.of(1, 2, 3);

    assertThat(anStream)
      .containsAllOf(1, 2, 3)
      .inOrder();
}

For more examples, please refer to the Iterable Assertions section.

7. Guava Assertions

In this section, we’ll see examples of assertions for the supported Guava types in Truth.

7.1. Optional Assertions

There are also three important assertion methods for a Guava Optional. The hasValue() and isPresent() methods behave exactly as with a Java 8 Optional.

But instead of isEmpty() to assert that an Optional is not present, we use isAbsent():

@Test
public void whenCheckingGuavaOptional_thenIsAbsent() {
    Optional anOptional = Optional.absent();

    assertThat(anOptional).isAbsent();
}

7.2. Multimap Assertions

Multimap and standard Map assertions are very similar.

One notable difference is that we can get the multiple values of a key within a Multimap and make assertions on those values.

Here’s an example that tests if the values of the “one” key have a size of two:

@Test
public void whenCheckingGuavaMultimap_thenExpectedSize() {
    Multimap<String, Object> aMultimap = ArrayListMultimap.create();
    aMultimap.put("one", 1L);
    aMultimap.put("one", 2.0);

    assertThat(aMultimap)
      .valuesForKey("one")
      .hasSize(2);
}

For more examples, please refer to the Map Assertions section.

7.3. Multiset Assertions

Assertions for Multiset objects include the ones for an Iterable and one extra method to verify if a key has a particular number of occurrences:

@Test
public void whenCheckingGuavaMultiset_thenExpectedCount() {
    TreeMultiset<String> aMultiset = TreeMultiset.create();
    aMultiset.add("baeldung", 10);

    assertThat(aMultiset).hasCount("baeldung", 10);
}

7.4. Table Assertions

Besides checking its size or where it’s empty, we can check a Table to verify if it contains a particular mapping for a given row and column:

@Test
public void whenCheckingGuavaTable_thenContains() {
    Table<String, String, String> aTable = TreeBasedTable.create();
    aTable.put("firstRow", "firstColumn", "baeldung");

    assertThat(aTable).contains("firstRow", "firstColumn");
}

or if it contains a particular cell:

@Test
public void whenCheckingGuavaTable_thenContainsCell() {
    Table<String, String, String> aTable = getDummyGuavaTable();

    assertThat(aTable).containsCell("firstRow", "firstColumn", "baeldung");
}

Furthermore, we can check if it contains a given row, column, or value. See the source code for the relevant test cases.

8. Custom Failure Messages and Labels

When an assertion fails, Truth displays very readable messages denoting exactly what went wrong. However, sometimes is necessary to add more information to those messages to provide more details about what happened.

Truth allows us to customize those failure messages:

@Test
public void whenFailingAssertion_thenCustomMessage() {
    assertWithMessage("TEST-985: Secret user subject was NOT null!")
      .that(new User())
      .isNull();
}

After running the test, we get the following output:

TEST-985: Secret user subject was NOT null!:
  Not true that <com.baeldung.testing.truth.User@ae805d5e> is null

Also, we can add a custom label that gets displayed before our subject in error messages. This may come in handy when an object does not have a helpful string representation:

@Test
public void whenFailingAssertion_thenMessagePrefix() {
    User aUser = new User();

    assertThat(aUser)
      .named("User [%s]", aUser.getName())
      .isNull();
}

If we run the test, we can see the following output:

Not true that User [John Doe]
  (<com.baeldung.testing.truth.User@ae805d5e>) is null

9. Extensions

Extending Truth means we can add support for custom types. To do this, we need to create a class that:

  • extends the Subject class or one of its subclasses
  • defines a constructor that accepts two arguments – a FailureStrategy and an instance of our custom type
  • declares a field of SubjectFactory type, which Truth will use to create instances of our custom subject
  • implements a static assertThat() method that accepts our custom type
  • exposes our test assertion API

Now that we know how to extend Truth, let’s create a class that adds support for objects of type User:

public class UserSubject
  extends ComparableSubject<UserSubject, User> {

    private UserSubject(
      FailureStrategy failureStrategy, User target) {
        super(failureStrategy, target);
    }

    private static final
      SubjectFactory<UserSubject, User> USER_SUBJECT_FACTORY
      = new SubjectFactory<UserSubject, User>() {

        public UserSubject getSubject(
          FailureStrategy failureStrategy, User target) {
            return new UserSubject(failureStrategy, target);
        }
    };

    public static UserSubject assertThat(User user) {
        return Truth.assertAbout(USER_SUBJECT_FACTORY).that(user);
    }

    public void hasName(String name) {
        if (!actual().getName().equals(name)) {
            fail("has name", name);
        }
    }

    public void hasNameIgnoringCase(String name) {
        if (!actual().getName().equalsIgnoreCase(name)) {
            fail("has name ignoring case", name);
        }
    }

    public IterableSubject emails() {
        return Truth.assertThat(actual().getEmails());
    }
}

Now, we can statically import the assertThat() method of our custom subject and write some tests:

@Test
public void whenCheckingUser_thenHasName() {
    User aUser = new User();

    assertThat(aUser).hasName("John Doe");
}

@Test
public void whenCheckingUser_thenHasNameIgnoringCase() {
    // ...

    assertThat(aUser).hasNameIgnoringCase("john doe");
}

@Test
public void givenUser_whenCheckingEmails_thenExpectedSize() {
    // ...

    assertThat(aUser)
      .emails()
      .hasSize(2);
}

10. Conclusion

In this tutorial, we explored the possibilities Truth gives us to write more readable tests and failure messages.

We showcased the most popular assertion methods for supported Java and Guava types, customized failure messages, and extended Truth with custom subjects.

As always, complete source code for this article can be found over on Github.

Viewing all 3761 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>