When loading log4j2 when starting fatjar

I am working on a project in which I use log4j2 logging. when developing in intellij, everything works fine, and logging is done as expected. log4j2.xml is connected through the java property passed to jvm when launched through the intellij settings. but as soon as I try to start the standalone gradle built-in jug, I have the following problems:

java -Dlog4j.debug=true -Dlog4j.configurationFile=/home/aaa/log4j2.xml -jar /home/aaa/myjar-SNAPSHOT.jar 

exceptions:

 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 No log4j2 configuration file found. Using default configuration: logging only errors to the console. 

I don’t even understand where these [thread] s came from, since I get the same error even when using a simple simple configuration in my log4j2:

 <?xml version="1.0" encoding="UTF-8" ?><Configuration status="WARN" monitorInterval="86400"> <Appenders> <Console name="console-log" target="SYSTEM_OUT"> <PatternLayout pattern="%-5p %d{yyyy-MM-dd HH:mm:ss.SSS} ${hostName} %c{1} %msg %throwable{7}%n"/> </Console> </Appenders> <Loggers> <Root level="info" additivity="false"> <AppenderRef ref="console-log"/> </Root> </Loggers> 

Any thoughts are welcome. thanks.

+5
source share
4 answers

in fatJar, dependencies can provide log4j-provider.properties in META-INF, which cause this problem,

delete it in the gradle task:

 task fatJar(type: Jar) { manifest { attributes 'Implementation-Title': 'project', 'Implementation-Version': project.version, 'Main-Class': 'com.sample.CLI' } baseName = project.name + '-all' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it).matching { exclude 'META-INF/**.RSA' exclude 'META-INF/MANIFEST.MF' exclude 'META-INF/log4j-provider.properties' } } } with jar } 
+1
source

The problem is described here: https://issues.apache.org/jira/browse/LOG4J2-673

Unfortunately, at the moment there is only a solution for maven-shade-plugin: https://github.com/edwgiz/maven-shaded-log4j-transformer

 <plugins> <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> <finalName>${project.artifactId}${appSuffix}</finalName> <transformers> ... <transformer implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer"> </transformer> </transformers> ... </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.1</version> </dependency> </dependencies> </plugin> </plugins> 
+1
source

LoggerContextFactory associates the Log4j API with its implementation. Log4j LogManager finds the LoggerContextFactory by looking for all instances of META-INF/log4j-provider.properties , the standard java.util.Properties file, and then checking each to make sure that it specifies a value for the Log4jAPIVersion property that matches the version required by LogManager.

Enabling fat jar, you can also explicitly tell log4j2 to use LoggerContextFactory in your application:

 System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.core.impl.Log4jContextFactory") 

or as indicated in the log4j-provider.properties file included in the log4j-core jar.

+1
source

When you launch the application from the IDE, the jar starts without dependency injection and you have no log settings conflicts. But when you convert the application to a fat jar, then all the dependencies will be inserted into your jar project file, and your log4j parameters, which come from external jar files (dependencies), may be conflicting, while the fatJar process combines them into one artifact.

In this case, I think your "Log4j2Plugins.dat" files may be conflicting. Of course, you can open the fatJar file using a zip editor (for example: 7Zip), go to fatJar as shown below, and delete one of the conflicting files (you can choose the smallest one) from your fatJar. Launch fatJar and verify that the log works correctly.

\ META-INF \ org \ Apache \ Logging \ log4j \ kernel \ Config \ Plugins \ Log4j2Plugins.dat

Now we can check the dependencies (artifacts) and find which ones contain the Log4j2Plugins.dat files. That way, you can exclude modules that have a file from your build tool, and then the process for creating fatJar will exclude conflicting files, and your new fatJar file may start logging as expected.

In my case, the fatJar module imports some other modules from Spring Boot, and when I exclude conflicting logging libraries, my fatJar starts to log without any errors.

configurations { all*.exclude module: 'spring-boot' all*.exclude module: 'spring-boot-starter-logging' all*.exclude module: 'logback-classic' all*.exclude module: 'commons-logging' }

0
source

Source: https://habr.com/ru/post/1208588/


All Articles