2017-06-01 2 views
1

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> 

Test results

Stacktrace

Antwort

0

Es scheint ein Teil der Anwendung verunstaltet tomee JNDI Platz (ein IBM Client jar?). Sie können versuchen, die Kontext-Factory zu erzwingen: org.apache.openejb.core.OpenEJBInitialContextFactory

Seitennotiz: vielleicht auch auf tomee 7.0.3 upgraden?

+0

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. –

Verwandte Themen