How do I handle or avoid null value in Spring EL?

In this example you will learn how to avoid a null value, which causing a NullPointerException thrown in a Spring EL expression. To avoid this from happening we can use the null-safe accessor, using the ?. operator.

We are using the previous example, How do I inject bean’s property using Spring EL? classes, which are the Student class and the Grade class. What we need is to create a new spring configuration file to demonstrate this feature. So, here is the configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="student" class="org.kodejava.spring.core.el.Student">
        <property name="name" value="Alice" />
        <property name="grade" value="#{grade.getName()?.toUpperCase()}" />
    </bean>

    <bean id="grade" class="org.kodejava.spring.core.el.Grade">
        <property name="name">
            <null />
        </property>
        <property name="description" value="A beginner grade." />
    </bean>

</beans>

The use of null-safe accessor can be seen on the student bean’s grade property. We are calling the grade.getName() method and convert it to uppercase. We deliberately set the grade.name property to null. Calling toUpperCase on a null value will throw the NullPointerException. But because we are using the null-safe accessor the exception is not thrown, because the expression will not execute the code after the null-safe accessor. In this case when getName() return null, the toUpperCase() method will never get called.

Below is the demo program code:

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELNullSafeExpressionDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-null-safe.xml")) {

            Student student = (Student) context.getBean("student");
            System.out.println("Name  = " + student.getName());
            System.out.println("Grade = " + student.getGrade());
        }
    }
}

Here is the result of the code:

Name  = Alice
Grade = null

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I inject beans, properties and methods using Spring EL?

Using Spring Expression Language (SpEL) we can inject object references or values into a bean dynamically when the bean is created instead of statically defined at development time. In this example you’ll learn how to inject a bean’s property using a property of another bean.

Let start by create two classes, the Student and Grade classes. The student object will have a property to store their grade name which will be obtained from the grade object.

package org.kodejava.spring.core.el;

public class Student {
    private String name;
    private String grade;

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}
package org.kodejava.spring.core.el;

public class Grade {
    private String name;
    private String description;

    public Grade() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Next we create the spring configuration file. In this configuration we have two beans definition, the grade and student bean. We set the name and description property of the grade bean.

We also set the name property of student bean using a string literal. But the grade property value is set to the grade‘s bean name property using the Spring EL, #{grade.name}. The expression tells the spring container to look for a bean whose id is grade, read its name and assign it to student‘s grade.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="grade" class="org.kodejava.spring.core.el.Grade">
        <property name="name" value="Beginner" />
        <property name="description" value="A beginner grade." />
    </bean>
    <bean id="student" class="org.kodejava.spring.core.el.Student">
        <property name="name" value="Alice" />
        <property name="grade" value="#{grade.name}" />
    </bean>

</beans>

And then create the following program to execute the spring container and retrieve the student bean from it.

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-example.xml")) {

            Student student = (Student) context.getBean("student");
            System.out.println("Name  = " + student.getName());
            System.out.println("Grade = " + student.getGrade());
        }
    }
}

This program will print the following output:

Name  = Alice
Grade = Beginner

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I use PriorityBlockingQueue class?

This example demonstrate how to use the PriorityBlockingQueue class. The PriorityBlockingQueue is one implementation of the BlockingQueue interface. It is an unbounded concurrent queue. The object place in this type of queue must implement the java.lang.Comparable interface. The Comparable interface defines how the order priority of the elements inside this queue.

For simplicity, in this example we use strings object as the elements to be placed in the queue. The String class implements the comparable interface. Running this example will print out the names in the string array in alphabetical orders.

package org.kodejava.util.concurrent;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

