我的用例是我有多个实现接口的类,在运行时我希望每个类都有一个实例。我找到了使用CDI的解决方案,Instance
结合@Any
限定符。以下示例在Glassfish中工作正常,但在WebSphere 8中没有。
我正在寻找的界面:
public interface TestIf {
String test();
}
一个示例实现:
import javax.ejb.Stateless;
@Stateless
public class TestA implements TestIf {
@Override
public String test() {
return getClass().getName();
}
}
另一个示例实现:
import javax.ejb.Stateless;
@Stateless
public class TestB implements TestIf {
@Override
public String test() {
return getClass().getName();
}
}
Glassfish不需要beans.xml
它可以正常使用bean注释,但是WebSphere抱怨CDI没有启用,除非它被提出:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
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/beans_1_0.xsd">
</beans>
我创建了一个简单的启动bean来尝试:
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.inject.Any;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
@Startup
@Singleton
public class Start {
@Any
@Inject
private Instance<TestIf> providers;
@PostConstruct
public void test() {
System.out.println(">>>>> FOO " + providers);
for (final TestIf b : providers) {
System.out.println(">>>>> " + b.test());
}
}
}
在Glassfish中它起作用:
...
Info: >>>>> FOO
Info: >>>>> TestB
Info: >>>>> TestA
...
在Websphere中我收到错误:
E CWOWB0102E: A JCDI error has occurred: Api type [javax.enterprise.inject.Instance] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Any()]
for injection into
Field Injection Point, field : private javax.enterprise.inject.Instance Start.providers, Bean Owner : [-495517893,Name:null,WebBeans Type:MANAGED,API Types:[Start,java.lang.Object],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
InjectionType : [javax.enterprise.inject.Instance<TestIf>]
Annotated : [Annotated Field,Base Type : javax.enterprise.inject.Instance<TestIf>,Type Closures : [Iterable<TestIf>, javax.enterprise.inject.Instance<TestIf>, Provider<interface TestIf>, class java.lang.Object],Annotations : [@javax.inject.Inject(), @javax.enterprise.inject.Any()],Java Member Name : providers]
Qualifiers : [[@javax.enterprise.inject.Any()]]
E CNTR0190E: The Start startup singleton session bean in the ejb.jar module failed initialization with exception:
javax.ejb.NoSuchEJBException: An error occurred during initialization of singleton session bean foo.ear#foo.ejb.jar#Start, resulting in the discarding of the singleton instance.; nested exception is: javax.ejb.EJBException: Injection failure; nested exception is: javax.enterprise.inject.UnsatisfiedResolutionException: Api type [javax.enterprise.inject.Instance] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Any()]
for injection into
Field Injection Point, field : private javax.enterprise.inject.Instance Start.providers, Bean Owner : [-495517893,Name:null,WebBeans Type:MANAGED,API Types:[Start,java.lang.Object],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
InjectionType : [javax.enterprise.inject.Instance<TestIf>]
Annotated : [Annotated Field,Base Type : javax.enterprise.inject.Instance<TestIf>,Type Closures : [Iterable<interface TestIf>, javax.enterprise.inject.Instance<TestIf>, Provider<interface TestIf>, class java.lang.Object],Annotations : [@javax.inject.Inject(), @javax.enterprise.inject.Any()],Java Member Name : providers]
Qualifiers : [[@javax.enterprise.inject.Any()]]
javax.ejb.EJBException: Injection failure; nested exception is: javax.enterprise.inject.UnsatisfiedResolutionException: Api type [javax.enterprise.inject.Instance] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Any()]
for injection into
Field Injection Point, field : private javax.enterprise.inject.Instance Start.providers, Bean Owner : [-495517893,Name:null,WebBeans Type:MANAGED,API Types:[Start,java.lang.Object],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
InjectionType : [javax.enterprise.inject.Instance<TestIf>]
Annotated : [Annotated Field,Base Type : javax.enterprise.inject.Instance<TestIf>,Type Closures : [Iterable<interface TestIf>, javax.enterprise.inject.Instance<TestIf>, Provider<interface TestIf>, class java.lang.Object],Annotations : [@javax.inject.Inject(), @javax.enterprise.inject.Any()],Java Member Name : providers]
Qualifiers : [[@javax.enterprise.inject.Any()]]
javax.enterprise.inject.UnsatisfiedResolutionException: Api type [javax.enterprise.inject.Instance] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.Any()]
for injection into
Field Injection Point, field : private javax.enterprise.inject.Instance Start.providers, Bean Owner : [-495517893,Name:null,WebBeans Type:MANAGED,API Types:[Start,java.lang.Object],Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
InjectionType : [javax.enterprise.inject.Instance<TestIf>]
Annotated : [Annotated Field,Base Type : javax.enterprise.inject.Instance<TestIf>,Type Closures : [Iterable<interface TestIf>, javax.enterprise.inject.Instance<TestIf>, Provider<interface TestIf>, class java.lang.Object],Annotations : [@javax.inject.Inject(), @javax.enterprise.inject.Any()],Java Member Name : providers]
Qualifiers : [[@javax.enterprise.inject.Any()]]
Glassfish使用Java 8“内部”NetBeans运行。 WebSphere在Eclipse内部运行IBM JDK 8。为简洁起见,我删除了我的课程的包名。