1

When a JSF managed bean extends an abstract Controller, I get Unsatisfied dependencies exception. I have methods in the AbstractController which I would like to override in the PoliceCaseList Bean. However, I get the exception below: I tried reading here and here , but my situation seems different.

exception

javax.servlet.ServletException: WELD-001408 Unsatisfied dependencies for type [AbstractFacade] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private ijmiscrudgen.backing.AbstractController.ejbFacade]

root cause

org.jboss.weld.exceptions.IllegalArgumentException: WELD-001408 Unsatisfied dependencies for type [AbstractFacade] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private ijmiscrudgen.backing.AbstractController.ejbFacade]


@ManagedBean
@ViewScoped
public class PoliceCaseList extends AbstractController<TblCase>{

@Inject
private TblCaseFacade caseFacade;
private TblCasePerson selectedPerson;
private TblCase selected;

@ManagedProperty(value = "#{loginController}")
private LoginController loginController;

/**
 * Creates a new instance of PoliceCaseList
 */
public PoliceCaseList() {
}


Here is the Abstract Controller. This Controller has methods which I always want to override. Beans with annotation @Named extend this controller and there are no complaints but the ones annotated with @ManagedBean get the exception above. How can I extend this AbstractController in my JSF Managed Beans without Unsatisfied dependency complaints?

public abstract class AbstractController<T> {

@Inject
private AbstractFacade<T> ejbFacade;
private Class<T> itemClass;
private T selected;
private Collection<T> items;
private boolean trueOrFalse;
private static int idOfSubmittedRecord;

private enum PersistAction {

    CREATE,
    DELETE,
    UPDATE
}

public AbstractController() {
}
Community
  • 1
  • 1
manpikin
  • 2,200
  • 1
  • 19
  • 19

1 Answers1

2

The problem is you are mixing two different dependency injection mechanisms: CDI and JSF managed beans/properties. That is why @Named beans work: this is a CDI annotation, so it follows CDI rules for injection to parent classes. On the contrary, @ManagedBeans live in a separate DI container, that of JSF, and do not care about the CDI annotations.

These two worlds communicate through the @Named annotation. So, what I would do is to make everything CDI and use the @Named beans through EL, as if they were normal JSF managed beans. The problem with this is that CDI does not support the view scope of JSF. This can be solved using e.g. the Deltaspike JSF module.

Bottom line: Make everything CDI. Use @Named instead of @ManagedBean and @Inject instead of @ManagedProperty and Deltaspike JSF module for things like @ViewScoped which are not provided out-of-the-box for CDI.

Some references

Community
  • 1
  • 1
Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
  • Deltaspike is not required if you're using JSF 2.2. Annotate your controller with javax.inject.Named and javax.faces.view.ViewScoped and it will work like the ManagedBean. – mamboking Mar 06 '14 at 15:50
  • When I make everything CDI with correct CDI imports for Scopes, it works fine(JSF 2.2); But one more Issue. I have an init method in PoliceCaseList Bean which makes use of the Injected loginController and it fails to be invoked, the exception says. It seems the Injected loginController is null at initialisation. Is the injected bean available after initialisation or before? What can I possibly do if I still want to do some initialization but using the injected loginCOntroller? – manpikin Mar 07 '14 at 08:21
  • By "init method" you mean a method (not constructor) annotated with `@PostConstruct` or a method (again not constructor) annotated with `@Inject`? The rule is `@PostConstruct` methods are called *after* `@Inject`ions have completed, so this should probably be used. – Nikos Paraskevopoulos Mar 07 '14 at 09:15