I come across a strange behavior. I looked for a possible explanation but I did not find (always the same types of answers).
My implementation is perfectly deployed under WildFly 10.x and the Logger works perfectly. I created very classic elements of CDI encapsulation of a Logger production bean. As shown it works well in deployed mode. I deleted the logging subsystem provided by Wildfly to use as logback and the configuration contained in the war file.
The worry is during a unit test. It tells me that the injected logger is null. It seems to me both normal but odd.
The CDI Logger Producer:
public class LoggerProducer {
@Produces
public Logger createLogger(InjectionPoint injectionPoint) {
return LoggerFactory.getLogger(injectionPoint.getBean().getBeanClass());
}
}
The implementation of a specific interceptor :
@Interceptor
@RestOperation
public class RestOperationInterceptor {
@Inject
private Logger logger;
@AroundInvoke
public Object interceptRestOperation(InvocationContext context) throws Exception {
Preconditions.checkNotNull(context);
logger.info("Context parameters : {}", MoreObjects.toStringHelper(context.getParameters()).toString());
return context.proceed();
}
}
This code works well on my Wildfly Server. The bean discovery (beans.xml), only for this interceptor and to avoid @Dependent annotation on LoggerProducer.class :
<?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"
bean-discovery-mode="all">
<interceptors>
<class>fr.hoag.interceptors.RestOperationInterceptor</class>
</interceptors>
</beans>
But this unit test...
@RunWith(CdiRunner.class)
public class RestInterceptorTest {
@Produces /* @Mock/@Inject etc. */
Logger logger;
@Test
public void should_intercept_rest_request() throws Exception {
InvocationContext context = mock(InvocationContext.class);
when(context.getParameters()).thenReturn(new Object[]{1,2,3});
when(context.proceed()).thenReturn("test");
RestOperationInterceptor interceptor = new RestOperationInterceptor();
assertThat(interceptor.interceptRestOperation(context)).isEqualTo("test");
}
}
The result is (Line 27 of RestOperationInterceptor is about the logger, context and context.getParameters() are not null):
java.lang.NullPointerException
at fr.hoag.interceptors.RestOperationInterceptor.interceptRestOperation(RestOperationInterceptor.java:27)
at RestInterceptorTest.should_intercept_rest_request(RestInterceptorTest.java:34)
at org.jboss.weld.proxies.RestInterceptorTest$Proxy$_$$_WeldClientProxy.should_intercept_rest_request(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.jglue.cdiunit.CdiRunner$2.evaluate(CdiRunner.java:179)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
The WELD stacktrace : Logger seems to be well produced.
11:18:38.388 [main] DEBUG org.jboss.weld.Bootstrap - WELD-000106: Bean: Producer Field [Logger] with qualifiers [@Any @Default] declared as [[UnbackedAnnotatedField] @Produces RestInterceptorTest.logger]
I think something is missing in bean discovery for the LoggerProducer in CDIUnit. What could i forget ?
Thanks you in advance.