OpenTelemetry/Spring Boot — проблема с загрузкой классов с помощью вспомогательного классаJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 OpenTelemetry/Spring Boot — проблема с загрузкой классов с помощью вспомогательного класса

Сообщение Anonymous »

Я использую Java 21, Spring Boot 3.3.12, Otel Java Agent 2.21.0 и простое приложение Product Service.
Ниже приведен файл Dockerfile моего приложения:

Код: Выделить всё

FROM openjdk:21-jdk-slim

WORKDIR /app
ARG JAR_FILE=target/product-service-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar

EXPOSE 8080

COPY opentelemetry-javaagent.jar /opt/agent/opentelemetry-javaagent.jar
COPY my-otel-extension.jar /opt/agent/my-otel-extension.jar
COPY my-otel-extension-helper.jar /opt/agent/my-otel-extension-helper.jar

ENV OTEL_EXPORTER_OTLP_ENDPOINT=http://host.docker.internal:4318
ENV OTEL_SERVICE_NAME="product-service"

ENTRYPOINT ["java",
"-Xbootclasspath/a:/opt/agent/my-otel-extension-helper.jar",
"-javaagent:/opt/agent/opentelemetry-javaagent.jar",
"-Dotel.javaagent.extensions=/opt/agent/my-otel-extension.jar",
"-jar", "app.jar"]
Мое расширение OpenTelemetry содержит:
  • Пользовательский MySpanProcessor
    (ссылка: DemoSpanProcessor.java)
    Метод onEnd() переопределяется для вызова статического метода DynaPathRecorder.stopRecording() из моего вспомогательного JAR.
    Во время выполнения MySpanProcessor (из расширения) загружается с помощью ExtensionClassLoader OpenTelemetry, который ссылается на вспомогательный JAR в пути к классам загрузки.
    Поэтому вспомогательный класс правильно загружается загрузчиком классов, как ожидается.

    Код: Выделить всё

    @Override
    public void onEnd(ReadableSpan span) {
    SpanKind spanKind = span.getKind();
    if (spanKind == SpanKind.SERVER) {
    com.rz.javaagent.instr.ext.DynaPathRecorder.stopRecording();
    }
    }
    
  • Класс @Advice
    Простой @Advice.OnMethodEnter внедряет фрагмент в метод контроллера приложения.
    Внедренный код вызывает другой статический метод DynaPathRecorder.controllerEntry() из того же помощника JAR.
    Во время выполнения этот класс Advice (из расширения) загружается с помощью Spring Boot LaunchedClassLoader.
    Хотя вспомогательный JAR находится в пути к загрузочным классам, LaunchedClassLoader загружает сам вспомогательный класс вместо делегирования загрузчику классов загрузки.
    В результате в JVM существуют две копии вспомогательного класса — одна загружается ExtensionClassLoader и еще один от LaunchedClassLoader.

    Код: Выделить всё

    @Advice.OnMethodEnter
    public static void onEnter(@Advice.Origin String method) {
    com.rz.javaagent.instr.ext.DynaPathRecorder.controllerEntry();
    }
    
Я думаю, что механизм загрузки классов Springboot или Otel вызывает эту проблему.
Я бы хотел, чтобы вспомогательный класс всегда загружался загрузочным загрузчиком классов, гарантируя, что существует только один экземпляр, общий для кода @Advice и кода MySpanProcessor.

Подробнее здесь: https://stackoverflow.com/questions/797 ... lper-class
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»