Reputation: 131
I have a Java 8 project and a JBoss 7.1.0GA server. I have a batch class with a global variable
@EJB
public MyInterface delegate;
which is defined as an instance of DelegateClass in my ejb-jar.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<module-name>moduleName</module-name>
<enterprise-beans>
<session>
<ejb-name>ejbName</ejb-name>
<business-remote>MyInterface</business-remote>
<ejb-class>DelegateClass</ejb-class>
<session-type>Stateless</session-type>
</session>
</enterprise-beans>
I have some implementations of MyInterface, so in my class DelegateClass I want to wrap an implementation of MyInterface and set it by an enum constant. Here the code:
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class DelegateClass implements MyInterface {
@Inject
@Any
protected Instance<MyInterface> instance;
protected MyInterface selectedImpl;
@PostConstruct
public void init() {
selectedImpl = instance.select(MyLiteralAnnotation.create(MyEnum.value)).get();
}
Here is the code of my literal annotation class:
public class MyLiteralAnnotation extends AnnotationLiteral<MyAnnotation> implements MyAnnotation {
private final MyEnum value;
private MyLiteralAnnotation(MyEnum value) {
this.value = value;
}
@Override
public MyEnum getValue() {
return value;
}
public static MyLiteralAnnotation create(MyEnum value) {
return new MyLiteralAnnotation(value);
}
}
the annotation I created:
@Retention(RetentionPolicy.RUNTIME)
@Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR })
@Qualifier
public @interface MyAnnotation {
MyEnum getValue();
}
and the implementation I want to have from the instance.select(...)
@Stateless
@LocalBean
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@MyAnnotation(MyEnum.value)
public class MyInterfaceImpl implements MyInterface {
....
}
I debug the application on my server, but when I try to instantiate the selectImpl field with instance.select(...), I have the exception:
org.jboss.weld.exceptions.UnsatisfiedResolutionException WELD-001334 Unsatisfied dependencies for type MyInterface with qualifiers @Any @MyAnnotation
Can someone help me, please ?
Upvotes: 0
Views: 6671
Reputation: 131
I solved my problem adding the annotation @ApplicationScope over the delegate class definition.
Upvotes: 3
Reputation: 506
The exception seems to occur because CDI does not find a bean annotated with @Any and @MyAnnotation, because the one you want select is only annotated with @MyAnnotation. I think @Any should not be necessary on Instance injection, because Instance will be capable of accessing all implementations of MyInterface, whereby you select the one annotated with @MyAnnotation(MyEnum.value). I have never used Instance with a qualifier, which uses a enum.
I think you shouldn't need to use Instace. Is the following injection not working?
class MyDelegate implements MyInterface{
@Inject
@MyAnnotation(MyEnum.value)
private MyInterface myInterface;
}
If you need to delegate to another implementation then maybe CDI-Decorators are what you need.
@Decorator
@Default // We decorate the default implementation of MyInterface or any qualified
// one you need to decorate
abstract class MyDecorator implements MyInterface {
@Inject
@MyAnnotation(MyEnum.value)
private MyInterface myInterface;
@Inject
@Delegate
private MyInterface delegate;
// Implement all methods you want to decroate
public void myMethod(){
if(condition) {
myInterface.myMethod();
} else {
delegate.myMethod();
}
}
}
You need to register the decorator in your beans.xml
<decorators>
<class>MyDecorator</class>
</decorators>
Does that help you?
Upvotes: 1