Is it possible to inject EJB implementation and not its interface using CDI?
Asked Answered
M

3

14

My configuration is: Wildfly 8.2.0, Weld

Is it possible to inject in bean and not in its interface in CDI ?

@Stateless
class Bean implements IBean {
...
}    

interface IBean {
...
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Fail

   @Inject
   IBean iBean; //OK
}

EDIT:

More Info in my previous question: Stateless EJB implements interface injection failed

Metropolitan answered 22/12, 2015 at 8:23 Comment(1)
Yes. It should work . What are the error message?Chyme
P
28

Yes you can, but as EJB inject the business view the only business view you are exposing is the @Local view which is the default when you implement an interface (IBean in your case is a local business interface). So, if you want to inject the bean itself, you need to tell the container that you are using the no-interface view.

In your example, if you still want to implement your interface and inject Bean you should use the @LocalBean annotation which means that the bean exposes a no-interface view:

@Stateless
@LocalBean // <-- no-interface view
class Bean implements IBean {
...
}  

interface IBean {
....
}

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //Should be OK
}

Or, If you don't want to implement any interface, then the bean defines by default a No-Interface view:

@Stateless
class Bean {
...
}  

@SessionScoped
class Scoped {
   @Inject
   Bean bean; //OK
}

See also:

Penney answered 22/12, 2015 at 13:26 Comment(2)
Thank you! Nice explanation and links.Metropolitan
glad that it helped :)Penney
W
2

It looks like you got an unclear answer in your prior question, and really all this question is is a follow up to that one.

Generally speaking, CDI allows you to inject both interface and impl for CDI managed beans. This is not the case for EJBs. When an EJB implements an interface, that becomes its business interface. Only the methods declared there are valid. Effectively, your Bean class defines only how those methods work, and does not actually exist as a bean in your runtime.

So no, when using EJBs, you cannot inject the implementation, only the interface. If you really want to do this, I would move away from EJBs.

Wauters answered 22/12, 2015 at 12:46 Comment(0)
Z
0

One of the possible reasons you might not be willing to use the interface to inject the EJB could be that you might have many EJBs implementing this interface and your EJB container might be complaining that it's not able to resolve the ambiguity of which particular EJB has to be injected in a given context. If this is the case, you can easily specify the name of the concrete EJB class implementing the common interface using javax.inject.Named annotation as shown below:

@SessionScoped
class Scoped {
   @Named("Bean")
   IBean iBean;
}
Zymogenesis answered 8/1, 2020 at 0:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.