adam bien's blog

Simplest Possible EJB 3.1 + JSR-299/JSR-330 Combination 📎

 JSR-299 / JSR-330 beans can be easily combined with EJB 3.1 without any friction. The @Stateless bean:

 @Path("message")

@Stateless

public class ServiceFacade {

    @Inject @Message(Say.GOOD_BYE) MessageService message;

    @Inject DateService dateService;

    @GET public String getMessage(){

      return message.getMessage() + " " + dateService.getCurrentTime();

    }

is exposed via JSR-311 (REST) and a @GET method in particular. Two others JSR-299 beans are directly injected to the @Stateless instance. The CurrentDateService is just a class, which implements the interface DateService, without any additional annotations or configuration:

public class CurrentDateService implements DateService{

  public Date getCurrentTime(){

        return new Date();

    }

The only implementation of the interface is injected with the @Inject annotation. It only works in case there is only one implementation of a particular interface (just like the @EJB annotation).  The MessageService has two implementations - so a particular implementation has to be qualified. A custom annotation Message is used for this purpose:

@Qualifier

@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

public @interface Message {

    enum Say{

        HELLO, GOOD_BYE

   }

    Say value();

Every injectable implementation of the interface has to be annotated as well:

@Message(Message.Say.GOOD_BYE)

public class GoodByeMessageService implements MessageService{

    public String getMessage() {

        return "Good Bye";

    }

 

EJB 3.1 are still the easiest possible choice for the implementation of services / boundaries. Convention over configuration makes any configuration really optional, and the default aspects like transactions, concurrency and request scope kill the superfluous bloat. JSR-299/JSR-330 DI exceed the EJB injection capabilities - both can be nicely combined. 

The working project with source was packaged as a WAR (EJB31AndJSR299.war with the size of 16kB) and pushed into: http://kenai.com/projects/javaee-patterns/. To make the enhanced injection work, you will have to create a configuration file beans.xml located in WEB-INF with the content <beans></beans>. This actually pollutes the cleanness and conciseness of EJB 3.1, so I opened an issue :-). 

An average deployment took < 300 ms. The project was tested with NetBeans 6.8 RC 1 and bundled Glassfish v3 b73.

[See also Dependency Injection Extender pattern, page 231 in "Real World Java EE Patterns Rethinking Best Practices" book for more in-depth discussion]