wake-up-neo.net

Angabe der Log4j2-Konfigurationsdatei bei Verwendung von ausführbarem JAR

Bei der Verwendung einer ausführbaren JAR-Datei ist es schwierig, den Speicherort der Log4j2-Konfigurationsdatei anzugeben. Es funktioniert gut, wenn ich alle JARs trenne, aber wenn ich versuche, sie in einer ausführbaren JAR-Datei zu kombinieren, wird die log4j2.xml-Datei aus irgendeinem Grund nicht von der Befehlszeile abgerufen.

Ich habe die folgenden zwei Methoden zum Festlegen des Speicherorts ausprobiert:

Java -Djava.libary.path=..\bin -cp ..\config -jar MyApplication.jar

Java -Djava.libary.path=..\bin -Dlog4j.configurationFile=..\config\log4j2.xml -jar MyApplication.jar

Keiner von denen arbeitet. Ich habe auch versucht, das Verzeichnis mit der Konfigurationsdatei zum Klassenpfad in der JAR-Manifestdatei hinzuzufügen:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.7.0_21-b11 (Oracle Corporation)
Main-Class: com.abc.MyApplication
Class-Path: ../config/

Ich hatte mit dieser Methode auch keinen Erfolg. Irgendwelche Ideen, was ich falsch machen könnte?

Vielen Dank im Voraus für jede Hilfe!


BEARBEITEN

Ah, ich glaube, ich habe das Problem falsch verstanden. Ursprünglich war dies der Fehler, den ich in der Befehlszeilenausgabe sah:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

Aber irgendwann, während ich Dinge änderte, änderte sich die Fehlermeldung, ohne dass ich es bemerkte:

ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

Ich fand heraus, dass, obwohl die ausführbare JAR, die ich baute, die JARs log4j-core-2.1.jar und log4j-api-2.1.jar darin und in den Klassenpfad der MANIFEST-Datei enthielt, ein Problem auftrat. Die Art und Weise, wie ich meine Ant-Datei geschrieben habe, um die Bibliotheken in einem einzelnen JAR zu kombinieren, kopierte die Verzeichnisse und Klassendateien erfolgreich, kopierte jedoch nicht die anderen Typen, die offensichtlich auch notwendig sind (z. B. Log4j-config) .xsd, Log4j-events.dtd usw.).

Um dies zu beheben, änderte ich die Art, wie ich die JARs in meiner Ant-Build-Datei zusammenführte, folgendermaßen:

<jar destfile="${dist}/${jarName}" basedir="${classes}" 
    excludes=".svn">

    <!-- Merge this JAR with all the JARs in the lib directory, so that
    we are only creating one distribution JAR that includes all the
    libraries that you need. -->
    <fileset dir="${classes}" includes="**/*.class" />
    <zipgroupfileset dir="${lib}" includes="**/*.jar" />

    <!-- Specify the manifest file of the JAR -->
    <manifest>
        <attribute name="Main-Class" value="com.abc.MyApplication"/>
        <attribute name="Class-Path" value=". ${manifest.classpath}"/>
    </manifest>
</jar>

Und das Problem wurde behoben und alle Dateien aus den JARs wurden in mein neu erstelltes JAR kopiert.

