[ 
https://issues.apache.org/jira/browse/LOG4J2-1606?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16189185#comment-16189185
 ] 

Robert Turner edited comment on LOG4J2-1606 at 10/3/17 2:41 AM:
----------------------------------------------------------------

Also affects 2.9.1.

So I've been fighting with this issue all night, reading Tomcat code, reading 
log4j code, etc. Basically I've got a circular problem, that I cannot seem to 
fix. Here's the two options I've worked through:

1. Used the automatic configuration; results in my contextDestroyed() being 
unable to log (as per the description of this Jira)
2. Used manual configuration, with log4j configured first; results in the file 
being created without being able to read lookups from the web context. (so I 
get a file named  ${web:contextPath}}

What I've managed to determine so far is that:
* Tomcat will execute all ServletContextInitializers (SCIs) after having 
constructed the list of ServletContextListeners (SCLs) from the web.xml file. 
This causes any dynamic listeners to be added at the end, and thus executed in 
reverse order for contextDestroyed().
* If I try to control the initialization order manually, I always see log4j 
being initialized before my contextInitialized() is invoked (likely due to some 
call to LoggerFactory.getLogger() or something -- I haven't tried building 
everything from source to putting a debugger on it yet). This results in the 
ServletContext not being tracked for some reasons, and the web lookups not 
working.

Moreover, I think there is a general sequencing issue to be concerned about 
here. The initialization and uninitialization are not going to be executed in 
the same "order" in the sequence. log4j initialization occurs when the SCI 
runs, and then the remaining SCLs run. During shutdown, the SCLs run, but the 
log4j un-initialization occurs first (so long as no other dynamic listeners 
have been added), and then the remaining SCLs execute, resulting in inverse 
order with respect to log4j.

**EDIT: Note that this next item won't work as written because addListener() 
cannot be called outside of an SCI**
The only solution I have come up with (but not yet verified) is to create a 
separate SCL, that is dynamically registered during my normal SCL 
initialization, so that it gets registered after log4j listener. and thus gets 
executed before log4j during shutdown. This is far from ideal, as it's not 
really symmetric, but it probably will give the desired result.


was (Author: [email protected]):
Also affects 2.9.1.

So I've been fighting with this issue all night, reading Tomcat code, reading 
log4j code, etc. Basically I've got a circular problem, that I cannot seem to 
fix. Here's the two options I've worked through:

1. Used the automatic configuration; results in my contextDestroyed() being 
unable to log (as per the description of this Jira)
2. Used manual configuration, with log4j configured first; results in the file 
being created without being able to read lookups from the web context. (so I 
get a file named  ${web:contextPath}}

What I've managed to determine so far is that:
* Tomcat will execute all ServletContextInitializers (SCIs) after having 
constructed the list of ServletContextListeners (SCLs) from the web.xml file. 
This causes any dynamic listeners to be added at the end, and thus executed in 
reverse order for contextDestroyed().
* If I try to control the initialization order manually, I always see log4j 
being initialized before my contextInitialized() is invoked (likely due to some 
call to LoggerFactory.getLogger() or something -- I haven't tried building 
everything from source to putting a debugger on it yet). This results in the 
ServletContext not being tracked for some reasons, and the web lookups not 
working.

Moreover, I think there is a general sequencing issue to be concerned about 
here. The initialization and uninitialization are not going to be executed in 
the same "order" in the sequence. log4j initialization occurs when the SCI 
runs, and then the remaining SCLs run. During shutdown, the SCLs run, but the 
log4j un-initialization occurs first (so long as no other dynamic listeners 
have been added), and then the remaining SCLs execute, resulting in inverse 
order with respect to log4j.

The only solution I have come up with (but not yet verified) is to create a 
separate SCL, that is dynamically registered during my normal SCL 
initialization, so that it gets registered after log4j listener. and thus gets 
executed before log4j during shutdown. This is far from ideal, as it's not 
really symmetric, but it probably will give the desired result.

> log4j-web deinitalizes the Logger too early if listeners defined in web.xml 
> use it 
> -----------------------------------------------------------------------------------
>
>                 Key: LOG4J2-1606
>                 URL: https://issues.apache.org/jira/browse/LOG4J2-1606
>             Project: Log4j 2
>          Issue Type: Bug
>          Components: Web/Servlet
>    Affects Versions: 2.6.2
>         Environment: Java8, Linux/Mac, Tomcat
>            Reporter: Lukas Vogel
>
> We use log4j in a Apache Tomcat environment.
> In the web.xml file we define a custom ServerStartup listener that 
> initializes the DB etc and logs both in contextInitialized and 
> contextDestroyed.
> If we use the log4j-web package the class Log4jServletContainerInitializer 
> initializes the logger and adds a Log4jServletContextListener to the 
> ServletContext. Since this listener is added after our listener the method 
> Log4jServletContextListener#contextDestroyed is called before our listener's 
> contextDestroyed method. Thus the Logger is de-initialized too early.
> We could disable auto initialization and initialize the logger ourselves but 
> then doing it in the listener is too late since the WebService-framework 
> (Metro glassfish) initializes the webservice endpoints before the listener. 
> Since we use static logger variables in those webservice classes this would 
> trigger the message "StatusLogger no log4j configuration found..."  because 
> the logger was not yet initialized.
> One possible patch we see is that we make an option to manually add the 
> Log4jServletContextListener:
> In Log4jServletContainerInitializer we would put an "if (! Manually added)" 
> around the  call "servletContext.addListener(new 
> Log4jServletContextListener());" and then we could manually add it to the 
> listeners in web.xml
> If you have any other suggestions I would be glad to hear them.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to