JUnit’s ExpectedException @Rule

Some time ago I had written a post about different ways to deal with exceptions using JUnit. It’s time to augment that post with a truly great way to achieve the same result.

Let’s look at this through an example. The task will be to implement a little method for an insurance company that registers a car to be insured by its license plate number. In Hungary, license plates follow the LLL-DDD pattern, where L stands for an uppercase letter, while D is a digit from 0 to 9. The initial requirement is simple: validate whether the input string conforms to the pattern described above; if it does, save it, else, throw an IllegalArgument exception. Continue reading “JUnit’s ExpectedException @Rule”

EJB Dependency injection misunderstandings

When I’m doing interviews, I like to ask the following question (provided that the candidate has real life experience with EJBs):

There are two stateless session beans, A and B. A has a dependency on B; at what point can bean A use its injected (@EJB) dependency?

This turns out to be a tough question, as most people get it wrong. I’ve already heard a load of answers, but the most common ones are these: “anywhere if we use constructor injection”, “in the body of the business methods” and “the body of the constructor” (this is the most common one, actually). Let’s see how it really is, and why these answers are not (entirely) correct.

1.) Anywhere with constructor injection: Constructor injection is not possible with EJBs only; it is only available in JavaEE if you enable CDI (put an empty beans.xml file in your META-INF directory). That  is, however, a different story, so let’s skip CDI for this post. This means that we are left with enterprise beans only (@EJB injection style), in which case the following code will not work; it will not even compile, as the @EJB annotation is disallowed for constructors:

@EJB
public EjbA(EjbB ejbB) {
  this.ejbB = ejbB;
  // ...
}

public void doSomeWork() {
  ejbB.calculate();
  // ...
}

2.) In the body of a business method: Strictly speaking, this answer is not entirely wrong. Dependency injection would be completely useless if it was not available for business methods, so, this code will just work fine:

@EJB
private EjbB ejbB;

public EjbA() {
  // ...
}

public void doBusiness() {
  ejbB.calculate();
 // ...
}

Although this code is functional, the answer cannot be considered a good one, since a business method is not our earliest possibility to work with injected dependencies.

3.) The body of the constructor: let’s take an example. Consider the following code:

@EJB
private EjbB ejbB;

public EjbA() {
  ejbB.calculate();
}

Usually it is a bad idea to place any work in the constructor, but this is never truer than in our case. Surprise, this piece of code will not work, but throw a NullPointerException upon deployment. Why? Let’s see how EJBs are created by the container.

The EJB 3.1 specification mandates that every EJB has a public, default constructor (again, when CDI comes into play, this requirement is relaxed, but that’s a different story). The specification requires some pooling logic is present for Stateless and Message Driven Beans, (some containers will also pool Stateful beans too – even though it’s not required by the spec), so instances have to be created to populate the bean pool. In order to achieve that, the container reflectively calls the public, default constructor. By the time the constructor has completed, there is nothing injected into the EJB. From DI perspective, at this point our EjbA bean is just a simple, normal Java object, and its state is the very same as it would have been if we had instantiated it using the new operator.

As soon as the construction is complete, the magic kicks in and the container starts injecting all the dependencies the EJB has. After that process is finished, a construction finished event is fired; if the bean is registered for this event -e.g. it has defined a @PostConstruct method -, the container will call this method, which turns out to be the very first point in the lifecycle of an EJB, where any of the injected EJBs are available.

In short, the @PostConstruct lifecycle callback method is the answer to the question. That is the first point where EJB B will be available to EJB A. Trying to reference those dependencies any sooner will result in a NullPointerException.