Specifying Log4j2 Configuration File When Using Executable JAR
For others who may have this issue...
- Make sure your -Dlog4j.configurationFile options occur before your '-jar' not after. Might seem obvious, but saw that mistake once.
- Try treating the file location as a url and see if that works. I.e. escape spaces with %20 etc. Also use 'file://path', replace backslashes with forwardslashes.
- Windows paths can be written as file://c:/path/to/log4j2.xml
Hence if you have a log4j2.xml in your program folder for your exampleApp in C:\Program Files\ExampleApp
then...
java.exe -Dlog4j.configurationFile=file://c:/program%20files/exampleapp/log4j2.xml -jar exampleApp.jar ...
...should work
I solved the problem of specifying the location of log4j2 configuration in a runnable Jar that I created from Eclipse by including this in my java code:
System.setProperty("log4j.configurationFile", "resources/log4j2.xml");
I have a package and so I needed to specify the path to my "resources" folder (in my "src" folder in Eclipse):
System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");
Notice I didn't include "src" in my path and I think it's the path in the "bin" folder that's required: ie in my case "com/company/app/resources/log4j2.xml"
My configuration file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level - %msg%n"/>
</Console>
<RollingFile
name="RollingFile"
fileName="${sys:logFilename}"
filePattern="${sys:logFilename}-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
</root>
</loggers>
Also notice I dynamically assign the rolling log file path + name "${sys:logFilename}" by including this in my java code:
System.setProperty("logFilename", "logs/myApp.log");
In order to get these 2 dynamic System.setProperty assignments to work they need to execute before the "getLogger" statement and so my java code looks like:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyTestLoggingClass {
public static Logger logger = null;
...................
setUpLogging();
...............
public static void setUpLogging() {
System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");
System.setProperty("logFilename", "logs/myApp.log");
logger = LogManager.getLogger(Logger.class.getName());
}
}
Having "logger" declared at the start of my class (but without invoking "getLogger" before my 2 System.setProperty statements) enables me to reference "logger" in other methods. I am obliged to initialise it though and so I chose "null" but then later update it with the "getLogger" statement - given this I can't make it "final" (can only assign it once) but can make it static - a constant class variable.
nb the 2 log4j2 jars I included in the build path are:
log4j-api-2.6.2.jar
log4j-core-2.6.2.jar
Something that isn't explained very well/obviously in the Java documentation is that if you're using an executable Jar, it will only use the Class-Path as specified in the Manifest file. It will not listen to the -cp
or --classpath
arguments.
-Dlog4j.configurationFile=directory/file.xml
should definitely work though. I'm assuming you're running on Windows given your slash direction. Are you sure you are running it from the correct relative directory?
Update
I just tried it in Windows with no problems. I used the following manifest:
Manifest-Version: 1.0
Built-By: andrew.flower
Build-Jdk: 1.7.0_67
Class-Path: lib/log4j-api-2.1.jar lib/log4j-core-2.1.jar
Created-By: Apache Maven 3.2.3
Main-Class: com.andrew_flower.test.Log4jTest
Archiver-Version: Plexus Archiver
The Log4j2 jars are located in a lib/
directory and the log4j2.xml
is in the conf/
directory. I executed the following command, and it found the config successfully.
java -Dlog4j.configurationFile=conf\log4j2.xml -jar log4j2test1-1.0-SNAPSHOT.jar