3

I don't understand when someone would use (new InitialContext()).lookup(....) instead of

@Stateless(mappedName="A1Global")
public class A1 implements A { ... }

@EJB(mappedName="A1Global")
private A a;

does the latter approach with mappedName have any downsides? I also noticed how the JNDI name can be vendor specific, complex and unnecessarily long.

Vjeetje
  • 4,914
  • 3
  • 31
  • 52

1 Answers1

3

Grabbing EJB by JNDI may be useful in classes which are not managed by the dependency injection container and thus where @EJB simply won't work. Those are however rare cases and usually caused by a bug or an oversight in the specification associated with the client framework where you'd like to use @EJB, and are supposed to be reported, discussed and solved in newer releases of that client framework so that one can ultimately just use @EJB.

For example, JSF, the Java EE's MVC framework, supports custom converters and validators. However, due to an oversight, @EJB is not supported in a custom JSF Converter or Validator while they may at times need to invoke a business service call. This was solved in JSF 2.3, but until that time, one workaround was to grab EJB by JNDI — which was rather clumsy though, there were easier workarounds, see also a.o How to inject @EJB, @PersistenceContext, @Inject, @Autowired, etc in @FacesConverter?

The same story goes on for Bean Validation, the Java EE's Validation framework. The @EJB was not supported in a custom ConstraintValidator until version 1.1. See also a.o. JSF 2.0 validation in actionListener or action method.

The JNDI name is in case of EJBs not vendor specific. At least, that's not as such specified in Java EE. It's however specific to the way how the EJB is packaged as well as where the EJB client is located in the application. The answer to this related question explains how the JNDI name is composed and which one you should use depending on the location of the EJB client: Inject EJB bean from JSF managed bean programmatically.

In a nutshell, if you can use @EJB, then by all means use it. If you can't, then first research if you're doing things the right way. Sometimes, people try to grab an EJB in a place where it absolutely doesn't make sense. If you can confirm that you're not the only having trouble with using @EJB in order to achieve the desired functional requirement, then report an issue to the client framework in question. Chances are big that they will add @EJB support in the intented place.

That said, if your environment supports CDI, then you need to know that it's these days recommended to migrate @EJB to @Inject. In Java EE 6/7 it'll work just fine expect of one corner case (cyclic injection of EJB in self). The aim of CDI is to unify all various dependency injection mechanisms throughout Java EE frameworks into a single API. JSF for example is already planning to deprecate its @ManagedBean/@ManagedProperty in favor of @Named/@Inject in a future Java EE version. See also a.o. Backing beans (@ManagedBean) or CDI Beans (@Named)? The same may happen for the @EJB in favor of @Inject.

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452