web-dev-qa-db-fra.com

Spécification du fichier de configuration Log4j2 lors de l'utilisation du fichier JAR exécutable

Je ne parviens pas à spécifier l'emplacement du fichier de configuration Log4j2 lors de l'utilisation d'un fichier JAR exécutable. Cela fonctionne bien si je sépare tous les fichiers JAR, mais lorsque j'essaie de les combiner dans un fichier JAR exécutable, le fichier log4j2.xml n'est pas extrait de la ligne de commande.

J'ai essayé ces deux méthodes pour spécifier l'emplacement:

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

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

Aucun de ceux qui travaillent. J'ai également essayé d'ajouter le répertoire contenant le fichier de configuration au chemin d'accès aux classes dans le fichier manifeste du fichier JAR:

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/

Je n'ai pas eu de succès avec cette méthode non plus. Des idées que je pourrais faire mal?

Merci d'avance pour votre aide!


MODIFIER

Ah, je crois que j'ai confondu le problème. À l'origine, c'était l'erreur que je voyais dans le résultat de la ligne de commande:

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

Mais à un moment donné, alors que je changeais de choses, le message d'erreur a changé sans que je m'en rende compte:

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

Donc, ce que j’ai compris, c’est que même si le JAR exécutable que je construisais incluait les JARs log4j-core-2.1.jar et log4j-api-2.1.jar à l’intérieur de celui-ci et dans le chemin de classe du fichier MANIFEST, il y avait un problème. La façon dont j'ai écrit mon fichier ant pour combiner les bibliothèques dans le JAR unique que je créais copiait avec succès les répertoires et les fichiers de classe, mais ne copiait pas les autres types pour une raison quelconque, qui est également évidemment nécessaire (par exemple, Log4j-config .xsd, Log4j-events.dtd, etc.).

Pour résoudre ce problème, j'ai modifié la façon dont je fusionnais les fichiers JAR de mon fichier de construction Ant en ceci:

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

Et cela a résolu le problème et copié tous les fichiers des fichiers JAR dans mon fichier JAR nouvellement créé.

Une fois ce problème résolu, la deuxième des commandes que j'ai postées ci-dessus permettait de spécifier l'emplacement du fichier de configuration. (Comme indiqué par @rewolf ci-dessous, la première commande ne fonctionnera pas car le chemin d'accès aux classes spécifié dans la variable MANIFEST du fichier JAR remplace tout chemin d'accès aux classes spécifié sur la ligne de commande.

Merci pour vos réponses, ils m'ont certainement aidé à prendre le bon chemin pour comprendre mes erreurs.

8
Steph

Un élément qui n’est pas très bien expliqué/évidemment dans la documentation Java est que si vous utilisez un fichier jar exécutable, il utilisera uniquement le chemin de classe spécifié dans le fichier Manifest. Il n'écoutera pas les arguments -cp et --classpath.

-Dlog4j.configurationFile=directory/file.xml 

devrait certainement fonctionner si. Je suppose que vous utilisez Windows, en fonction de la direction de votre barre oblique. Êtes-vous sûr de l'exécuter à partir du bon répertoire relatif?

Mettre à jour

Je viens de l'essayer dans Windows sans aucun problème. J'ai utilisé le manifeste suivant:

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

Les fichiers JAR Log4j2 sont situés dans un répertoire lib/ et le log4j2.xml se trouve dans le répertoire conf/. J'ai exécuté la commande suivante et la configuration a été trouvée avec succès.

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

J'ai résolu le problème de la localisation de la configuration log4j2 dans un fichier jar exécutable créé à partir d'Eclipse en l'incluant dans mon code Java:

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

J'ai un paquet et j'ai donc dû spécifier le chemin d'accès à mon dossier "ressources" (dans mon dossier "src" dans Eclipse):

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

Remarquez que je n'ai pas inclus "src" dans mon chemin et que je pense que c'est le chemin dans le dossier "bin" qui est requis: c'est-à-dire dans mon cas "com/company/app/resources/log4j2.xml"

Mon fichier de configuration ressemble à ceci:

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

Notez également que j'assigne de manière dynamique le chemin du fichier journal de roulement + nom "$ {sys: nomFichier}}" en l'incluant dans mon code Java:

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

Afin de faire fonctionner ces 2 assignations dynamiques System.setProperty, elles doivent être exécutées avant l'instruction "getLogger" et mon code Java ressemble à ceci:

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

}

Avoir "logger" déclaré au début de ma classe (mais sans invoquer "getLogger" avant mes 2 instructions System.setProperty) me permet de référencer "logger" dans d'autres méthodes. Je suis obligé de l'initialiser et j'ai donc choisi "null", puis plus tard, je le mets à jour avec l'instruction "getLogger" - je ne peux donc pas le rendre "final" (je ne peux l'assigner qu'une seule fois), mais je peux le rendre statique une variable de classe constante.

nb les 2 jarres log4j2 que j'ai inclus dans le chemin de construction sont:

  1. log4j-api-2.6.2.jar

  2. log4j-core-2.6.2.jar

6
David Miller

Pour d'autres qui peuvent avoir ce problème ...

  1. Assurez-vous que vos options -Dlog4j.configurationFile apparaissent avant votre '-jar' pas après. Cela peut sembler évident, mais j'ai vu cette erreur une fois.
  2. Essayez de traiter l'emplacement du fichier comme une URL et voyez si cela fonctionne. C'est à dire. espaces d'échappement avec % 20 etc. Utilisez également 'fichier: // chemin', remplacez les barres obliques inverses par des barres obliques.
  3. Les chemins Windows peuvent être écrits sous la forme file: // c: /path/to/log4j2.xml

Par conséquent, si vous avez un log4j2.xml dans votre dossier de programme pour votre exempleApp dans C:\Program Files\ExampleApp, alors ...

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

...devrait marcher

4
kervin

J'avais ce problème avec la version 2.8 de Log4j2 . Ce problème avait disparu lorsque les bocaux Log4j2 respectifs ont été remplacés par la version 2.6 de Log4j2.

0
sujeet suryawanshi