0
votes

My problem differs from both WELD-001408 Unsatisfied dependencies when injecting EntityManager and WELD-001408 Unsatisfied dependencies. While those issues dealt with trying to inject a managed bean into a stateless EJB, I'm trying to do the reverse.

I'm getting an "Unsatisfied dependencies" when attempting to inject a @Stateless @Local interfaced bean into a web managed bean. I'm building an EAR with various EJB modules and a web module, running Glassfish 4 build 89 on JDK 8. Below are the details of the error and project config.

First, here is the error:

SEVERE:   Exception while loading the app
SEVERE:   Undeployment failed for context /platform-app
SEVERE:   Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [SessionSettingsBeanLocal] with qualifiers [@MyClient] at injection point [[BackedAnnotatedField] @Inject @MyClient private com.comp.jsf.dropdown.Settings.settingsBean]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [SessionSettingsBeanLocal] with qualifiers [@MyClient] at injection point [[BackedAnnotatedField] @Inject @MyClient private com.comp.jsf.dropdown.Settings.settingsBean]

Custom qualifier (in library project):

@Documented
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public @interface MyClient

EJB interface (in library project):

@Local
public interface SessionSettingsBeanLocal

EJB implmentation (in EJB module project):

@Stateless
@MyClient
public class SessionSettingsBean implements SessionSettingsBeanLocal

Managed bean (in web project - used for JSF):

@Named
@javax.faces.view.ViewScoped
public class Settings implements Serializable {
    @Inject
    @MyClient
    private SessionSettingsBeanLocal settingsBean;

Lastly, all of my beans.xml files (EJB modules, web) look like the following. The libraries, which contain the interface and qualifier, don't have a beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="annotated">
</beans>

The @Stateless EJB should register itself, but it's not found.

3
Why are you mixing custom CDI qualifiers and EJB?ra2085
I've had no problem with this exact thing in GF 3.1. I use qualifiers because I have multiple beans implementing the same @Local interface.John Manko
I don't think that's the way to go. You should be using EJB 3.0 disanbiguation by string, not a CDI Qualifier.ra2085
and here. Very nice examples for EJB 3.0 disambiguation: oracle.com/technetwork/articles/java/…ra2085

3 Answers

1
votes

Try to change the bean-discovery-mode from annotated to all

0
votes

You basically have three options how to overcome this

Completely switch to CDI

Since CDI 1.1 you can also use transactions in your beans so if you are not using remote EJBs, MDBs or anything else EJB specific, this would be way to go.

Produce EJB with Qualifier by another EJB

@Stateless
public class EJBProducer {

    @EJB
    private SessionSettingsBeanLocal settingsBean;

    @Produces 
    @MyClient
    public SessionSettingsBeanLocal getSettingsBean() {
        return settingsBean;
    }

}

Note tha this class has to be in WAR module. Now you can inject this EJB normally to CDI beans by its qualifier.

Distinguish EJB beans by their JNDI name

@Stateless
public class SessionSettingsBean implements SessionSettingsBeanLocal {}

Than just inject it to class like

@EJB(name = "SessionSettingsBean") 
private SessionSettingsBeanLocal bean; 

This way you can avoid CDI whatsoever.

0
votes

CDI Qualifiers are only meant to be used on CDI beans. Granted, you can inject EJB dependencies, but don't mix CDI qualifiers.

Here's a nice workaround from Arjan Tijms if you want to use qualifiers. link

UPDATE:

The 299 spec does mention EJB integration. They provide an example with both 299 and EJB annotations, which means, that bean will be CDI and EJB injectable. Here's the sample:

@Stateful @SessionScoped @Model
public class Login {
@Inject Credentials credentials;
@Inject @Users EntityManager userDatabase;
...
private User user;
@Inject
void initQuery(@Users EntityManagerFactory emf) {
...
}
@TransactionAttribute(REQUIRES_NEW)
@RolesAllowed("guest")
public void login() {
...
}
public void logout() {
user = null;
}
public boolean isLoggedIn() {
return user!=null;
}
@RolesAllowed("user")
@Produces @LoggedIn User getCurrentUser() {
...
}
}

So you may need to assign a scope to your SessionSettingsBean.