私はTomieに埋め込まれたArquillianを使用して、CDIを使用してロガーオブジェクトを作成するSpringLoggerBeanProducerをテストします。これはBeanを使用してSpringコンテナに挿入できます方法。私が遭遇する問題は、生産可能な5種類のロガーがあることです。テストを実行すると(それぞれ1つのタイプのロガーが生成されます)、最初に実行されるテストのみが成功しますが、その後のすべてのテストはjavax.naming.ConfigurationExceptionのため失敗します。 最初のテストだけがJEEサーバー環境で実行されているように見えますが、他のテストは実行されていません。Arquillian TomEEは最初のテスト後にjavax.naming.ConfigurationExceptionを埋め込みました
次のように生産者のためのコードがある:私は、次のMaven追加した
package mypackage.monitoring.spring.logger.producer;
import static org.junit.Assert.assertThat;
import java.lang.reflect.Field;
import javax.inject.Inject;
import org.hamcrest.Matchers;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.InjectionPoint;
import mypackage.monitoring.shared.event.MonitorEventType;
import mypackage.monitoring.shared.logger.Logger;
import mypackage.monitoring.shared.qualifier.Application;
import mypackage.monitoring.shared.qualifier.Business;
import mypackage.monitoring.shared.qualifier.Security;
import mypackage.monitoring.shared.qualifier.Technical;
@RunWith(Arquillian.class)
public class SpringLoggerBeanProducerIT<X> {
@Inject
private SpringLoggerBeanProducer producer;
private Logger defaultLogger;
@Application
private Logger applicationLogger;
@Business
private Logger businessLogger;
@Security
private Logger securityLogger;
@Technical
private Logger technicalLogger;
@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class).addPackages(true, "mypackage")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void alsDefaultLoggerDanMonitorEventTypeTechnical() throws Exception {
System.out.println("Default Logger");
Logger logger = producer.applicationLogger(new InjectionPoint(this.getClass().getDeclaredField("defaultLogger")));
assertThat(logger, Matchers.notNullValue());
Field typeField = logger.getClass().getSuperclass().getDeclaredField("type");
typeField.setAccessible(true);
MonitorEventType type = (MonitorEventType) typeField.get(logger);
assertThat(type, Matchers.is(MonitorEventType.TECHNICAL));
}
@Test
public void alsApplicationLoggerDanMonitorEventTypeApplication() throws Exception {
System.out.println("Application Logger");
Logger logger = producer.applicationLogger(new InjectionPoint(this.getClass().getDeclaredField("applicationLogger")));
assertThat(logger, Matchers.notNullValue());
Field typeField = logger.getClass().getSuperclass().getDeclaredField("type");
typeField.setAccessible(true);
MonitorEventType type = (MonitorEventType) typeField.get(logger);
assertThat(type, Matchers.is(MonitorEventType.APPLICATION));
}
@Test
public void alsBusinessLoggerDanMonitorEventTypeBusiness() throws Exception {
System.out.println("Business Logger");
Logger logger = producer.applicationLogger(new InjectionPoint(this.getClass().getDeclaredField("businessLogger")));
assertThat(logger, Matchers.notNullValue());
Field typeField = logger.getClass().getSuperclass().getDeclaredField("type");
typeField.setAccessible(true);
MonitorEventType type = (MonitorEventType) typeField.get(logger);
assertThat(type, Matchers.is(MonitorEventType.BUSINESS));
}
@Test
public void alsSecurityLoggerDanMonitorEventTypeSecurity() throws Exception {
System.out.println("Security Logger");
Logger logger = producer.applicationLogger(new InjectionPoint(this.getClass().getDeclaredField("securityLogger")));
assertThat(logger, Matchers.notNullValue());
Field typeField = logger.getClass().getSuperclass().getDeclaredField("type");
typeField.setAccessible(true);
MonitorEventType type = (MonitorEventType) typeField.get(logger);
assertThat(type, Matchers.is(MonitorEventType.SECURITY));
}
@Test
public void alsTechnicalLoggerDanMonitorEventTypeTechnical() throws Exception {
System.out.println("Technical Logger");
Logger logger = producer.applicationLogger(new InjectionPoint(this.getClass().getDeclaredField("technicalLogger")));
assertThat(logger, Matchers.notNullValue());
Field typeField = logger.getClass().getSuperclass().getDeclaredField("type");
typeField.setAccessible(true);
MonitorEventType type = (MonitorEventType) typeField.get(logger);
assertThat(type, Matchers.is(MonitorEventType.TECHNICAL));
}
}
:例外がラインbeanManager = InitialContext.doLookup("java:comp/BeanManager");
テストするためのコードで発生
package mypackage.monitoring.spring.logger.producer;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import mypackage.monitoring.shared.logger.Logger;
import mypackage.monitoring.shared.qualifier.Application;
import mypackage.monitoring.shared.qualifier.Business;
import mypackage.monitoring.shared.qualifier.Security;
import mypackage.monitoring.shared.qualifier.Technical;
@Configuration
public class SpringLoggerBeanProducer {
private BeanManager beanManager;
@org.springframework.context.annotation.Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Application
public Logger applicationLogger(org.springframework.beans.factory.InjectionPoint springIp) {
return logger(springIp);
}
@org.springframework.context.annotation.Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Business
public Logger businessLogger(org.springframework.beans.factory.InjectionPoint springIp) {
return logger(springIp);
}
@org.springframework.context.annotation.Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Security
public Logger securityLogger(org.springframework.beans.factory.InjectionPoint springIp) {
return logger(springIp);
}
@org.springframework.context.annotation.Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Technical
public Logger technicalLogger(org.springframework.beans.factory.InjectionPoint springIp) {
return logger(springIp);
}
private Logger logger(org.springframework.beans.factory.InjectionPoint springIp) {
setBeanManager();
Field field = springIp.getField();
Annotation[] qualifiers = getFieldQualifiers(field);
Bean<? extends Object> bean = getLoggerBean(qualifiers);
return getInjectableLoggerReference(field, bean);
}
private Logger getInjectableLoggerReference(Field field, Bean<?> bean) {
CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
return (Logger) beanManager.getInjectableReference(getInjectionPoint(field), creationalContext);
}
private Bean<? extends Object> getLoggerBean(Annotation[] qualifiers) {
Set<Bean<?>> beans = beanManager.getBeans(Logger.class, qualifiers);
return beanManager.resolve(beans);
}
private Annotation[] getFieldQualifiers(Field field) {
Annotation[] annotations = field.getAnnotations();
Set<Annotation> qualifierSet = getQualifierSet(annotations);
annotations = qualifierSet.toArray(new Annotation[0]);
return annotations;
}
private void setBeanManager() {
try {
if (beanManager == null) {
beanManager = InitialContext.doLookup("java:comp/BeanManager");
}
} catch (NamingException e) {
throw new LoggerProducerException("BeanManager not found.", e);
}
}
private Set<Annotation> getQualifierSet(Annotation[] annotations) {
Set<Annotation> qualifierSet = new HashSet<Annotation>();
for (Annotation annotation : annotations) {
if (annotation.annotationType().isAnnotationPresent(javax.inject.Qualifier.class)) {
qualifierSet.add(annotation);
}
}
return qualifierSet;
}
private InjectionPoint getInjectionPoint(final Field member) {
class GeneratedInjectionPoint implements InjectionPoint {
@Override
public boolean isTransient() {
return Modifier.isTransient(member.getModifiers());
}
@Override
public boolean isDelegate() {
return false;
}
@Override
public Type getType() {
return member.getType();
}
@Override
public Set<Annotation> getQualifiers() {
Annotation[] annotations = member.getAnnotations();
return getQualifierSet(annotations);
}
@Override
public Member getMember() {
return member;
}
@Override
public Bean<?> getBean() {
return null;
}
@Override
public Annotated getAnnotated() {
throw new UnsupportedOperationException("Method not implemented for " + this.getClass().getSimpleName() + ".class");
}
}
return new GeneratedInjectionPoint();
}
}
を私のプロジェクトへの依存関係:
<!-- Arquillian junit testen -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>1.1.9.FINAL</version>
<scope>test</scope>
</dependency>
<!-- Arquillian adapter voor TomEE -->
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>arquillian-tomee-embedded</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<!-- Embedded container TomEE -->
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>tomee-embedded</artifactId>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
最初のテストの実行後に変更されるため、実際にはJNDIスペースで競合しているように見えます。私はまだこれがどうして起こったのか、少し不明ですが、今はこの問題を回避する方法があります。 –