You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Matt Sicker <bo...@gmail.com> on 2016/06/20 17:14:46 UTC

Re: 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?

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 <jo...@gmx.de> 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: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>


-- 
Matt Sicker <bo...@gmail.com>

Re: 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?

Posted by Ralph Goers <ra...@dslextreme.com>.
From what I am reading, that is what he is doing.

As you noted, the ClassLoaderContextSelect tries to associate the Logger being created with the correct LoggerContext - which should be the LoggerContext associated with the ClassLoader for the class obtaining the Logger.  It sounds like it some of the cases it is not locating that ClassLoader.  I would need to know what the class loader hierarchy looks like to understand why it isn’t finding it.

Ralph



> On Jun 20, 2016, at 10:14 AM, Matt Sicker <bo...@gmail.com> wrote:
> 
> 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 <jo...@gmx.de> 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: log4j-user-unsubscribe@logging.apache.org
>> For additional commands, e-mail: log4j-user-help@logging.apache.org
>> 
>> 
> 
> 
> -- 
> Matt Sicker <bo...@gmail.com>



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