問題
使用maven-shade-plugin或者maven-assembly-plugin插件把項目打成一個可執行JAR包時,如果你引入了log4j2會出現如下問題:
ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
解決方法
pom中添加如下配置。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <finalName>${artifactId}-${env}-${version}</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>xxx.yyyy.zzz.Main</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.tooling</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer"/> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" /> </transformers> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.6.1</version> </dependency> </dependencies> </plugin>
原因分析
log4j2 是采用的插件式編程,當log4j2包編譯時,或者含有log4j2插件的包編譯時,會將需要加載的插件信息放在META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat這個文件中(包括官方logj42的原生插件),然后項目啟動的時候,log4j2會在各個jar包的META-INF目錄下掃描這個插件信息文件,然后去加載插件。
但是當項目被打成一個jar包時,如果兩個不同的jar包中都有Log4j2Plugins.dat 這個文件,就會出現問題,其中一個文件會被另一個覆蓋,導致項目啟動的時候有一個文件中的插件不能被正常加載,導致報錯。
解決這個問題就是當所有jar包被打成一個jar包時,需要對各個jar包中的Log4j2Plugins.dat進行合並,這就是maven-shade-plugin.log4j2-cachefile-transformer這個包所做的事情了。