logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Joachim Kanbach" <jo...@gmx.de>
Subject Is there an easy/recommended way to initialize Log4j2 so it works properly in a @Startup @Singleton EJB, or in a static EJB class member?
Date Thu, 03 Mar 2016 13:54:45 GMT
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-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org

View raw message