Do not use AllArgsConstructor in your public API

Introduction

Do you think about compatibility of your public API when you modify classes from it? It is especially easy to miss out that something incompatibly changed when you are using Lombok. If you use AllArgsConstructor annotation it will cause many problems.

What is the problem?

Let's define simple class with AllArgsConstructor:
@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}
Now we can use generated constructor in spock test:
def 'use generated allArgsConstructor'() {
    when:
        Person p = new Person('John', 'Smith', 30)
    then:
        with(p) {
            firstName == 'John'
            lastName == 'Smith'
            age == 30
        }
}
And the test is green. Let's add new optional field to our Person class - email:
@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
    private String email;
}
Adding optional field is considered compatible change. But our test fails...
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: com.github.alien11689.allargsconstructor.Person(java.lang.String, java.lang.String, java.lang.Integer)

How to solve this problem?

After adding field add previous constructor

If you still want to use AllArgsConstructor you have to ensure compatibility by adding previous version of constructor on your own:
@Data
@AllArgsConstructor
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
    private String email;

    public Person(String firstName, String lastName, Integer age) {
        this(firstName, lastName, age, null);
    }
}
And now our test again passes.

Annotation lombok.Data is enough

If you use only Data annotation, then constructor, with only mandatory (final) fields, will be generated. It is because Data implies RequiredArgsConstructor:
@Data
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}
class PersonTest extends Specification {
    def 'use generated requiredFieldConstructor'() {
        when:
            Person p = new Person('John', 'Smith')
            p.age = 30
        then:
            with(p) {
                firstName == 'John'
                lastName == 'Smith'
                age == 30
            }
    }
}
After adding new field email test still passes.

Use Builder annotation

Annotation Builder generates for us PersonBuilder class which helps us create new Person:
@Data
@Builder
public class Person {
    private final String firstName;
    private final String lastName;
    private Integer age;
}
class PersonTest extends Specification {
    def 'use builder'() {
        when:
            Person p = Person.builder()
                    .firstName('John')
                    .lastName('Smith')
                    .age(30).build()
        then:
            with(p) {
                firstName == 'John'
                lastName == 'Smith'
                age == 30
            }
    }
}
After adding email field test still passes.

Conclusion

If you use AllArgsConstructor you have to be sure what are you doing and know issues related to its compatibility. In my opinion the best option is not to use this annotation at all and instead stay with Data or Builder annotation. Sources are available here.

Primitives and its wrapped types compatibility

Introduction

How often do you think about possible changes in your API? Do you consider that something required could become optional in future? How about compatibility of such change? One of this changes is going from primitive (e. g. int) to its wrapped type (e. g. Integer). Let's check it out.

API - first iteration

Let's start with simple DTO class Dep in our public API.

public class Dep {
    private int f1;

    public int getF1(){
        return f1;
    }

    public void setF1(int f1){
        this.f1 = f1;
    }

    // other fields and methods omitted
}

f1 is obligatory field that never will be null.

Let's use it in Main class:

public class Main {
    public static void main(String... args) {
        Dep dep = new Dep();
        dep.setF1(123);
        System.out.println(dep.getF1());
    }
}

compile it:

$ javac depInt/Dep.java
$ javac -cp depInt main/Main.java

and run:

$ java -cp depInt:main Main
123

It works.

API - obligatory field become optional

Now suppose our business requirements have changed. f1 is not longer obligatory and we want possibility to set it to null.

So we provide next iteration of Dep class where f1 field has type Integer.

public class Dep {
    private Integer f1;

    public Integer getF1(){
        return f1;
    }

    public void setF1(Integer f1){
        this.f1 = f1;
    }

    // other fields and methods omitted
}

We compile only the new Dep class because we do not want to change the Main class:

$ javac depInteger/Dep.java

and run it with old Main:

$ java -cp depInteger:main Main
Exception in thread "main" java.lang.NoSuchMethodError: Dep.setF1(I)V
    at Main.main(Main.java:4)

Wow! It does not work...

Why does it not work?

We can use javap tool to investigate Main class.

$ javap -c main/Main.class
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class Dep
       3: dup
       4: invokespecial #3                  // Method Dep."<init>":()V
       7: astore_1
       8: aload_1
       9: bipush        123
      11: invokevirtual #4                  // Method Dep.setF1:(I)V
      14: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: aload_1
      18: invokevirtual #6                  // Method Dep.getF1:()I
      21: invokevirtual #7                  // Method java/io/PrintStream.println:(I)V
      24: return
}

