Have you tried using log4j as a server library instead of adding it to your deployment artifacts? If you do that, you should be able to avoid using log4j-web entirely as well which is mainly used for .war deployments.
On 3 March 2016 at 07:54, Joachim Kanbach <[email protected]> wrote: > 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: [email protected] > For additional commands, e-mail: [email protected] > > -- Matt Sicker <[email protected]>
