Grzegorz Grzybek created LOG4J2-3040:
----------------------------------------

             Summary: ShutdownCallbackRegistry should be part of log4j-api, not 
core
                 Key: LOG4J2-3040
                 URL: https://issues.apache.org/jira/browse/LOG4J2-3040
             Project: Log4j 2
          Issue Type: Bug
            Reporter: Grzegorz Grzybek


I'm working on https://github.com/ops4j/org.ops4j.pax.logging/issues/395 
related to Pax Logging project, which implements OSGi Log specification based 
on 3 _backends_:
* Log4j1
* Logback
* Log4j2
and several _frontends_:
* Commons Logging
* JULI Logging
* javax.logging
* SLF4J
* Avalong
* Log4j1 (API)
* Log4j2 (API)
* JBoss Logging

Pax Logging implements own 
{{org.apache.logging.log4j.spi.LoggerContextFactory}}, where the 
{{org.apache.logging.log4j.spi.LoggerContext}} returned is managed by OSGi 
runtime (without using 
{{org.apache.logging.log4j.core.selector.ContextSelector}}).

The problem is that several libraries assume that some casts are possible. 
There was an elasticsearch problem described 
[here|https://groups.google.com/g/ops4j/c/yjqOzvrKRkc/m/DZeUSdZeCAAJ], where 
level was set through configuration and 
{{org.apache.logging.log4j.core.LoggerContext#getContext(boolean)}} explicitly 
calls (in {{org.apache.logging.log4j.core.config.Configurator#setLevel()}}):
{code:java}
public static LoggerContext getContext(final boolean currentContext) {
    return (org.apache.logging.log4j.core.LoggerContext) 
LogManager.getContext(currentContext);
}
{code}
assuming that {{org.apache.logging.log4j.LogManager#getContext(boolean)}} 
returns log4j-core specific implementation of the context.

With https://github.com/ops4j/org.ops4j.pax.logging/issues/395 there's 
different problem.

{{org.apache.logging.log4j.core.appender.mom.jeromq.JeroMqAppender}} (part of 
log4j-core library) [long time 
ago|https://github.com/apache/logging-log4j2/commit/a6af67c5d6faee5b4d422add674e4c518c33d528]
 started to use {{org.apache.logging.log4j.core.util.ShutdownCallbackRegistry}} 
for cleanup. Now this is moved to 
{{org.apache.logging.log4j.core.appender.mom.jeromq.JeroMqManager}}, but still 
there's this explicit code:
{code:xml}
if (enableShutdownHook) {
    SHUTDOWN_HOOK = ((ShutdownCallbackRegistry) 
LogManager.getFactory()).addShutdownCallback(CONTEXT::close);
{code}

While normally, LogManager.getFactor() returns an instance of 
{{org.apache.logging.log4j.core.impl.Log4jContextFactory}}, it's *not* 
guaranteed by {{org.apache.logging.log4j.LogManager#getFactory}} API and indeed 
- pax-logging-api's implementation returns a factory that doesn't implement 
{{ShutdownCallbackRegistry}}.

I tried two approaches:
# _move_ (in OSGi terms) some packages from log4j-core to pax-logging-api (for 
now, pax-logging-api only operates on log4j-api), howver, transitively I ended 
up with almost entire log4j-core inside pax-logging-api
# refactor log4j2 itself (locally) so {{ShutdownCallbackRegistry}} (and 
{{Cancellable}}) are part of {{org.apache.logging.log4j.spi}} package, but I 
ended with quite long list of errors from 
org.revapi:revapi-maven-plugin:0.11.1:check

Mind that even 
{{org.apache.logging.log4j.core.LoggerContext#setUpShutdownHook()}} correctly 
checks for the interface to be implemented:
{code:java}
final LoggerContextFactory factory = LogManager.getFactory();
if (factory instanceof ShutdownCallbackRegistry) {
{code}

It's *only* org.apache.logging.log4j.core.appender.mom.jeromq.JeroMqManager 
that blindly calls:
{code:java}
SHUTDOWN_HOOK = ((ShutdownCallbackRegistry) 
LogManager.getFactory()).addShutdownCallback(CONTEXT::close);
{code}

Summarizing - ideally (IMO) {{ShutdownCallbackRegistry}} should be part of the 
API, but if it's not possible, please fix {{JeroMqManager}} to check for the 
implementation.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to