Ich benutze Arquillian mit TomEE-embedded, um einen SpringLoggerBeanProducer zu testen, der CDI verwendet, um ein Logger-Objekt zu konstruieren, das wiederum in einen Spring-Container injiziert werden kann Methode. Das Problem, auf das ich gestoßen bin, ist, dass es 5 Arten von Loggern gibt, die produziert werden können. Wenn ich die Tests durchführe (die jeweils einen Loggertyp erzeugen), ist nur der Test erfolgreich, der zuerst ausgeführt wird, während alle folgenden Tests aufgrund einer javax.naming.ConfigurationException fehlschlagen. Es scheint, als ob nur der erste Test in einer JEE-Serverumgebung ausgeführt wird, während die anderen nicht ausgeführt werden.Arquillian TomEE embedded javax.naming.ConfigurationException nach dem ersten Test
Der Code für den Hersteller ist wie folgt:
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();
}
}
Die Ausnahme an der Linie für den Test beanManager = InitialContext.doLookup("java:comp/BeanManager");
Der Code kommt:
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));
}
}
ich folgendes Maven hinzugefügt haben Abhängigkeiten zu meinem Projekt:
<!-- 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>
Es scheint tatsächlich ein Konflikt im JNDI-Raum zu sein, da er sich nach dem ersten Test ändert. Ich weiß immer noch nicht genau, warum das passiert, aber im Moment habe ich eine Möglichkeit, dieses Problem zu umgehen. –