Injecting EJBs from JAR to WAR using CDI

Recently I faced a problem of how to use @Inject annotation in one of the CDI Beans. Our project has a following structure:

  • Business logic: JAR which packs EJB, JPA Entity Classes, …
  • User interface: WAR which packs CDI Beans, images, XHTMLs, …

Technically what I call JAR is actually EJB-JAR, because it packs EJBs, but EJB-JAR is really nothing more than a JAR archive, so let’s call it JAR for simplicity. WAR is responsible for user interface and uses JAR for business logic. So far a pretty standard architecture.

Both JAR and WAR are deployed separately and running on JBoss AS 7.1 (released in 2012, after this JBoss AS was renamed to Wildfly). Our client uses this version, so we have to work with what we have, but overly it’s not a problem.

To use business logic from the JAR we need access to our EJBs which implements it. Our CDI Beans in WAR looks like this:

@Model annotation is a built-in stereotype (stereotype is annotation that incorporates other annotations) from CDI. It’s for beans that are intended for the model component of the MVC pattern which needs multiple annotation that you don’t want to list every time (readability and laziness). Then we use @Inject for dependency injection of EJB named TestSessionEJBLocal which lays in JAR. For those who are at least familiar with CDI it must look pretty simple.

But after deployment we got following error:

What the error said? Well, that Weld (Weld is the reference implementation of CDI) couldn’t inject TestSessionEJBLocal to injection point cz.pfreiberg.test.view.portlet.ViewPortlet.testBean. We couldn’t use Weld for injection, it’s simply didn’t see JAR classes from WAR. Other variant was to use only manual JNDI lookup, but I really wanted to use @Inject for dependency injection.

So after a lot of research (special thanks go to Martin Polák), probably the only viable solution is to use separate class (EJBProducer), which uses CDI @Produces annotation and hides JNDI lookup. This class lays in WAR.

Method with @Produces annotation is used every time when you need the type which returning. You can have only one method for one type otherwise error will be thrown during deployment phase. The only problem which remains is that you still have to write JNDI for each bean separately.

Now you can @Inject classes from another deployment.

Leave a Reply

Your email address will not be published.