在使用 Glassfish 嵌入式插件使用 Arquillian 运行单元测试时,我收到以下 CDI 错误:
2015-09-18 06:25:24,376 DEBUG | main | org.jboss.weld.Reflection | WELD-000620: interface com.SupportedLocales is not declared @Target(METHOD, FIELD, PARAMETER, TYPE). Weld will use this annotation, however this may make the application unportable.
sept. 18, 2015 6:25:24 AM com.sun.enterprise.v3.server.ApplicationLifecycle deploy
GRAVE: Exception during lifecycle processing
org.glassfish.deployment.common.DeploymentException: CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Set<Locale> with qualifiers @SupportedLocales
at injection point [BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] @Inject protected com.MyClass(@SupportedLocales Set<Locale>)
at com.MyClass.<init>(MyClass.java:0)
带有限定符 @SupportedLocales 的 Set(Locale) 定义在已测试 WebArchive 中部署的模块中。存档内容是:
/WEB-INF/
/WEB-INF/lib/
/WEB-INF/lib/commons-lang3-3.3.2.jar
/WEB-INF/lib/commons-configuration-1.10.jar
/WEB-INF/lib/reflections-0.9.9-RC2.jar
/WEB-INF/lib/jcl-over-slf4j-1.7.10.jar
/WEB-INF/lib/slf4j-api-1.7.10.jar
/WEB-INF/lib/deltaspike-core-api-1.5.0.jar
/WEB-INF/lib/commons-util-1.0.0-SNAPSHOT.jar
/WEB-INF/lib/commons-io-2.4.jar
/WEB-INF/lib/guava-16.0.1.jar
/WEB-INF/lib/log4j-over-slf4j-1.7.10.jar
/WEB-INF/lib/javassist-3.18.2-GA.jar
/WEB-INF/lib/logback-classic-1.1.2.jar
/WEB-INF/lib/logback-core-1.1.2.jar
/WEB-INF/lib/jul-to-slf4j-1.7.10.jar
/WEB-INF/lib/commons-cdi-1.0.0-SNAPSHOT.jar
/WEB-INF/lib/xml-apis-1.0.b2.jar
/WEB-INF/lib/deltaspike-core-impl-1.5.0.jar
/WEB-INF/lib/dom4j-1.6.1.jar
/WEB-INF/lib/commons-codec-1.9.jar
/WEB-INF/lib/commons-lang-2.6.jar
/WEB-INF/lib/annotations-2.0.1.jar
/WEB-INF/lib/libphonenumber-7.0.3.jar
/WEB-INF/classes/
/WEB-INF/classes/com/
/WEB-INF/classes/com/timm/
/WEB-INF/classes/com/timm/common/
/WEB-INF/classes/com/timm/common/cdi/
/WEB-INF/classes/com/timm/common/cdi/web/
/WEB-INF/classes/com/timm/common/cdi/web/i18n/
/WEB-INF/classes/com/timm/common/cdi/web/i18n/ShiroCurrentLocale.class
/WEB-INF/beans.xml
该对象由位于“common-cdi”模块中的生产者方法提供。同一个模块提供 CDI 扩展功能,如 ThreadScoped。Weld 在测试启动期间未发现此生产者,并且 Weld 未从“commons-cdi”模块中发现 bean。这怎么可能?我们可以在同一个模块中提供 CDI 扩展功能和 CDI bean 吗?
@SupportedLocales 在“commons-cdi”中声明:
@Qualifier
@Target({
ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD
})
@Retention(RetentionPolicy.RUNTIME)
public @interface SupportedLocales {
}
生产者在“commons-cdi”中声明:
@Dependent
public class I18NProducer {
@Produces
@ApplicationScoped
@Default
@SupportedLocales
public Set<Locale> getSupportedLocales() {
Set<Locale> supportedLocales;
supportedLocales = new HashSet<Locale>();
supportedLocales.add(Locale.US);
return supportedLocales;
}
}
JUnit 测试用例定义:
@RunWith(Arquillian.class)
public class LocaleInjectionTest {
@Deployment
public static Archive<?> deploy() {
final String moduleName = LocaleInjectionTest.class.getSimpleName();
PomEquippedResolveStage resolver = Maven.resolver().loadPomFromFile("pom.xml");
File[] libs = resolver.resolve("com.myname:commons-cdi").withTransitivity().asFile();
WebArchive testWar = ShrinkWrap
.create(WebArchive.class, moduleName + ".war")
.addClass(MyCurrentLocale.class)
.addAsLibraries(libs)
.addAsWebInfResource(ArchiveUtils.getResourceBeanXMLWithAlternativeAndDiscoveryModeAnnotated(MyCurrentLocale.class),
"beans.xml");
return testWar;
}
@Inject
private CurrentLocale bean;
@Test
public void testInjection() throws Exception {
...
}
}
MyCurrentLocale 类定义:
@SessionScoped
@Alternative
public class MyCurrentLocale extends DefaultCurrentLocale implements Serializable {
@Inject
protected MyCurrentLocale(@SupportedLocales Set<Locale> supportedLocales) {
super(supportedLocales);
}
...
}
声明有问题吗?