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

Java 使用log4j2 API在EAR中未检测到自定义插件,java,logging,log4j,log4j2,apache-commons-logging,Java,Logging,Log4j,Log4j2,Apache Commons Logging,我正在将EAR应用程序从log4j迁移到log4j2。我在EAR的不同jar中扩展了appender、filter和layouts类,现在,我已经将它们转换为插件。这意味着我在多个jar中有自定义插件(假设有3个jar) 我没有使用log4j2.xml中的packages属性,而是使用指向EAR的META-INF位置的Dlog4j.configurationFileJVM参数初始化日志系统 在所有三个jar项目中添加下面的插件不起作用 <plugin> <

我正在将EAR应用程序从
log4j
迁移到
log4j2
。我在EAR的不同jar中扩展了appender、filter和layouts类,现在,我已经将它们转换为插件。这意味着我在多个jar中有自定义插件(假设有3个jar)

我没有使用
log4j2.xml
中的
packages
属性,而是使用指向EAR的
META-INF
位置的
Dlog4j.configurationFile
JVM参数初始化日志系统

在所有三个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>
用于上述模式布局的自定义转换器插件(jar1):

jar1在
org.apache..
文件夹中的
META-INF
下有
Log4J2Plugins.dat
文件

@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]
甚至,没有一个自定义插件被识别为我得到的
无效元素
,其余的自定义插件都在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

我已经定义了一个自定义模式转换器插件,希望该转换器能够应用于所有模式布局,包括使用
定义的默认模式布局。是这样吗


如果是,请帮助,如果有人面临这个问题,并指导我,如果我在定义自定义插件的错误,因为他们都没有得到从JAR在耳朵检测到

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

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

问题是,在使用包覆膜收缩器测试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);
  }
}
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);