実行可能なJARファイルを使用するときに、Log4j2構成ファイルの場所を指定するのに問題があります。すべてのJARを分離すると問題なく動作しますが、何らかの理由でそれらを1つの実行可能JARファイルに結合しようとすると、log4j2.xml
ファイルがコマンドラインから取得されません。
場所を指定するこれらの2つの方法を試しました:
Java -Djava.libary.path=..\bin -cp ..\config -jar MyApplication.jar
Java -Djava.libary.path=..\bin -Dlog4j.configurationFile=..\config\log4j2.xml -jar MyApplication.jar
どちらも機能していません。また、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/
私もこの方法で成功していません。私が間違っているかもしれないアイデアはありますか?
助けてくれてありがとう!
編集
ああ、私は問題を間違えたと思います。もともと、これは私がコマンドライン出力で見たエラーでした:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
しかし、私が物事を変更している間のある時点で、これに気付かずにエラーメッセージが変更されました。
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
だから私が理解したのは、私が構築している実行可能JARがlog4j-core-2.1.jar
およびlog4j-api-2.1.jar
JARが内部にあり、MANIFEST
ファイルのクラスパスに問題があります。ライブラリを組み合わせて作成中の単一のJARにするためにantファイルを作成した方法は、ディレクトリとクラスファイルを正常にコピーしていましたが、何らかの理由で他のタイプをコピーしていませんでした。これも明らかに必要です(Log4j-configなど)。 .xsd、Log4j-events.dtdなど)。
これを修正するために、AntビルドファイルのJARをマージする方法を次のように変更しました。
<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>
これで問題が修正され、JARからすべてのファイルが新しく作成されたJARにコピーされました。
この問題が解決されると、上記で投稿した2番目のコマンドは、構成ファイルの場所を指定するために機能しました。 (@rewolf
以下では、JARのMANIFEST
で指定されたクラスパスがコマンドラインで指定されたクラスパスをオーバーライドするため、最初のコマンドは機能しません。
あなたの回答をありがとう、間違いは私が間違いを理解するための正しい道に進むのを確実に助けました。
Javaのドキュメントで十分に/明らかに説明されていないものは、実行可能なJarを使用している場合、マニフェストファイルで指定されているClass-Pathのみを使用するということです。 -cp
または--classpath
引数をリッスンしません。
-Dlog4j.configurationFile=directory/file.xml
間違いなく動作するはずです。スラッシュの方向性を考えると、Windowsで実行していると思います。正しい相対ディレクトリから実行していますか?
更新
私は問題なくWindowsで試してみました。次のマニフェストを使用しました。
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
Log4j2 jarはlib/
ディレクトリにあり、log4j2.xml
はconf/
ディレクトリにあります。次のコマンドを実行すると、設定が正常に検出されました。
Java -Dlog4j.configurationFile=conf\log4j2.xml -jar log4j2test1-1.0-SNAPSHOT.jar
これをJavaコードに含めることで、Eclipseから作成した実行可能なJARでlog4j2構成の場所を指定する問題を解決しました。
System.setProperty("log4j.configurationFile", "resources/log4j2.xml");
私はパッケージを持っているので、「Eclipse」の「src」フォルダー内の「resources」フォルダーへのパスを指定する必要がありました。
System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");
パスに「src」を含めておらず、必要なのは「bin」フォルダー内のパスだと思います。つまり、私の場合は「com/company/app/resources/log4j2.xml」です。
私の設定ファイルは次のようになります:
<?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>
また、これをJavaコードに含めることで、ローリングログファイルのパス+名前 "$ {sys:logFilename}"を動的に割り当てています。
System.setProperty("logFilename", "logs/myApp.log");
これらの2つの動的System.setProperty割り当てを機能させるには、「getLogger」ステートメントの前に実行する必要があるため、Javaコードは次のようになります。
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());
}
}
クラスの開始時に「ロガー」が宣言されている(ただし、2つのSystem.setPropertyステートメントの前に「getLogger」を呼び出さない)と、他のメソッドで「ロガー」を参照できます。私はそれを初期化する義務があるので、「null」を選択しましたが、後で「getLogger」ステートメントで更新します-これを考えると、「最終」にすることはできません(1回だけ割り当てることができます)が、静的にすることができます-定数クラス変数。
ビルドパスに含めた2つのlog4j2 jarは次のとおりです。
log4j-api-2.6.2.jar
log4j-core-2.6.2.jar
この問題があるかもしれない他の人のために...
したがって、C:\Program Files\ExampleApp
のexampleAppのプログラムフォルダーにlog4j2.xmlがある場合は、...
Java.exe -Dlog4j.configurationFile=file://c:/program%20files/exampleapp/log4j2.xml -jar exampleApp.jar ...
...うまくいくはず
Log4j2のバージョン2.8でこの問題が発生しました。これは、それぞれのLog4j2 jarがバージョン2.6のLog4j2に置き換えられたときになくなりました。