gpt4 book ai didi

java - 使用 log4j2 API 在 EAR 中未检测到自定义插件

转载 作者:行者123 更新时间:2023-11-30 07:52:04 24 4
gpt4 key购买 nike

我正在从 log4j 迁移 EAR 应用程序至log4j2 。我有一些类在不同的 EAR jar 中扩展附加器、过滤器、布局,现在,我已将它们转换为插件。这意味着我在多个 jar 中有自定义插件(假设有 3 个 jar)。

我没有使用packages log4j2.xml 中的属性并使用 Dlog4j.configurationFile 初始化日志系统JVM 参数指向 log4j2.xml位置在META-INF耳朵。

在所有三个 jar 项目中添加以下插件不起作用。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>log4j-plugin-processor</id>
<goals>
<goal>compile</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<proc>only</proc>
<annotationProcessors>
<annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</execution>
</executions>
</plugin>

图案布局:在下面的图案布局中,e是自定义模式,其中编写了自定义模式转换器插件来转换此字符串。

<Pattern>%d %-5p [%c{1}] [EventId: %e] [%t] %m%n</Pattern>

上述模式布局的自定义转换器插件(在 jar1 中):

jar1 有 Log4J2Plugins.dat文件位于META-INF下在org.apache..文件夹。

@Plugin(name = "EventPatternConverter", category = "Converter")
@ConverterKeys({"e"})

public class EventPatternConverter extends LogEventPatternConverter {

protected EventPatternConverter(String name, String style) {
super(name, style);
}

public static EventPatternConverter newInstance(String[] options) {
return new EventPatternConverter("e", "e");
}

@Override
public void format(LogEvent event, StringBuilder toAppendTo) {
String eventId= "";
// Append empty string (OR) value
toAppendTo.append(eventId);
}
}

但是,我收到以下错误

ERROR Unrecognized format specifier [e]

甚至,没有一个自定义插件被识别为我得到 invalid element对于其余的自定义插件,它们都在 jar2、jar3 中可用,并且它们都有 Log4J2Plugins.dat文件。

ERROR File contains an invalid element or attribute "TestFilter"

我正在使用log4j-api-2.4.jar , log4j-core-2.4.jar , log4j-jcl-2.4.jar , log4j-web-2.4.1.jar , commons-logging-1.1.1.jar EAR 中的 jar 。

我已经定义了一个自定义模式转换器插件,并期望该转换器应用于所有模式布局,包括使用<patternlayout>定义的默认模式布局。 。这是对的吗?

如果是的话,如果有人遇到这个问题,请提供帮助,如果我在定义自定义插件时出错,请指导我,因为它们都没有从 EAR 中的 jar 中检测到。

最佳答案

编译自定义Plugin时,Log4J pom.xml定义了一个插件,该插件会自动在文件META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat中生成缓存数据您可以在 Maven 项目中的目标/类下看到它。

log4j-core-2.x.x.jar 还包含定义其缓存数据的 Log4j2Plugins.dat。

问题是使用 ShrinkWrap 测试 EAR 时会创建一个 JAR,并且通常会将 log4j-core-2.x.x.jar Log4j2Plugins.dat 添加到测试 JAR 中,因为它很可能位于类路径中的第一个。

这意味着您的自定义插件缓存丢失。

使用 ShrinkWrap 的解决方案是创建一个新的 Log4j2Plugins.dat,将任何所需的自定义插件缓存文件与核心合并,然后将其添加到 JAR 中。

以下函数实现了...

private static void mergeLog4J2Log4j2PluginsFile(JavaArchive ja, Class... uniqueJARClasses) {
// @Author: Johnathan Ingram <jingram@rogueware.org>
// Log4J2 uses /META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat within a JAR to define custom plugins
// This is automatically generated by the plugin defined in the log4j-core-2.x.x pom.xml when compiling your custom plugin
// The problem with shrinkwrap is that the JAR is not preserved and only a single
// /META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
// file can exist as JAR files cannot be added to a JAR file as a library.
// This is normally the default contained in log4j-core-2.x.x.jar which does not expose any custom plugins
// To rectify, both the core and the custom plugin JAR file Log4j2Plugins.dat need to be merged into a single Log4j2Plugins.dat
try {
// List of a unique class in each JAR containing a Log4j2Plugins.dat requiring merging
Vector<URL> datUrls = new Vector<URL>();
for (Class klass : uniqueJARClasses) {
// Find the JAR the class belongs to
URL classLoc = klass.getProtectionDomain().getCodeSource().getLocation();
URL resourceURL = classLoc.toString().endsWith(".jar")
? new URL("jar:" + URLDecoder.decode(classLoc.toString(), "UTF-8") + "!/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat")
: new URL(URLDecoder.decode(classLoc.toString(), "UTF-8") + "/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat");
datUrls.add(resourceURL);
}

// Use the Log4J2 PluginCache to build a merged Log4j2Plugins.dat
File mergedDatFile = new File("target/Log4j2Plugins.dat");
try (FileOutputStream fo = new FileOutputStream(mergedDatFile)) {
org.apache.logging.log4j.core.config.plugins.processor.PluginCache pc = new org.apache.logging.log4j.core.config.plugins.processor.PluginCache();
pc.loadCacheFiles(datUrls.elements());
pc.writeCache(fo);
}

// Replace the default Log4j2Plugins.dat if present
ja.delete("/META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat");
ja.addAsManifestResource(mergedDatFile, "org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat");

} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}

使用您的示例运行:

JavaArchive ja = ShrinkWrap.create(JavaArchive.class, "my-test.jar");
...
mergeLog4J2Log4j2PluginsFile(ja, org.apache.logging.log4j.core.config.plugins.processor.PluginCache.class, EventPatternConverter.class);

关于java - 使用 log4j2 API 在 EAR 中未检测到自定义插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33214821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com