The most important are 11th and 18th instructions of main method. Main lookups for methods which use int (I in method signature).

Next let's compile the Main class with Dep which has f1 of type Integer:

$ javac -cp depInteger main/Main.java

and use javap on this class:

$ javap -c main/Main.class
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class Dep
       3: dup
       4: invokespecial #3                  // Method Dep."<init>":()V
       7: astore_1
       8: aload_1
       9: bipush        123
      11: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      14: invokevirtual #5                  // Method Dep.setF1:(Ljava/lang/Integer;)V
      17: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      20: aload_1
      21: invokevirtual #7                  // Method Dep.getF1:()Ljava/lang/Integer;
      24: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      27: return
}

Now we see the difference. The main method:

  • converts int to Integer in instruction 11th,
  • invokes method setF1 which takes parameter of type Integer (Ljava/lang/Integer;) in instruction 14th,
  • invokes method getF1 which returns Integer in instruction 21st.

These differences do not allow us to use the Main class with Dep without recompilation if we change f1.

How about Groovy?

We have GroovyMain class which do the same as Main class written in Java.

class GroovyMain {
    static void main(String... args) {
        Dep dep = new Dep(f1: 123)
        println(dep.f1)
    }
}

We will compile GroovyMain class only with Dep which uses int:

$ groovyc -cp lib/groovy-all-2.4.5.jar:depInt -d main main/GroovyMain.groovy

It runs great as expected with int:

$ java -cp lib/groovy-all-2.4.5.jar:depInt:main GroovyMain
123

but with Integer... It works the same!

$ java -cp lib/groovy-all-2.4.5.jar:depInteger:main GroovyMain
123

Groovy is immune to such change.

With CompileStatic

But what if we compile groovy with CompileStatic annotation? This annotation instructs groovy compiler to compile class with type checking and should produce bytecode similar to javac output.

GroovyMainCompileStatic class is GroovyMain class with only CompileStatic annotation:

import groovy.transform.CompileStatic

@CompileStatic
class GroovyMainCompileStatic {
    static void main(String... args) {
        Dep dep = new Dep(f1: 123)
        println(dep.f1)
    }
}

When we compile this with Dep with int field:

$ groovyc -cp lib/groovy-all-2.4.5.jar:depInt -d main main/GroovyMainCompileStatic.groovy

then of course it works:

$ java -cp lib/groovy-all-2.4.5.jar:depInt:main GroovyMainCompileStatic
123

but with Dep with Integer field it fails like in Java:

$ java -cp lib/groovy-all-2.4.5.jar:depInteger:main GroovyMainCompileStatic
Exception in thread "main" java.lang.NoSuchMethodError: Dep.setF1(I)V
    at GroovyMainCompileStatic.main(GroovyMainCompileStatic.groovy:6)

Conclusion

Change from primitive to its wrapped java type is not compatible change. Bytecode which uses dependent class assumes that there will be method which consumes or returns e. g. int and cannot deal with the same class which provides such method with Integer in place of int.

Groovy is much more flexible and could handle it, but only if we do not use CompileStatic annotation.

The source code is available here.

Scheduling tasks using Message Queue

Introduction

How to schedule your task for later execution? You often create table in database, configure job that checks if due time of any task occured and then execute it.

But there is easier way if only you have message broker with your application... You could publish/send your message and tell it that it should be delivered with specified delay.

Scheduling messages using ActiveMQ

ActiveMQ is open source message broker written in Java. It is implementation of JMS (Java Message Service).

You could start its broker with scheduling support by adding flag schedulerSupport to broker configuration:

<beans ...>
...
<broker xmlns="http://activemq.apache.org/schema/core"
brokerName="localhost"
dataDirectory="${activemq.data}"
schedulerSupport="true">
...
</broker>
...
</beans>

Now, if you want to delay receiving message by few seconds, you could add property during message creation, e.g.:

message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 8000)

Delay unit is miliseconds.

Of course queue must be persisted.

When you listen for message on the same queue, then you will see that message indeed will be received with 8 second delay.

...
Send time: Tue Dec 01 18:51:23 CET 2015
...
Message received at Tue Dec 01 18:51:31 CET 2015
...

Scheduling messages using RabbitMQ

Scheduling tasks is not only the feature of ActiveMQ. It is also available with RabbitMQ.

RabitMQ is message broker written in Erlang. It uses protocol AMQP.

First you have to install plugin rabbitmq_delayed_message_exchange. It could be done via command:

