When I try to inject my Logger producer in an enum, I get a NPE. How can I inject a Logger in an enum?
Example:
public enum MyEnum {
HI("Hi there!"),
HELLO("Hello mister!");
@Inject
private Logger log;
private final String greeting;
private MyEnum(String greeting) {
this.greeting = greeting;
// this.log = LoggerFactory.getLogger(this.getClass());
}
public String getGreeting() {
log.debug("Method getGreeting called");
return this.greeting;
}
}
This class gives me a NPE on the log.debug()
line. When I remove the @Inject
and uncomment the this.log
line it works.
Testcase looks like this:
@RunWith(Arquillian.class)
public class CoverKindTest {
@Deployment
public static WebArchive createDeployment() {
return ShrinkWrap.create(WebArchive.class, "test.war")
.addClass(MyEnum.class)
.addClass(LoggerProducer.class)
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
public void testEnum() {
MyEnum myEnum = MyEnum.HI;
String greeting = myEnum.getGreeting();
assertThat("Should give the greeting.", greeting, is("Hi there!"));
}
}
Complete testable project for this question can be found here, MyEnum.class
is the original question, MyEnum1.class
is the solution without injection (working, but not what I am looking for) and MyEnum2.class
is a suggested answer.
Edit: Updated the GitHub repo with a working solution. https://github.com/martijnburger/how-to-inject-a-logger-in-an-enum
Found a solution that works!
I created a helper class as follows:
public class LoggerHelper {
private static Logger logger;
private void injectLogger(@Observes @Initialized(ApplicationScoped.class) Object context,
Logger logger) {
LoggerHelper.logger = logger;
}
public static Logger getLogger() {
return logger;
}
}
Now I can inject the logger in the Enum using:
private final Logger log = LoggerHelper.getLogger();