Hi all,

I'm currently in the process of migrating my existing Java EE Web Profile 
applications, running on GlassFish 4.1, from JUL to Log4j2. That is, not just 
the application logging but also the server logging (cf. 
http://mail-archives.apache.org/mod_mbox/logging-log4j-user/201603.mbox/%3Ctrinity-b7c77190-7ef6-48a1-bb32-61adeba3989f-1456841976889%403capp-gmx-bs56%3E).

Regarding application logging, I can declare (static or non-static) Logger 
instances in my CDI beans and JAX-RS resource classes without problems, i.e. 
those instances are associated with the correct LoggerContext of the 
application module.

But with my EJBs (being on Java EE Web Profile, those are EJB Lites), things 
don't work so well. As I see it, the basic problem is that the EJB 
initialization in GlassFish happens before the web (servlet) initialization, 
which in turn triggers the Log4j2 initialization.

So if I declare a static Logger class member like this: "private static final 
Logger LOGGER = LogManager.getLogger();", LOGGER is associated with the wrong 
LoggerContext, namely the LoggerContext of my GlassFish server logging 
configuration. I debugged the startup process and found that in 
ClassLoaderContextSelector.locateContext(), the parent classloader is 
repeatedly looked up until the sun.misc.Launcher$ExtClassLoader is reached - 
this is because I placed the Log4j2 JARs in [...]/domains/domain1/lib/ext for 
them to be available to GlassFish itself. As the Log4j2 initialization of the 
application module didn't occur yet, it had no chance to associate the 
application LoggerContext with the application classloader.

I found a thread about TomEE that seems to describe the same problem here: 
http://tomee-openejb.979440.n4.nabble.com/log4j2-initialized-too-early-td4668307.html.
 In particular, the posting at 
http://tomee-openejb.979440.n4.nabble.com/log4j2-initialized-too-early-td4668307.html#a4668601
 says "log4J uses a servlet container initialzer to get web info which is of 
course initialized after openejb part of tomee and ejb are scanned (so loaded) 
before.".

The conclusion from that thread is to not use static Loggers in EJBs. But even 
if I do that, there's still another problem: I'm doing some application 
initialization in @Startup @Singleton EJBs in their @PostConstruct method. 
Those methods too are called before the servlet initialization started. This 
means that even if a get a Logger instance locally in such a method, it's still 
associated with that wrong LoggerContext of the GlassFish server logging 
configuration.

Just to be sure, I also tried to get a Logger instance in a business method of 
an EJB that is called from a JAX-RS method, i.e. after the servlet context was 
initialized. As expected, that instance does get the correct LoggerContext of 
the application module.

So the question is if there is a recommended way to have Log4j2 initialized on 
demand/programmatically for it to be ready before the servlet initialization? 
If there is one, I guess I'd have to use the isLog4jAutoInitializationDisabled 
parameter as described here: 
https://logging.apache.org/log4j/2.0/manual/webapp.html. The information on 
that page also makes me think that my use case is not really foreseen for 
"out-of-the-box" configuration of Log4j2 yet, since it only mentions servlet 
container initialization?


Best regards,
Joachim Kanbach

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-user-h...@logging.apache.org

Reply via email to