rabbitmq-plugins enable --offline rabbitmq_delayed_message_exchange

You have to define exchange in RabbitMQ which will use features from this plugin. Queue for delayed messages should be bound to this exchange. Routing key should be set to queue name.

channel.exchangeDeclare(exchange, 'x-delayed-message', true, false, ['x-delayed-type': 'direct']);
channel.queueBind(queue, exchange, queue);
channel.queueDeclare(queue, true, false, false, null);

Of course queue must be persisted.

To test it just publish new message with property x-delay:

channel.basicPublish(exchange,
queue,
new AMQP.BasicProperties.Builder().headers('x-delay': 8000).build(),
"Message: $currentUuid".bytes)

Message will be delayed with 8 seconds:

...
Send time: Tue Dec 01 19:04:18 CET 2015
...
Message received at Tue Dec 01 19:04:26 CET 2015
...

Conclusion

Why you create similar mechanism for handling scheduled tasks on your own, when you could use your message brokers and delayed messages to schedule future tasks?

Sources are available here.

How to recover after Hibernate’s OptimisticLockException

I've read many articles about optimistic locking and OptimisticLockException itself. Problem is that each one of them ended up getting their first exception and no word on recovery. What to do next? Repeat? If so, how? Or drop it? Is there any chance to continue? How? Even more, documentation says that if you get Hibernate exception - you're done, it's not recoverable:

An exception thrown by Hibernate means you have to rollback your database transaction and close the Session immediately (this is discussed in more detail later in the chapter). If your Session is bound to the application, you have to stop the application. Rolling back the database transaction does not put your business objects back into the state they were at the start of the transaction. This means that the database state and the business objects will be out of sync. Usually this is not a problem, because exceptions are not recoverable and you will have to start over after rollback anyway.

Here is my attempt on this: repeatable and recoverable.

Business case

Let's say we have distributed application with two web servers, connected to the same database. Applications use optimistic locking to avoid collisions. Customers buy lottery coupons, which are numbered from 1 to 100. In the same second Alice on web server 1 draws two coupons: 11 and 12. In the same moment Bob reserves two coupons on web server 2. It draws 11 and 13 for Bob and tries to write it back to database. But it fails, since Alice's commit was first. I want a web application server to draw coupons for Bob again and then - try to save again until it succeeds.

Solution

For every request Hibernate associates different Session that is flushed at the end of request processing. If you hit OptimisticLockException then this Request Session is polluted and will be rolled back. To avoid this we will create a separate Hibernate's Session especially for drawing coupons. If separate session fails - drop this session and try again in a new one. If it succeeds - merge it with a main request session. Request Session cannot be touched during draws. Take a look at the following picture:

On this picture yellow and green short-term sessions has failed with OptimisticLockException. Red session was successful and these objects are merged to a main session on the left.

Reservation entity

Key requirement here is to keep a domain you want to lock on as small as possible and not coupled directly to anything else. Best approach here is to create some Reservation entity with few fields, let's say: couponId and customerId. For each Coupon create one Reservation row and use reserved boolean field as a reservation status. For coupon and customer use weak identifiers (long) instead of real entities. This way no object tree will be loaded and Reservation stays decoupled.

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

import static org.apache.commons.lang3.Validate.isTrue;
import static org.springframework.util.Assert.isNull;

@Getter
@Setter
@ToString
@Entity
public class Reservation {
@Id
private long id;
@Column("coupon_id")
private long couponId;
@Column("customer_id")
private Long customerId;
@Column("is_reserved")
private boolean reserved;

public void reserve(long reservingCustomerId) {
isTrue(reserved == false);
isNull(customerId);
reserved = true;
customerId = reservingCustomerId;
}
}

Method reserve has some business assertions to keep it legit. You can also spot lombok's annotations that provide getters, setters and toString methods on the fly.

Reservation Service

Reservation Service implements my solution. I've commented some steps for better reading. Please read a source code:

import lombok.extern.slf4j.Slf4j;
import org.hibernate.*;
import org.hibernate.ejb.HibernateEntityManager;
import org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException;

import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceContext;
import java.util.List;

