Log4j2自定义插件 – 使用Maven Assembly Plugin进行注释处理

我对Maven不太熟悉,我昨天开始使用它,但我喜欢它。 在我的项目中,我使用Log4j2库进行日志记录,由于高级插件(如appender,转换器)的不足, 我需要使用自定义插件log4j-apilog4j-core (还有一堆其他库)作为依赖项添加到与我的项目关联的pom.xml中。 实际上我使用的是Log4j的2.0版本。

Log4j使用注释处理来预加载标记为@Plugin类。 据我所知,在较早版本的log4j中,必须在pom.xml中指定其他插件条目才能触发插件处理,或者必须在配置文件中的packages属性中键入包含自定义插件的packages ( https:/ /logging.apache.org/log4j/2.x/manual/configuration.html#ConfigurationSyntax )。 但是自2.0-rc2以来,这不受支持。

在v2.0中,只要log4j-core可用于构建引擎,就应该自动完成。 myproject-0.0.1-SNAPSHOT.jar / META-INF / org / apache / logging / log4j / core / config / plugins /中有一个文件Log4j2Plugins.dat ,它包含我的自定义插件的映射 – 没关系。

对于使用Maven进行构建,我还使用了Maven Assembly Plugin 。 它的目标single是捆绑到package阶段。 打包项目后,我自然在目标目录中有一个额外的jar – myproject-0.0.1-SNAPSHOT-jar-with-dependencies.jar 。 但是,此jar中的Log4j2Plugins.dat文件包含原始插件的映射,与log4j-core库中的文件相同。 这就是问题,因为它没有任何对我的自定义插件的引用。 似乎来自myproject-0.0.1-SNAPSHOT.jar的文件被log4j库中的原始文件覆盖,但我不确定是什么情况。

因此,当我运行myproject-0.0.1-SNAPSHOT-jar-with-dependencies.jar时 ,log4j无法从我的项目中找到插件类。 我认为myproject-0.0.1-SNAPSHOT.jar运行正常,但是如果没有依赖项我就无法运行它。

配置中的packages属性应该在2.0.1版本中重新启用,但如果我不想等待发布,我必须使用注释处理方法。

你知道如何解决它吗?


我尝试使用log4j的2.0-rc1版本运行它,其中配置元素的packages属性可用。 结果是: log4j成功加载了我的自定义插件的类 。 但是,还有很多其他错误(在此特定版本中出现)使程序更加无法使用。

这是一个好点,它确保了如果在下一版本2.0.1中启用packages属性,我的插件起作用。 它应该根据此问题跟踪恢复: https : //issues.apache.org/jira/browse/LOG4J2-741


添加了我的pom.xml

  4.0.0 com.jjurm twbot 0.0.1-SNAPSHOT jar twbot http://maven.apache.org  UTF-8      org.apache.maven.plugins maven-compiler-plugin 3.1  1.7 1.7       maven-assembly-plugin 2.4   jar-with-dependencies    com.jjurm.twbot.system.Run      make-assembly  package   single    jar-with-dependencies    com.jjurm.twbot.system.Run           junit junit 3.8.1 test   org.mariadb.jdbc mariadb-java-client 1.1.7   joda-time joda-time 2.3   commons-configuration commons-configuration 1.10   net.snaq dbpool 6.0   org.fusesource.jansi jansi 1.11   org.apache.logging.log4j log4j-core 2.0   org.apache.logging.log4j log4j-api 2.0   org.slf4j slf4j-api 1.7.7   org.apache.logging.log4j log4j-slf4j-impl 2.0   commons-jxpath commons-jxpath 1.3   net.sourceforge.htmlunit htmlunit 2.15    

我认为问题源于将依赖项打包到jar中。 快速浏览代码,看起来插件处理器会覆盖它处理的每组插件的插件dat文件。 我的猜测是,在打包过程中,处理自定义插件并将其写入dat文件,然后在处理log4j依赖项以包含在包中时覆盖。 可能有更好的解决方案,但我不建议您执行以下操作之一:

  1. 不要将依赖项打包到jar中。 只需打包项目,然后在执行时将依赖项包含在类路径中。 即使您想将所有内容打包在一个便携式jar中,执行此操作也可以至少确认您的插件是否被覆盖,或者是否存在其他错误。

  2. 为自定义插件创建一个单独的项目,将其与主项目分开打包,然后将生成的jar包含为依赖项。 与选项1一样,请确保您不在此包中包含log4j jar。 一旦你创建了自定义插件jar,你可以将它与主jar中的其他依赖项一起打包,它应该可以正常工作,因为你的自定义插件jar将有自己的插件dat文件。

祝你好运!

Log4j 2 issue 673中提到了另一种解决方案。 使用maven shade插件与特定的变压器而不是maven组件插件 。

  org.apache.maven.plugins maven-shade-plugin 2.4.3        com.github.edwgiz maven-shade-plugin.log4j2-cachefile-transformer 2.6.1     make-assembly package  shade     

如果我准确理解它,变换器通过正确合并来自所有依赖项的Log4j2Plugins.dat和主jar来创建Log4j2Plugins.dat文件,即将包含所有插件。