-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Labels
bugSomething isn't workingSomething isn't workingneeds triageNew issue that requires triageNew issue that requires triage
Description
Describe the bug
When using the JUL bridge of Log4j (org.apache.logging.log4j:log4j-jul) together with the io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17 library, there is a circular dependency in the initialization of the logger context.
- Anything triggers the context initialization
- Log4j attempts to construct the OTEL appender
- The OTEL appender eagerly gets
GlobalOpenTelemetry GlobalOpenTelemetryrequests a JUL logger- The JUL logging bridge finds a partially initialized context and fails to construct a logger
Steps to reproduce
- Use the following dependencies together:
io.opentelemetry.instrumentation:opentelemetry-log4j-appender-2.17:2.24.0-alphaor2.25.0-alphaor2.26.0-alphaorg.apache.logging.log4j:log4j-api:2.25.3org.apache.logging.log4j:log4j-core:2.25.3org.apache.logging.log4j:log4j-jul:2.25.3
- Configure log4j to use an OpenTelemetry appender, e.g. through log4j2.xml
- Write a minimal application that only creates a logger (
LogManager.getLogger(MyClass.class)) - Run it while setting the system property
java.util.logging.managertoorg.apache.logging.log4j.jul.LogManager
Expected behavior
The logger is successfully initialized
Actual behavior
The initialization fails with
2026-03-19T09:28:35.765558700Z main ERROR Unable to create Lookup for ctx
java.lang.NullPointerException: Cannot invoke "java.util.List.size()" because "org.apache.logging.log4j.core.impl.ThreadContextDataInjector.SERVICE_PROVIDERS" is null
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector.getProviders(ThreadContextDataInjector.java:284)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector.access$000(ThreadContextDataInjector.java:60)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector$AbstractContextDataInjector.<init>(ThreadContextDataInjector.java:95)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector$ForDefaultThreadContextMap.<init>(ThreadContextDataInjector.java:116)
at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createDefaultInjector(ContextDataInjectorFactory.java:86)
at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOfProperty(LoaderUtil.java:365)
at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createInjector(ContextDataInjectorFactory.java:71)
at org.apache.logging.log4j.core.lookup.ContextMapLookup.<init>(ContextMapLookup.java:34)
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.apache.logging.log4j.core.util.ReflectionUtil.instantiate(ReflectionUtil.java:188)
at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:90)
at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:109)
at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:138)
at org.apache.logging.log4j.core.config.DefaultConfiguration.<init>(DefaultConfiguration.java:46)
at org.apache.logging.log4j.core.LoggerContext.<init>(LoggerContext.java:132)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(ClassLoaderContextSelector.java:265)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector.java:224)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:142)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:125)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:119)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:155)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:48)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:139)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:138)
at org.apache.logging.log4j.jul.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:34)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.log4j.jul.LogManager.getLogger(LogManager.java:81)
at java.logging/java.util.logging.LogManager.demandLogger(LogManager.java:521)
at java.logging/java.util.logging.LogManager.demandLogger(LogManager.java:517)
at java.logging/java.util.logging.Logger.demandLogger(Logger.java:656)
at java.logging/java.util.logging.Logger.getLogger(Logger.java:720)
at java.logging/java.util.logging.Logger.getLogger(Logger.java:703)
at io.opentelemetry.api.GlobalOpenTelemetry.<clinit>(GlobalOpenTelemetry.java:69)
at io.opentelemetry.instrumentation.log4j.contextdata.v2_17.OpenTelemetryContextDataProvider.<clinit>(OpenTelemetryContextDataProvider.java:31)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:200)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:549)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at java.base/java.util.ServiceLoader$ProviderImpl.newInstance(ServiceLoader.java:789)
at java.base/java.util.ServiceLoader$ProviderImpl.get(ServiceLoader.java:729)
at java.base/java.util.ServiceLoader$3.next(ServiceLoader.java:1403)
at org.apache.logging.log4j.util.ServiceLoaderUtil$ServiceLoaderSpliterator.tryAdvance(ServiceLoaderUtil.java:106)
at java.base/java.util.Spliterator.forEachRemaining(Spliterator.java:332)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector.getServiceProviders(ThreadContextDataInjector.java:86)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector.<clinit>(ThreadContextDataInjector.java:69)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector$AbstractContextDataInjector.<init>(ThreadContextDataInjector.java:95)
at org.apache.logging.log4j.core.impl.ThreadContextDataInjector$ForDefaultThreadContextMap.<init>(ThreadContextDataInjector.java:116)
at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createDefaultInjector(ContextDataInjectorFactory.java:86)
at org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOfProperty(LoaderUtil.java:365)
at org.apache.logging.log4j.core.impl.ContextDataInjectorFactory.createInjector(ContextDataInjectorFactory.java:71)
at org.apache.logging.log4j.core.lookup.ContextMapLookup.<init>(ContextMapLookup.java:34)
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.apache.logging.log4j.core.util.ReflectionUtil.instantiate(ReflectionUtil.java:188)
at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:90)
at org.apache.logging.log4j.core.lookup.Interpolator.<init>(Interpolator.java:109)
at org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(AbstractConfiguration.java:138)
at org.apache.logging.log4j.core.config.NullConfiguration.<init>(NullConfiguration.java:32)
at org.apache.logging.log4j.core.LoggerContext.<clinit>(LoggerContext.java:111)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(ClassLoaderContextSelector.java:265)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(ClassLoaderContextSelector.java:224)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:142)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:125)
at org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(ClassLoaderContextSelector.java:119)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:155)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:48)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:139)
at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:557)
at io.vertx.core.logging.Log4j2LogDelegateFactory.isAvailable(Log4j2LogDelegateFactory.java:27)
at io.vertx.core.internal.logging.LoggerFactory.configureWith(LoggerFactory.java:59)
at io.vertx.core.internal.logging.LoggerFactory.initialise(LoggerFactory.java:42)
at io.vertx.core.internal.logging.LoggerFactory.<clinit>(LoggerFactory.java:28)
The stack trace clearly shows the circular dependency
Javaagent or library instrumentation version
2.24.0-alpha through 2.26.0-alpha
Environment
JDK: Temurin 21
OS: Windows
Additional context
No response
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingneeds triageNew issue that requires triageNew issue that requires triage