Skip to content

Reflection in Logback instrumentation breaks Android support #13230

@bencehornak

Description

@bencehornak

Describe the bug

The Logback instrumentation crashes on Android since version 2.11.0, because Android doesn't support the reflection that was introduced in #12513. In particular the crash occurs during the class initialization of LoggingEventMapper, when it refers to java.lang.ClassValue, which is absent on Android below API level 34.

private static final ClassValue<FieldReader> valueField =
new ClassValue<FieldReader>() {
@Override
protected FieldReader computeValue(Class<?> type) {
return createFieldReader(type);
}
};

Steps to reproduce

Configure Logback to use the OpenTelemetryAppender on Android:

logback.xml

<configuration>
  <root>
    <appender name="opentelemetry" class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender" />
  </root>
</configuration>

And then initialize logback.

Expected behavior

The LoggingEventMapper class should carefully check for the existence of the ClassValue class (just like it does in supportsLogstashMarkers() with other classes) and it should only try to instantiate ClassValue, if it is available. Otherwise it should continue without the Logstash functionality added in #12513.

Actual behavior

The LoggingEventMapper class crashes on Android during the class initialization:

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/ClassValue;
	at io.opentelemetry.instrumentation.logback.appender.v1_0.internal.LoggingEventMapper.builder(LoggingEventMapper.java:105)
	at io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender.start(OpenTelemetryAppender.java:82)
	at ch.qos.logback.core.joran.action.AppenderAction.end(Unknown Source:13)
	at ch.qos.logback.core.joran.spi.Interpreter.callEndAction(Unknown Source:23)
	at ch.qos.logback.core.joran.spi.Interpreter.endElement(Unknown Source:34)
	at ch.qos.logback.core.joran.spi.Interpreter.endElement(Unknown Source:11)
	at ch.qos.logback.core.joran.spi.EventPlayer.play(Unknown Source:84)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(Unknown Source:16)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(Unknown Source:18)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(Unknown Source:8)
	at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(Unknown Source:24)
	at ch.qos.logback.classic.util.ContextInitializer.autoConfig(Unknown Source:32)
    ...
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.ClassValue" on path: DexPathList[[...]]
	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)

Javaagent or library instrumentation version

2.12.0

Environment

JDK: Android
OS: Android (API level 29)

Additional context

I will submit a bugfix in the next days, if I have some free time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds triageNew issue that requires triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions