Q:

Correct CDI annotations with Jersey/Glassfish

Since I'm struggling on documentation about CDI, I hope this question could become a useful resource for the correct CDI annotations to use in Jersey/Glassfish.
Say we have an application BookStore:
package my.bookstore;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("/bookstore")
public class BookStore extends ResourceConfig {
    public BookStore() {
        this.packages("my.bookstore.resource");
    }
}

We want to make Book entities accessible via a RESTful service:
package my.bookstore.entity;

public class Book {
    public String isbn;
    public String title;
    public String author;

    public Book(String isbn, String title, String author) {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
    }
}

So we need a DAO to access the datastore:
package my.bookstore.dao;

import my.bookstore.entity.Book;
import java.util.List;

public interface BookDAO {
    public List<Book> getAllBooks();
}

And its implementation:
package my.bookstore.dao;

import my.bookstore.entity.Book;
import java.util.List;
import java.util.ArrayList;

public class DefaultBookDAO implements BookDAO {
    public List<Book> getAllBooks() {
        List<Book> bookList = new ArrayList<>();
        list.add(new Book("1234", "Awesome Book", "Some Author"));
        return bookList;
     }
}

Then I want to inject the DefaultBookDAO into the RESTful service:
package my.bookstore.resource;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/books")
public class BookResource {

   @Inject
   BookDAO dao;

   @GET
   @Produces(MediaType.APPLICATION_JSON)
   public List<Book> getBooks() {
       return this.dao.getAllBooks();
   }
}

Now, when deploying the application I get:
Unsatisfied dependencies for type BookDAO with qualifiers @Default

since I need to make CDI aware of it; but how? I tried various combinations of @Named, @Default, @Model, @Singleton, @Stateless and many resources such as questions and blog articles have they own interpretation of them.
What are the correct, plain CDI annotation to use to make this injection work in Jersey/Glassfish?

A:

To me, it seems that you did not put beans.xml file into your application. With Glassfish 4 (generally with Java EE 7) this file is not required, however, if you omit it, only beans annotated with scope annotations are considered. Therefore, as DefaultBookDAO is not marked by any annotation, it is not considered by CDI as a candidate for injection.
You have 2 options to fix it and make CDI mechanism consider DefaultBookDAO:

put @Dependent annotation on DefaultBookDAO class - this will not change its scope, as @Dependent is the default scope, but will make CDI to consider this class
create beans.xml file in either META-INF or WEB-INF (for web apps) with the value of bean-discovery-mode="all"

In my opinion, the first option is cleaner - you may easily separate code which can be injected and which cannot. But if you want to increase productivity by omitting unnecessary annotations, go with the second option. It is more complicated, but you have to do it only once per module.
Please see this oracle blog post about beans.xml in Java EE 7 and the default behavior if it is omitted.