@Slf4j
public class ReservationService {

@PersistenceContext
private HibernateEntityManager hibernateEntityManager;

@SuppressWarnings("uncheked")
private Iterable<Reservation> reserveOptimistic(long customerId, final int count) throws NoFreeReservationsException {
log.info("Trying to reserve {} reservations for customer {}", count, customerId);

//This is the request session that needs to stay clean
Session currentSession = hibernateEntityManager.getSession();
Iterable<Reservation> reserved = null;

do {
//This is our temporary session to work on
Session newSession = hibernateEntityManager.getSession().getSessionFactory().openSession();
newSession.setFlushMode(FlushMode.COMMIT);
Transaction transaction = newSession.beginTransaction();

List<Reservation> availableReservations = null;

try {
Query query = newSession.createQuery("from Reservation r where r.reserved = false")
.setLockMode("optimistic", LockMode.OPTIMISTIC)
.setMaxResults(count);

availableReservations = query.list();

//There is no available reservations to reserve
if (availableReservations.isEmpty()) {
throw new NoFreeReservationsException();
}

for (Reservation available : availableReservations) {
available.reserve(customerId);
newSession.save(available);
}

//Commit can throw optimistic lock exception if it fails
transaction.commit();

//Commit succeeded - this reference is used outside try-catch-finally block
reserved = availableReservations;

} catch (OptimisticLockException | StaleObjectStateException | HibernateOptimisticLockingFailureException e) {
log.info("Optimistic lock exception occurred for customer {} and count {}: {} {}", customerId, count, e.getClass(), e.getMessage());

transaction.rollback();

for (Reservation availableMsisdn : availableReservations) {
newSession.evict(availableMsisdn);
}
} finally {
newSession.close();
}
//Repeat until we reserve something
} while (reserved == null);

log.info("Successfully reserved {} reservations for customer {}", count, customerId);

//Merge reserved entities to request session
for (Reservation reservedMsisdn : reserved) {
currentSession.merge(reservedMsisdn);
}

return reserved;
}
}

This code says it all. It tries to reserve some Reservations until it succeeds in a do-while loop. Main Request Session is not polluted and it achieves our goal.

I hope this example helps you in similar some cases. It works as expected for a few months on our customer's production site and I recommend this solution.

What’s the cause of your problem?

Most of exceptions has a few constructors including those with cause exception. But what if you have to throw an exception that has no cause in constructor? You try to survive:

 Exception cause = new Exception("I'm the cause!");
 SSLHandshakeException noCauseExc = new SSLHandshakeException(String.format("SSL problem: [%s]", cause.getMessage()));
 noCauseExc.printStackTrace();
...and you lose stacktrace which is crucial! There's a solution Throwable::initCause(). Check this code and have cause tailed to your exception

import javax.net.ssl.SSLHandshakeException;

/**
 * Created by bartek on 04.09.15.
 */
public class Cause  {

    public static void main(String[] args) {

        Exception cause = new Exception("I'm the cause!");
        SSLHandshakeException noCauseExc = new SSLHandshakeException(String.format("SSL problem: [%s]", cause.getMessage()));
        noCauseExc.printStackTrace();

        SSLHandshakeException withCauseExc = new SSLHandshakeException("Another SSL problem");
        withCauseExc.initCause(cause);
        withCauseExc.printStackTrace();
    }
}

Spring Boot and AngularJS quick start

In this post I am going to show very simple and quick example of web application using Spring Boot with AngularJS. This app contains simple functionality of sending and storing imaginary messages. I've also used gradle for build management. All code is public and it is available on my github: https://github.com/rafalnowak/spring-boot-fun

Introduction to Spring Boot

Spring Boot is quite new project created under Spring Source umbrella. It was very few months ago when it reached version 1.0 and status of general availability.
Most important and prominent goals of this projects are:
  • providing ability to create simple web apps very quickly
  • minimizing amount of XML codebloat which is usually necessary to configure every Spring application
  • most of app configuration is automatical
  • simplify running and deployment process by using embedded Tomcat or Jetty servers that can run our applications without special effort and deploy process
  • there are lot of so called spring boot starters which are packages containing default configuration for various fields of Spring like database access by JPA, aspect oriented programming or security
As we can see, it looks promising. In this post I'll show few basic steps necessary to create and boot simple Spring Boot web application.

First steps

