Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
-
None
Description
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, 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()):
public static LoggerContext getContext(final boolean currentContext) { return (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(currentContext); }
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 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:
if (enableShutdownHook) { SHUTDOWN_HOOK = ((ShutdownCallbackRegistry) LogManager.getFactory()).addShutdownCallback(CONTEXT::close);
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:
final LoggerContextFactory factory = LogManager.getFactory(); if (factory instanceof ShutdownCallbackRegistry) {
It's only org.apache.logging.log4j.core.appender.mom.jeromq.JeroMqManager that blindly calls:
SHUTDOWN_HOOK = ((ShutdownCallbackRegistry) LogManager.getFactory()).addShutdownCallback(CONTEXT::close);
Summarizing - ideally (IMO) ShutdownCallbackRegistry should be part of the API, but if it's not possible, please fix JeroMqManager to check for the implementation.