public class PriorityBlockingQueueExample {
    public static void main(String[] args) {
        final String[] names =
                {"carol", "alice", "malory", "bob", "alex", "jacobs"};

        final BlockingQueue<String> queue = new PriorityBlockingQueue<>();

        new Thread(() -> {
            for (String name : names) {
                try {
                    queue.put(name);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer").start();

        new Thread(() -> {
            try {
                for (int i = 0; i < names.length; i++) {
                    System.out.println(queue.take());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Consumer").start();
    }
}

This code print out:

alex
alice
bob
carol
jacobs
malory

How do I use LinkedBlockingQueue class?

In the following code snippet you will learn how to use the LinkedBlockingQueue class. This class implements the BlockingQueue interface. We can create a bounded queue by specifying the queue capacity at the object construction. If we do not define the capacity, the upper bound is limited to the size of Integer.MAX_VALUE.

The data in the queue represented as a linked node in a FIFO (First-In-First-Out) order. The head element of the queue is the longest element placed in the queue and the tail element is the latest element added to the queue.

Let’s see the code in action below:

package org.kodejava.util.concurrent;

import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class LinkedBlockingQueueExample {
    public static void main(String[] args) {
        final BlockingQueue<String> queue = new LinkedBlockingQueue<>(1024);

        // Producer Tread
        new Thread(() -> {
            while (true) {
                try {
                    String data = UUID.randomUUID().toString();
                    System.out.printf("[%s] PUT [%s].%n",
                            Thread.currentThread().getName(), data);
                    queue.put(data);
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer").start();

        // Consumer-1 Thread
        new Thread(() -> {
            while (true) {
                try {
                    String data = queue.take();
                    System.out.printf("[%s] GET [%s].%n",
                            Thread.currentThread().getName(), data);
                    Thread.sleep(550);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer-1").start();

        // Consumer-2 Thread
        new Thread(() -> {
            while (true) {
                try {
                    String data = queue.take();
                    System.out.printf("[%s] GET [%s].%n",
                            Thread.currentThread().getName(), data);
                    Thread.sleep(750);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer-2").start();
    }
}

The output of the code snippet above:

[Producer] PUT [34418601-19cf-41fc-aecc-a0fa7caa72bb].
[Consumer-1] GET [34418601-19cf-41fc-aecc-a0fa7caa72bb].
[Producer] PUT [f2050eaa-c575-4faf-89e8-1ad0e3fbce0e].
[Consumer-2] GET [f2050eaa-c575-4faf-89e8-1ad0e3fbce0e].
[Producer] PUT [2f24985b-009b-44c3-9cec-7a066aa08ecf].
[Consumer-1] GET [2f24985b-009b-44c3-9cec-7a066aa08ecf].
[Producer] PUT [b4332823-c1a2-4587-bf5f-1f67407d6945].
[Consumer-2] GET [b4332823-c1a2-4587-bf5f-1f67407d6945].
[Producer] PUT [33edcd78-1b14-4913-afe2-7f44d76db50b].
[Consumer-1] GET [33edcd78-1b14-4913-afe2-7f44d76db50b].

How to implement queue using the DelayQueue?

The java.util.concurrent.DelayQueue class in an implementation of the BlockingQueue interface. Elements added to the queue must implement the java.util.concurrent.Delayed interface.

The queue is unbound in size, enabling adds to return immediately, we can only take an element from the queue when the delay time has expired. If multiple elements have expired delays, the element with the longest delay expiration will be taken first.

package org.kodejava.util.concurrent;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;

public class DelayQueueExample {
    public static void main(String[] args) {
        // Creates an instance of blocking queue using the DelayQueue.
        final BlockingQueue<DelayObject> queue = new DelayQueue<>();
        final Random random = new Random();

        new Thread(() -> {
            while (true) {
                try {
                    // Put some Delayed object into the Queue.
                    int delay = random.nextInt(10000);
                    DelayObject object = new DelayObject(
                            UUID.randomUUID().toString(), delay);

                    System.out.printf("Put object = %s%n", object);
                    queue.put(object);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer Thread").start();

        new Thread(() -> {
            while (true) {
                try {
                    // Take elements out from the DelayQueue object.
                    DelayObject object = queue.take();
                    System.out.printf("[%s] - Take object = %s%n",
                            Thread.currentThread().getName(), object);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer Thread-1").start();

        new Thread(() -> {
            while (true) {
                try {
                    // Take elements out from the DelayQueue object.
                    DelayObject object = queue.take();
                    System.out.printf("[%s] - Take object = %s%n",
                            Thread.currentThread().getName(), object);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer Thread-2").start();
    }
}

Below is an implementation of the Delayed interface. In the implementation class we have to implement the getDelay(TimeUnit) and the compareTo(Object) methods.

package org.kodejava.util.concurrent;

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayObject implements Delayed {
    private final String data;
    private final long startTime;

    public DelayObject(String data, long delay) {
        this.data = data;
        this.startTime = System.currentTimeMillis() + delay;
    }

    @Override
    public long getDelay(TimeUnit unit) {
        long diff = startTime - System.currentTimeMillis();
        return unit.convert(diff, TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return Long.compare(this.startTime, ((DelayObject) o).startTime);
    }

    @Override
    public String toString() {
        return "{" +
                "data='" + data + '\'' +
                ", startTime=" + startTime +
                '}';
    }
}

Running this example give you some kind of the following output:

Put object = {data='ff217d8f-30c7-4ff6-b107-f5e6b13b5cf1', startTime=1635830327667}
Put object = {data='ad9b7f64-04f6-45ba-8b4a-6d9d25785303', startTime=1635830326742}
Put object = {data='7e439219-486a-473f-b093-2ada26b682f4', startTime=1635830328540}
Put object = {data='1fd6f3d2-60b1-4986-a8d0-ceb0863b30a7', startTime=1635830328498}
[Consumer Thread-1] - Take object = {data='ad9b7f64-04f6-45ba-8b4a-6d9d25785303', startTime=1635830326742}
Put object = {data='9d8811a2-5f2a-487b-a229-11ad8ed54515', startTime=1635830330952}
Put object = {data='baf72a83-0242-42cb-93db-9ef08da5f78d', startTime=1635830336088}
[Consumer Thread-2] - Take object = {data='ff217d8f-30c7-4ff6-b107-f5e6b13b5cf1', startTime=1635830327667}
Put object = {data='9d4d14c5-0777-4675-aa67-a49a0519d9b2', startTime=1635830328952}
Put object = {data='c4979d10-4a11-44a8-b79c-ff31309e968b', startTime=1635830331430}