Quarkus, Log4J 1-2 Bridge и Uber Jar

У меня есть этот код, который инициализирует контекст Log4J в моем приложении. Приложение разрабатывается с использованием Quarkus 2.16.7.Final. Контекст Log4j заключен в мой общий класс «loggingContext», который предоставляет метод «initialize», который можно использовать для инициализации контекста журналирования внутри более общего контекста приложения:

public synchronized void initialize(ApplicationContext currentApplicationContext) throws LoggingContextException {
    if (!isInitialized()) {
        File configurationFile = null;
        configurationFile = new File(getConfigurationContext().getLog4jFilePath());
        if (!configurationFile.exists()) {
            throw new LoggingContextException("Could not find LOG4J configuration file: \"" + getConfigurationContext().getLog4jFilePath() + "\".");
        }
        this.loggingId = currentApplicationContext.getApplicationName();
        try (FileInputStream fis = new FileInputStream(configurationFile);) {
            this.loggerContext = LoggerContext.getContext(getConfigurationContext().getClassLoader(), false, null);
            loggerContextOwnership = initLoggerContext(this.loggerContext, configurationFile);
            if (loggerContextOwnership) {
                System.out.println(loggingId + " - Logging Context INITIALIZED (LOG4J File Path: \"" + this.loggerContext.getConfiguration().getConfigurationSource().getFile() + "\"). <<<");
            } else {
                File configFile = loggerContext.getConfiguration().getConfigurationSource().getFile();
                if (!configFile.getAbsolutePath().equals(configurationFile.getAbsolutePath())) {
                    throw new LoggingContextException("Could not acquire LOG4J context ownership.");
                }
            }
        } catch (IOException e) {
            throw new LoggingContextException("Could not read LOG4J configuration file", e);
        }
        this.initialized = true;
        super.initialize(currentApplicationContext);
    }
}
private boolean initLoggerContext(LoggerContext loggerContext, File log4jConfigurationFile) {
    boolean hasOwnership = false;
    Configuration xmlConfig = ConfigurationFactory.getInstance().getConfiguration(null, "Application Framework LOG4J configuration", log4jConfigurationFile.toURI());
    File configFile = loggerContext.getConfiguration().getConfigurationSource().getFile();
    String key = getConfigurationContext().getLog4jFilePath();
    if (configFile == null) {
        loggerContext.setConfiguration(xmlConfig);
        hasOwnership = true;
        synchronized (log4jContextMap) {
            List<LOG4JContext> list = log4jContextMap.get(getConfigurationContext().getClassLoader()).computeIfAbsent(key, k -> {
                return new LinkedList<>();
            });
            list.add(this);
        }
    } else {
        if (!configFile.getAbsolutePath().equals(log4jConfigurationFile.getAbsolutePath())) {
            System.out.println(loggingId + " - WARNING: LOG4J Context already initialized (file: \"" + configFile.getAbsolutePath() + "\").");
            LoggingOwnershipMode loggingOwnershipMode = getConfigurationContext().getLoggingOwnershipMode();
            switch (loggingOwnershipMode) {
                case DEFAULT:
                    break;
                case FORCE:
                    loggerContext.setConfiguration(xmlConfig);
                    hasOwnership = true;
                    System.out.println(loggingId + " - WARNING: LOG4j Context has been reconfigured.");
                    break;
                default:
                    break;
            }
        } else {
            hasOwnership = true;
            synchronized (log4jContextMap) {
                List<LOG4JContext> list = log4jContextMap.get(getConfigurationContext().getClassLoader()).computeIfAbsent(key, k -> {
                    return new LinkedList<>();
                });
                list.add(this);
            }
        }
    }
    return hasOwnership;
}

У меня есть эти зависимости (иерархия зависимостей, представление Eclipse IDE):

Мой контекст Log4J работает (в Windows) только с конфигурацией FAST-JAR. Вместо этого я хотел бы использовать Uber-Jar. Используя Uber Jar, у меня есть следующий SystemOut:

Я не хочу использовать ведение журнала Jboss, поскольку это приложение представляет собой порт из приложения J2EE, которое активно использует log4j. Использование fast jar не считается окончательным решением. Я почти уверен, что проблема связана с механизмами загрузки классов, но мне хотелось бы ее преодолеть. Есть предложения?

Примечание

Я не уверен, что это связано с предложенным дублирующим вопросом. Мы создаем Uber-Jar в семантике Quarkus. maven-shade-plugin не используется, и вопрос связан с добавлением моста log4j1-2 в Quarkus, который работает в режиме fast-jar, но не в режиме uber-jar/legacy-jar.

Этот вопрос похож на: Динамическое добавление Log4J2 не работает с плагином maven-shade. Если вы считаете, что это другое, отредактируйте вопрос, поясните, чем он отличается и/или как ответы на этот вопрос не помогают решить вашу проблему.

Piotr P. Karwasz 30.08.2024 13:23

Если вы хотите объединить несколько JAR-файлов в один, вам необходимо правильно разрешить каждый конфликт имен файлов. В частности, файлы Log4j2Plugins.dat должны быть объединены соответствующим образом. См. обсуждение 2874 по той же проблеме.

Piotr P. Karwasz 30.08.2024 13:26

Привет Петр, спасибо за ваш комментарий. Кстати, я не использую какой-либо плагин maven-shade. Uber-jar здесь используется как особый режим для jar-файлов Quarkus. Решение, представленное в прикрепленном вами вопросе, не применимо для моего конкретного случая, поскольку я создаю приложение, используя: quarkus-maven-plugin

Lazarus 30.08.2024 15:14

Детали могут измениться, но причина одна и та же. Если два файла из разных файлов JAR имеют одинаковое имя, quarkus-maven-plugin удаляет один из них.

Piotr P. Karwasz 30.08.2024 16:36

СПАСИБО! Мне помогло удаление Log4j2Plugins.dat. Я знаю, что его следует объединить, но мне просто нужны плагины log4j2-CORE, которые должны быть аннотированы @Plugin, и мне их достаточно.

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

Ответы 1

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

Проблема была решена удалением из финального runner.jar файла "Log4j2Plugins.dat". этот файл следует объединить, а не удалить, но мне просто нужны плагины log4j2-CORE, которые должны быть помечены @Plugin, и мне их достаточно.

Предупреждения Quarkus достаточно, чтобы понять, что проблема в файле (упаковке uber-jar):

[ПРЕДУПРЕЖДЕНИЕ] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Обнаружены зависимости с повторяющимися файлами. Зависимости [org.apache.logging.log4j:log4j-1.2-api::jar:2.19.0[пути: H:\Maven\org\apache\logging\log4j\log4j-1.2-api\2.19.0\log4j -1.2-api-2.19.0.jar;], org.apache.logging.log4j:log4j-core::jar:2.19.0[пути: H:\Maven\org\apache\logging\log4j\log4j-core \2.19.0\log4j-core-2.19.0.jar;], org.apache.logging.log4j:log4j-web::jar:2.19.0[пути: H:\Maven\org\apache\logging\log4j \log4j-web\2.19.0\log4j-web-2.19.0.jar;]] содержат повторяющиеся файлы, например. META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat

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