Inject a stateless EJB with @Inject into CDI Weld ManagedBean (JSF 1.2 EJB Application on jboss 6 AS)
Asked Answered
P

3

7

Currently I am trying to inject a stateless EJB into a CDI managed controller on Jboss 6 AS Final. The controller is managed in the context an accessible from the JSF pages. If I inject the stateless bean with @EJB it is working. If I inject the stateless EJB with @Inject I get the following Exception:

My controller:

@Named("TestController")
public class TestController {   
    @Inject
    private TestManagerLocal myTestManager;
        ...
    }
}

My stateless bean:

@SuppressWarnings("unchecked")
@Stateless
public class TestManagerBean implements TestManagerLocal {

    @PersistenceContext
    private EntityManager em;
        ...
}

The Interface of the Bean is annotated with @Local.

If I try to call myTestManager I get the following exception:

WELD-000079 Could not find the EJB in JNDI: class de.crud.org$jboss$weld$bean-jboss$classloader:id="vfs:$$$usr$local$jboss$server$default$deploy$test$ear"-SessionBean-TestManagerBean_$$_WeldProxy

THX a lot.

Postobit answered 20/2, 2011 at 21:50 Comment(0)
P
2

The problem was, that I built and deployed my application as an ear. Weld is working when I deploy my application as an war including all EJBs.

Postobit answered 22/2, 2011 at 23:9 Comment(0)
M
9

For those not having the luxury to change an ear to a war, I've found the following workaround:

  • Create an EJB in the war
  • Inject that EJB with the EJBs from the EJB module
  • Add CDI producer methods
  • Qualify @Inject with the qualifier for those producer methods:

Code:

// This bean is defined in the WEB module
@Stateless
public class EJBFactory {

    @EJB
    protected UserDAO userDAO;

    // ~X other EJBs injected here


    @Produces @EJBBean
    public UserDAO getUserDAO() {
        return userDAO;
    }

    // ~X other producer methods here
}

Now EJBs from anywhere in the EAR can be injected with:

// This bean is also defined in the web module
@RequestScoped
public class MyBean {

    @Inject @EJBBean
    private UserDAO userDAO; // injection works

    public void test() {
        userDao.getByID(...); // works
    }

}

EJBBean is a simple standard qualifier annotation. For completeness, here it is:

@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface EJBBean {

}
Mccallion answered 18/4, 2011 at 20:2 Comment(2)
Is it necessary to annotate EJBFactory as @Stateless for this to work?Crinoid
Yes, EJBFactory needs to be a session bean. The thing is that EJB beans defined in the war (either message driven or session ones) can be normally injected with EJB beans defined in the EJB module. Since the factory needs to grab the beans from somewhere, this is a good place. Alternatively, you could not annotate the factory with stateless and have a second bean that you do annotate and inject with the EJB module beans. Then you @Inject this second bean into the factory, and let the factory get the required beans from it. But just combining the two concepts seems much easier.Mccallion
P
2

The problem was, that I built and deployed my application as an ear. Weld is working when I deploy my application as an war including all EJBs.

Postobit answered 22/2, 2011 at 23:9 Comment(0)
O
2

Currently there are various problems arising from the fact that WARs in EAR-Deployments don't share the same classloader. See https://issues.jboss.org/browse/JBAS-8683 for the ongoing discussion in the JBoss-AS JIRA (and vote it up :-) )

UPDATE I found this information on how to disable separate classloaders, option 1 worked for me, but be extremely careful with this. The separation of classloaders hasn't been introduced for no reason, so apparently there are new problems on the road ahead...

Origen answered 19/4, 2011 at 5:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.