简体   繁体   中英

Inject interface implementation with CDI

I can't get a very simple point on CDI!

I have these classes in my application:

public class CarrelloController extends AbstractController {

    @Inject CarrelloService carrelloService;

    ...
}


@Stateless
public class CarrelloService implements CarrelloDataProvider {
   ...
}

public interface CarrelloDataProvider {
    public Oggetto getSomething(String foo);
}

However, I am getting the following error, after deploying:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type CarrelloService with qualifiers @Default at injection point [BackedAnnotatedField] @Inject @Default it.footballove.web.controller.CarrelloController.carrelloService at it.footballove.web.controller.CarrelloController.carrelloService(CarrelloController.java:0)

at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:359) at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281) at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134) at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155) at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518) at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68) at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66) at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60) at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Exception 0 :

I get that only using an interface. Abstract class instead makes no problem!

Why?

This is the way that EJBs work with CDI. The CDI bean types of an EJB are given by the business interface of the EJB, not by the implementation class. The business interface may be explicitly declared with a @Local annotation.

In your case, the business interface defaults to the one and only declared interface CarelloDataProvider . So there really is no CDI bean of type CarelloService .

Suggestion:

Rename your EJB class to CarelloServiceImpl and factor out an interface CarelloService containing the extra methods you need in CarelloController .

@Stateless
public class CarelloServiceImpl implements CarelloService {
}

public interface CarelloService extends CarelloDataProvider {
}

Or just reconsider your design - usually, when you need to access an implementation method not contained in an interface, this is a symptom of mismatched abstractions.

i've hit the same problem, following scenario:

public interface Importer() { ..... }

with following structure:

public abstract class DefaultImporter implements Importer { // some default methods }

and finally the implementation to use for injetion:

public class DefaultFileImporter extends DefaultImporter implements Serializable { ...}

this didn't work and the WELD exception state above has been thrown. I've tried to annonate the classes with @Named, @Qualifier, @Default... but non has worked.

In order to make the injection work with an abstract class, it is required to implement explicitly the interface in the service bean:

public class DefaultFileImporter extends DefaultImporter implements Importer, Serializable { ...}

Simple said: implement explicit the interface you want to injection into the implementation (in addition to the abstract class).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM