Асинхронные методы выдают сообщение «Реализация JAXB-API не найдена в пути к модулю или пути к классам»

У меня есть проект, основанный на Java 17 и Springboot 3. Недавно я добавил в проект асинхронный метод. Класс асинхронной конфигурации следующий:

@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean(name = "taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

А асинхронный метод выглядит так:

@Async("taskExecutor")
public CompletableFuture<Response<Exception>> createOrUpdateEntryAsync(
        .....,
        @Nullable ProgressListener progressListener) {

    return CompletableFuture.supplyAsync(() -> createOrUpdateEntry(
        ......,
        progressListener));
}

Во время локальной разработки и отладки с использованием IntelliJ этот метод работает нормально. Однако после того, как я использовал Docker для упаковки его в образ (используя openjdk:17-jdk-slim в качестве базового образа) и развернул его на сервере, при вызове этого асинхронного метода возникает ошибка: «Реализация JAXB-API не была найдено по пути к модулю или пути к классам». Я искал ответ, нашел несколько подсказок и добавил следующую зависимость Maven, но это не решает проблему:

    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.3</version>
    </dependency>

Вот часть трассировки исключений ниже моих кодов проекта:

java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1760)
java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

Может ли кто-нибудь помочь мне в этом? Заранее благодарим за помощь!

jaxb-runtime должно быть достаточно, но попробуйте использовать современную версию библиотеки (больше шансов быть совместимой с последней весенней загрузкой) — текущая версия 4.0.5
J Asgarov 24.06.2024 13:16

Сейчас я использую jaxb-bom версии 4.0.2 для управления версией, но это не помогает. Я не понимаю, почему эти ошибки возникают только при использовании асинхронного метода, когда он запускается в контейнере докеров. Есть ли какой-нибудь трюк в докере, который я пропустил?

Vincent 24.06.2024 13:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я узнал, что пошло не так. JAXB API кажется невидимым в новом потоке, созданном асинхронным методом. Загрузчик контекстного класса должен быть установлен явно, как показано ниже:

@Async("taskExecutor")
public CompletableFuture<Response<Exception>> createOrUpdateEntryAsync(
        .....,
        @Nullable ProgressListener progressListener) {

    ClassLoader contextClassLoader = this.getClass().getClassLoader();
    log.debug("Context ClassLoader: " + contextClassLoader);

    return CompletableFuture.supplyAsync(() -> {
        Thread.currentThread().setContextClassLoader(contextClassLoader);
        createOrUpdateEntry(
        ......,
        progressListener));
    }
}

Другие вопросы по теме

Похожие вопросы

Пользовательский плагин Maven: как обрабатывать FileSet?
Почему мы используем новый оператор для доступа к вложенному статическому классу в Java?
Почему полученные сообщения не отображаются в пользовательском интерфейсе?
Плагин [id: 'kotlin-android', версия: '1.7.10'] не был найден ни в одном из следующих источников в Android Studio для Flutter
Как программно установить в Jetty 12 максимальный размер запроса?
Не удалось найти валидатор для ограничения «jakarta.validation.constraints.Pattern» — ошибка все еще появляется даже после удаления валидатора из класса
Свойство цвета строки состояния Android не применяется к действиям, выполненным из предустановки действий «Пустые представления»
Область столбца-заполнителя полосы прокрутки в стиле TableView
Невозможно получить доступ к классу Retrofit2.Response. Проверьте путь к классам вашего модуля на предмет отсутствующих или конфликтующих зависимостей
Ошибка запуска log4j2. Нераспознанный спецификатор преобразования и спецификатор формата