Although Spring Boot can be used with special command line interface tools, I've decided to use it with very popular gradle build system.
Spring Boot comes with plugins to integrate with maven or gradle. They allow us to easily run application in embedded server. Necessary instructions to include these plugin are shown on snippet below:
buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.1.RELEASE")
    }
}
With this basic config we can proceed to next steps. In my sample project I've divided application into two modules: one contains persistence layer with domain object and JPA repositories and another contains presentation layer with controllers. Of course this completely optional and in such simple project it does not add any benefits. But it can show how to create multi module project in gradle. Next code fragment contains common configuration for all modules in our gradle build:
allprojects {
    apply plugin: "java"

    version = '1.0-SNAPSHOT'
    group = "info.rnowak.springBootFun"

    repositories {
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        compile "org.springframework.boot:spring-boot-starter-test:1.0.1.RELEASE"
        compile "com.google.guava:guava:16.0.1"
        compile "com.h2database:h2:1.3.175"

        testCompile "junit:junit:4.11"
        testCompile "org.mockito:mockito-all:1.9.5"
        testCompile "org.assertj:assertj-core:1.5.0"
    }
}
Now when we have common configuration, we can declare basic modules of application:
project(":persistence") {
    dependencies {
        compile "org.springframework.boot:spring-boot-starter-data-jpa:1.0.1.RELEASE"

        testCompile project(":webapp")
    }
}

project(":webapp") {
    apply plugin: "spring-boot"

    dependencies {
        compile project(":persistence")
        compile "org.springframework.boot:spring-boot-starter-web:1.0.1.RELEASE"
    }
}
Most important parts are including special Spring Boot Starter packages and declaring usage of spring-boot plugin in one of subprojects.
Every starter packet contains dependencies for all necessary libraries used on given feature. For example, JPA starter has Hibernate dependencies and AOP starter contains spring-aop and AspectJ libraries. What is more, with this libraries Spring Boot provides also default configuration.
It is simple quick start configuration but it is enough for some starter applications.

Let's start fun with Spring!

Our next step should be creating of starting point of application. With Spring Boot it can be done by writing regular main method in some class. Now you only need to annotate this class with special Spring Boot auto configuration annotations and application is ready to run! Example of start class is shown below:
package info.rnowak.springFun;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class SpringFun {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(SpringFun.class);
        app.setShowBanner(false);
        app.run(args);
    }
}
Well, this step look simple but it has few interesting implications for all application.
Firstly, this class enables component scan for Spring managed beans with root package info.rnowak.springFun because it is placed in this package.
Another thing is that this main method allows to run application using command gradle run. By default it uses embedded Tomcat running on port 8080. Of course this behaviour can be changed and it is very well described in project documentation. It is also possible to create runnable jar from our application.
With main class defined we can create all other classes in our application like controllers, repositories, domain classes or services. But I won't show exact examples of such classes because they do not differ in any way from the same classes in old classic Spring. If you are interesed in my example, please take a look at the repository Spring Boot Fun repo.

Add some AngularJS

One of another "side effect" of Spring Boot main configuration class is that we get few default view resolvers. View resolver, in short version, is Spring feature, which maps names of view to specific view files.
Spring Boot with its default configuration sets lookup path for index.html file which will be served by default controller. Framework looks for this file in public/, webapp/ or resources/ directory on classpath. So you can just put index.html file in one of these locations and Spring Boot will create controller serving this view. And this is the way we can use AngularJS in our project. Of course it's not the only way but it is the simplest method for using AngularJS with Spring Boot application.
In our example application index.html file was placed in webapp/ directory and it looks like this:
<!DOCTYPE html>

<html ng-app="springFun">

<head>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.4/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.4/angular-route.min.js"></script>
    <script src="js/application.js"></script>
    <script src="js/controllers.js"></script>
</head>

<body>

    <nav class="navbar navbar-default" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#/index">Spring Boot Fun</a>
            </div>
            <div class="collapse navbar-collapse">
                <ul class="nav navbar-nav">
                    <li><a href="#/list">Messages list</a></li>
                    <li><a href="#/about">About</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <div ng-view></div>

    <footer class="text-center">
        Spring Boot Fun
    </footer>

</body>

</html>
This file includes all angular libraries used in project, controllers definition and main application module with routing defined.
The rest of files is available in repository mentioned earlier in post so I will not provide all listings here as it would be just waste of virtual space in post :)

Summary

As we can see, Spring Boot greatly decreases time needed to write and run simple Java web application. It reduces amount of XML configuration and provieds a lot of default values and conventions. But if we want to precisely set some settings, Spring Boot does not forbid it and programmer can manually set all the settings.
Also deploy of application is simplified because Spring Boot with gradle or maven plugin allows to run application in place with these tools. We can also create runnable jar that contains embedded Tomcat or Jetty. And if it is not desired by us, we can always use war plugin and create regular, traditional war and deploy it in classical way.
Spring Boot has also great documentation and I strongly encourage to read it by everybody interested in this tool: Spring Boot Docs