18

Can I (and if so, how?) lookup CDI managed beans using javax.naming.Context#lookup in EJB module?

I'm using GlassFish v3. I suppose that I can use @Named, but what is JNDI name of CDI managed bean? I want to lookup them from unmanaged POJOs so I can't use @Inject.

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
zacheusz
  • 8,750
  • 3
  • 36
  • 60

3 Answers3

35

You can also access the BeanManager by using CDI.current(), which saves you typing a good few lines of code. Example taken from here

Using CDI.current()

BeanManager bm = CDI.current().getBeanManager();

Using JNDI:

BeanManager bm = null;
try {
    InitialContext context = new InitialContext();
    bm = (BeanManager) context.lookup("java:comp/BeanManager");
} catch (Exception e) {
    e.printStackTrace();
}

Now you have the BeanManager you can access your CDI beans by doing either a type-based lookup or a name-based lookup.

Type based:

Bean<CrudService> bean = (Bean<CrudService>) bm.getBeans(CrudService.class).iterator().next();
CreationalContext<CrudService> ctx = bm.createCreationalContext(bean);
CrudService crudService = (CrudService) bm.getReference(bean, CrudService.class, ctx);

Name-based

Bean bean = bm.getBeans("crudService").iterator().next();
CreationalContext ctx = bm.createCreationalContext(bean);
CrudService crudService = bm.getReference(bean, bean.getClass(), ctx);

Full example:

//get reference to BeanManager
BeanManager bm = CDI.current().getBeanManager();
Bean<CrudService> bean = (Bean<CrudService>) bm.getBeans(CrudService.class).iterator().next();
CreationalContext<CrudService> ctx = bm.createCreationalContext(bean);

//get reference to your CDI managed bean
CrudService crudService = (CrudService) bm.getReference(bean, CrudService.class, ctx);

UPDATE - This can now be achieved in one line if you are using CDI 1.1:

CrudService crudService = CDI.current().select(CrudService.class).get();
Chris Ritchie
  • 4,749
  • 2
  • 36
  • 33
  • 6
    In my case I had to use `bean.getBeanClass()` instead of `bean.getClass()` to avoid WELD-001305 exception. – Panu Haaramo May 05 '15 at 17:06
  • 7
    You could do CDI.current().select(CrudService.class).get() with CDI 1.1+ – ravthiru Mar 29 '17 at 03:47
  • How do I pass authentication credentials when using CDI.current()? When using InitialContext() I can specify the Principal in the constructor properties. How do I do something equivalent with CDI.current()? – Eric B. Apr 10 '17 at 20:15
  • Is it necessary to call CreationalContext::release when done using CrudService if CrudService is a stateless EJB? – aandeers Aug 04 '17 at 19:17
7

You can lookup the BeanManager via JNDI (java:comp/BeanManager) then use the JSR-299 API hung off of the BeanManager to get a contextual reference to a managed bean.

JSR-299 managed beans are not available for direct JNDI lookup.

Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
covener
  • 17,402
  • 2
  • 31
  • 45
  • 3
    I found a good code example at http://dominikdorn.com/2010/04/cdi-weld-manual-bean-lookup/ – Sebi Aug 22 '12 at 20:21
  • A named @ManagedBean(value="MyManagedBean") POJO can be looked up through JNDI with i.e. InitialContext.doLookup("java:app/myapp/MyManagedBean"); see API doc of javax.annotation.ManagedBean – Torsten Römer Apr 20 '14 at 19:29
  • I was curious about what `javax.annotation.ManagedBean` exactly is, here is a good answer: http://stackoverflow.com/a/32420123/1341535 – Vsevolod Golovanov Jun 10 '16 at 15:50
  • `@ManagedBean`: `The ManagedBean annotation marks a POJO (Plain Old Java Object) as a ManagedBean. A ManagedBean supports a small set of basic services such as resource injection, lifecycle callbacks and interceptors. Since: Common Annotations 1.1` – Roland Oct 30 '17 at 22:06
0

If you are working on a JSF / Jakarta Faces project and you're using OmniFaces, you can simply do:

MyBean myBean = org.omnifaces.util.Beans.getInstance("myBeanName");

See also:

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102