Specifying Log4j2 Configuration File When Using Executable JAR

For others who may have this issue...

  1. Make sure your -Dlog4j.configurationFile options occur before your '-jar' not after. Might seem obvious, but saw that mistake once.
  2. 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.
  3. 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:

  1. log4j-api-2.6.2.jar

  2. 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