Nachdem das Problem behoben wurde, funktionierte der zweite der oben genannten Befehle, um den Speicherort der Konfigurationsdatei anzugeben. (Wie unten in @rewolf angegeben, funktioniert der erste Befehl nicht, da der in MANIFEST der JAR angegebene Klassenpfad jeden in der Befehlszeile angegebenen Klassenpfad überschreibt.

Vielen Dank für Ihre Antworten, sie haben mir definitiv geholfen, den richtigen Weg zu finden, um meine Fehler herauszufinden.

8
Steph

Was in der Java-Dokumentation nicht sehr gut erklärt wird, ist, dass Sie bei Verwendung einer ausführbaren Jar nur den Klassenpfad verwenden, wie er in der Manifest-Datei angegeben ist. Die Argumente -cp oder --classpath werden nicht abgehört.

-Dlog4j.configurationFile=directory/file.xml 

sollte auf jeden Fall funktionieren. Ich gehe davon aus, dass Sie unter Windows laufen, wenn Sie die Richtung des Schrägstrichs angeben. Sind Sie sicher, dass Sie es aus dem richtigen relativen Verzeichnis ausführen?

Update

Ich habe es gerade in Windows ohne Probleme ausprobiert. Ich habe das folgende Manifest verwendet:

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

Die Log4j2-Dosen befinden sich in einem lib/-Verzeichnis, und log4j2.xml befindet sich im conf/-Verzeichnis. Ich habe den folgenden Befehl ausgeführt und die Konfiguration erfolgreich gefunden.

Java -Dlog4j.configurationFile=conf\log4j2.xml -jar log4j2test1-1.0-SNAPSHOT.jar
14
rewolf

Ich habe das Problem gelöst, den Speicherort der log4j2-Konfiguration in einer ausführbaren Jar anzugeben, die ich aus Eclipse erstellt habe, indem ich dies in meinen Java-Code einfügte:

System.setProperty("log4j.configurationFile", "resources/log4j2.xml");

Ich habe ein Paket und daher musste ich den Pfad zu meinem "resources" -Ordner angeben (in meinem "src" -Ordner in Eclipse):

System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");

Beachten Sie, dass ich "src" nicht in meinen Pfad aufgenommen habe. Ich denke, es ist der Pfad im Ordner "bin", der erforderlich ist: in meinem Fall "de/company/app/resources/log4j2.xml".

Meine Konfigurationsdatei sieht so aus:

<?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>

Beachten Sie auch, dass ich den Pfad der laufenden Protokolldatei + den Namen "$ {sys: logFilename}" dynamisch zuweise, indem Sie Folgendes in meinen Java-Code einfügen:

System.setProperty("logFilename", "logs/myApp.log");

Damit diese beiden dynamischen System.setProperty-Zuweisungen funktionieren, müssen sie vor der "getLogger" -Anweisung ausgeführt werden, sodass mein Java-Code folgendermaßen aussieht:

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());  
 }

}

Wenn "logger" zu Beginn meiner Klasse deklariert ist (aber ohne "getLogger" vor meinen 2 System.setProperty-Anweisungen aufzurufen), kann ich in anderen Methoden auf "logger" verweisen. Ich bin jedoch verpflichtet, es zu initialisieren, und so habe ich "null" gewählt, aber später mit der "getLogger" -Anweisung aktualisiert - da ich es nicht "final" machen kann (kann es nur einmal zuweisen), kann es statisch gemacht werden. eine konstante Klassenvariable.

die 2 log4j2-Gläser, die ich im Build-Pfad enthalten habe, sind:

  1. log4j-api-2.6.2.jar

  2. log4j-core-2.6.2.jar

6
David Miller

Für andere, die dieses Problem haben könnten ...

  1. Stellen Sie sicher, dass Ihre -Dlog4j.configurationFile -Optionen vorher Ihr '-jar' nicht danach auftreten. Könnte offensichtlich erscheinen, aber den Fehler einmal gesehen haben.
  2. Behandeln Sie den Dateispeicherort als URL und prüfen Sie, ob dies funktioniert. Das heißt Leerzeichen mit% 20 etc. umgehen. Verwenden Sie auch 'file: // path ' und ersetzen Sie umgekehrte Schrägstriche durch Vorwärtswischen.
  3. Windows-Pfade können als file geschrieben werden: // c: /path/to/log4j2.xml

Wenn Sie also eine log4j2.xml in Ihrem Programmordner für Ihre exampleApp in C:\Program Files\ExampleApp haben, dann ...

Java.exe -Dlog4j.configurationFile=file://c:/program%20files/exampleapp/log4j2.xml -jar exampleApp.jar ... 

...sollte arbeiten

4
kervin

Ich hatte dieses Problem mit Version 2.8 von Log4j2. Dies war nicht mehr der Fall, als die entsprechenden Log4j2-Gläser durch Version 2.6 von Log4j2 ersetzt wurden.

0