简体   繁体   中英

Java EE bean with interface not being created for injection

I have a simple case where I have a REST Service MyService that should get injected with a bean beanB of type BeanB which implements interface BeanBInterface . The error I get is the classic WELD-001408 one shown below:

org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type BeanBInterface with qualifiers @BeanBQualifier
  at injection point [BackedAnnotatedField] @Inject @BeanBQualifier public com.example.MyService.beanB
  at com.example.MyService.beanB(MyService.java:0)

The REST Service:

import javax.ws.rs.Path;
import javax.inject.Inject;

@Path("/")
public class MyService {
    @Inject 
    @BeanBQualifier(BeanBQualifier.Type.PROD)
    public BeanBInterface beanB;

    public MyService() {}
}

Bean Interface:

public interface BeanBInterface {
}

Bean Implementation:

import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Produces;

@Startup
@Singleton
@BeanBQualifier(BeanBQualifier.Type.PROD)
public class BeanB implements BeanBInterface {
    private String name = "B";

    public BeanB() {}

    public String getName() {return name;}

    public void setName(String name) {this.name = name;}
}

The Bean Qualifier

import javax.inject.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface BeanBQualifier {
   Type value();
   enum Type{PROD, TEST}
}

Beans.xml (tried in META-INF/beans.xml and also tried in WEB-INF/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>

I also tried a bean-discovery-mode="all" with no luck.

If I make the declaration of beanB to use the concrete class BeanB rather than its interface in MyService it works (but that defeats the purpose of an interface):

If I add an @Produces factory method to MyService to construct the bean it also works but this defeats the purpose of letting the container instantiate my beans for me:

@javax.enterprise.inject.Produces
public static BeanB get() {
    return new BeanB();
}

but if this @Produces factory method returns the interface instead it won't work:

@javax.enterprise.inject.Produces
public static BeanBInterface get() {
    return new BeanB();
}

EJBs have some weird rules about what interfaces are actually exposed as implemented. Only interfaces marked as @Local/@Remote will be exposed. If you want to use the bean with the interface and with the class you need to add @LocalBean to the ejb.

In short: add @Local to the interface or @Local(BeanBInterface.class) to BeanB

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