org.apache.logging.log4j.core.pattern.PatternParser не может получить доступ к методу "newInstance" класса подключаемого модуля Custom Pattern Converter - PullRequest
0 голосов
/ 05 января 2019

Я использую конвертер пользовательских шаблонов log4j. Во время выполнения, когда он пытается вызвать метод newInstance класса преобразователя, он завершается ошибкой:

"Ошибка создания конвертера для cm java.lang.IllegalAccessException: Класс org.apache.logging.log4j.core.pattern.PatternParser не может получить доступ к члену класса com.test.plugin.LogMaskingConverter с помощью модификаторы "public static" "

После отладки я обнаружил, что «newInstance» вызывается с помощью Reflection и в классе Reflection перед вызовом метода, который он вызывает «isSameClassPackage» и возвращает false.

одна из возможных причин может заключаться в том, что для загрузки основного и преобразовательного классов используются разные загрузчики классов.

Я попробовал решение, приведенное в приведенной ниже ветке, а также добавил конфигурацию плагина в pom.xml, но ничего из этого не сработало.

В конфигурации log4j2 не будет загружен конвертер пользовательских шаблонов

LogMaskingConverter.java

package com.test.plugin;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import   org.apache.logging.log4j.core.pattern.LogEventPatternConverter;

@Plugin(name = "LogMaskingConverter", category = "Converter")
@ConverterKeys({"cm"})
class LogMaskingConverter extends LogEventPatternConverter {
  private static final String NAME = "cm";
  private static final String JSON_REPLACEMENT_REGEX = "\"\\$1\":  \"****\"";
  private static final String JSON_KEYS = String.join("|", new    String[]{"ssn", "private", "creditCard"});
  private static final Pattern JSON_PATTERN = Pattern.compile("(${ssn|card}): ([^]+)");

  private static final LogMaskingConverter INSTANCE = new LogMaskingConverter();

  private LogMaskingConverter() {
    super(NAME, NAME);
  }

  public static LogMaskingConverter newInstance(final String[] options) {

    return INSTANCE;
}

@Override
public void format(LogEvent event, StringBuilder outputMessage) {
    String message = event.getMessage().getFormattedMessage();
    String maskedMessage = message;

    if (event.getMarker().getName() == LoggingMarkers.JSON.getName()) {
        try {
            maskedMessage = mask(message);

        } catch (Exception e) {
            maskedMessage = message; // Although if this fails, it may be better to not log the message
        }
    }

    outputMessage.append(maskedMessage);
}

private String mask(String message) {
    StringBuffer buffer = new StringBuffer();
    Matcher matcher = JSON_PATTERN.matcher(message);

    while (matcher.find()) {
        matcher.appendReplacement(buffer, JSON_REPLACEMENT_REGEX);
    }

    matcher.appendTail(buffer);

    return buffer.toString();
}
}

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config"
status="all" packages="com.test.plugin">
<Appenders>
    <Console name="console" target="SYSTEM_OUT">
        <PatternLayout pattern=" %-6level %cm  %d{HH:mm:ss.SSS}  %msg%n" />
    </Console>
</Appenders>
<Loggers>
    <Logger level="all" />
    <root level="all">
        <appender-ref ref="console" level="TRACE" />
    </root>
</Loggers>
</Configuration>

основной класс

package com.test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.test.plugin.LoggingMarkers;


public class TestLogging {

public static final Logger logger = LoggerFactory.getLogger(TestLogging.class);


public TestLogging() {
    logger.info("test info");
    logger.debug(LoggingMarkers.JSON, "{\"ssn\": \"1234567890\"}");
}

public static void main(String[] args) {
    new TestLogging();


}
}
...