Search code examples
jsfejbcode-injectionmanaged-bean

Inject EJB bean from JSF managed bean programmatically


I have EJB stateless bean.
How can I inject it to JSF managed bean by programmatic instead of @EJB annotation?


Solution

  • You can't inject it programmatically. You can however obtain it programmatically. EJBs are also available via JNDI. Usually, you find those JNDI names/aliases printed in server startup log. At least JBoss / WildFly does that.

    There are different JNDI name aliases:

    java:global/APP_NAME[/MODULE_NAME]/EJB_NAME
    java:app/MODULE_NAME/EJB_NAME
    java:module/EJB_NAME

    Where /APP_NAME is the name of the WAR or EAR application, and /MODULE_NAME is the name of the EJB module in case of an EAR application, or the WAR module in case of a single-WAR application (and this will be absent in java:global as it otherwise repeats /APP_NAME), and /EJB_NAME defaults to the class name of the EJB class.

    The java:global is accessible through the entire server. The java:app is only accessible from inside the same application (WAR or EAR). The java:module is only accessible from inside the same module (EJB in case of EAR or WAR itself in case of single-WAR).

    A JSF managed bean is obviously inside a WAR. If you've a single-WAR application, then java:module/EJB_NAME must work. If you've however an EAR project, then the EJB is obviously inside the EJB module, in that case the java:module won't work and you'd need java:app or java:global.

    So, given an EJB like below,

    @Stateless
    public class FooService {}
    

    it's in a single-WAR project named "foo_war" via JNDI available in a JSF managed bean as follows (usually you do that in @PostConstruct method):

    InitialContext jndi = new InitialContext();
    
    FooService fooService = (FooService) jndi.lookup("java:module/FooService");
    // Or
    FooService fooService = (FooService) jndi.lookup("java:app/foo_war/FooService");
    // Or
    FooService fooService = (FooService) jndi.lookup("java:global/foo_war/FooService");
    

    or in an EAR project named "foo_ear" with an EJB module named "foo_ejb" with therein the EJB class (while the JSF managed bean is in the WAR module of the EAR project):

    InitialContext jndi = new InitialContext();
    
    FooService fooService = (FooService) jndi.lookup("java:app/foo_ejb/FooService");
    // Or
    FooService fooService = (FooService) jndi.lookup("java:global/foo_ear/foo_ejb/FooService");