简体   繁体   English

如何在使用Eclipse创建的可运行jar中指定外部log4j2配置文件

[英]How to Specify External log4j2 Config File in Runnable jar Created with Eclipse

Log is created when running project in Eclipse, however when a runnable jar is created (Library handling option: Extract required libraries into generated JAR) the configuration file cannot be found and no log is produced. 在Eclipse中运行项目时会创建日志,但是在创建可运行jar时(库处理选项:将所需的库提取到生成的JAR中),找不到配置文件,并且不会生成日志。

When running the jar through the command line (cd into the directory containing the runnable jar) the following is output: 通过命令行运行jar时(cd进入包含可运行jar的目录中),将输出以下内容:

ERROR StatusLogger Unrecognized format specifier [d]
ERROR StatusLogger Unrecognized conversion specifier [d] starting at position 16 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [thread]
ERROR StatusLogger Unrecognized conversion specifier [thread] starting at position 25 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [level]
ERROR StatusLogger Unrecognized conversion specifier [level] starting at position 35 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [logger]
ERROR StatusLogger Unrecognized conversion specifier [logger] starting at position 47 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [msg]
ERROR StatusLogger Unrecognized conversion specifier [msg] starting at position 54 in conversion pattern.
ERROR StatusLogger Unrecognized format specifier [n]
ERROR StatusLogger Unrecognized conversion specifier [n] starting at position 56 in conversion pattern.
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.

The last bit of the message tells me that the config file cannot be found, although it's reading a configuration PatternLayout from somewhere. 消息的最后一点告诉我,尽管配置文件正在从某个位置读取配置PatternLayout,但找不到该配置文件。 When the option -Dlog4j.configurationFile option is added to the command, the following exception occurs (in addition to the previous error messages): 将选项-Dlog4j.configurationFile选项添加到命令时,会发生以下异常(除了以前的错误消息):

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException: No Configuration was provided
        at java.util.Objects.requireNonNull(Unknown Source)
        at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java
:477)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:561)
        at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:577)
        at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:212)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextF
actory.java:242)
        at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextF
actory.java:45)
        at org.apache.logging.log4j.LogManager.getContext(LogManager.java:174)
        at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:618)
        at test.SmokeTest.<clinit>(SmokeTest.java:41)

I have tried specifying the -Dlog4j.configurationFile value as "c:/path/to/config/log4j2.xml" and "file://c:/path/to/config/log4j2.xml" and get the same error. 我尝试将-Dlog4j.configurationFile值指定为“ c:/path/to/config/log4j2.xml”和“ file:// c:/path/to/config/log4j2.xml”,并得到相同的错误。 That last line in the exception message is the initialization of the logger. 异常消息中的最后一行是记录器的初始化。 In the code I have tried to initialize the logger with the following options: 在代码中,我尝试使用以下选项初始化记录器:

 - private static final Logger logger =
   LogManager.getLogger("c:/path/to/config/log4j2.xml");
 - private static final Logger logger = LogManager.getLogger("logger name specified in config file");

Before writing to the file, I set the log4j.configurationFile system property. 在写入文件之前,我设置了log4j.configurationFile系统属性。 Tried the following options: 尝试了以下选项:

- System.setProperty("log4j.configurationFile", "C:\\path\\to\\config\\log4j2.xml")
- System.setProperty("log4j.configurationFile", "file://c:/path/to/config/log4j2.xml")

I have also tried using the BasicConfigurator.configure() and PropertyConfigurator.configure() methods from importing import org.apache.log4j.BasicConfigurator and PropertyConfigurator from original log4j (log4j-1.2.17.jar). 我还尝试了通过从原始log4j(log4j-1.2.17.jar)导入import org.apache.log4j.BasicConfigurator和PropertyConfigurator来使用BasicConfigurator.configure()和PropertyConfigurator.configure()方法。

Thinking that maybe log4j2 was unable to get its configuration from an external file, I put a copy of the log4j2.xml file in the src folder of the project. 考虑到log4j2可能无法从外部文件获取其配置,我将log4j2.xml文件的副本放入项目的src文件夹中。 Then tried initializing the logger with: 然后尝试使用以下命令初始化记录器:

- private static final Logger logger = LogManager.getLogger(MyClass.class.getName());
- private static final Logger logger = LogManager.getLogger(SmokeTest.class);

Both gave me the same errors, but perhaps that's why it works when running from Eclipse? 两者都给了我相同的错误,但是也许这就是为什么从Eclipse运行时它可以工作吗?

Also, if I double click the program icon or run from command line without -Dlog4j.configurationFile option, the application launches but does not produce log. 另外,如果我双击程序图标或在没有-Dlog4j.configurationFile选项的情况下从命令行运行,该应用程序将启动,但不会产生日志。

Please help me to troubleshoot this problem and let me know if you need me to provide any further information. 请帮助我解决此问题,如果您需要我提供任何进一步的信息,请告诉我。 I know similar questions have been asked before, but I am unable to find a solution that works for my issue; 我知道以前也曾问过类似的问题,但是我找不到适合我问题的解决方案。 runnable jar, Eclipse, external log4j2 configuration file. 可运行的jar,Eclipse,外部log4j2配置文件。 Not using Ant or Maven. 不使用Ant或Maven。

My problem was that I was calling the log before initializing it. 我的问题是我在初始化日志之前先调用它。
Everything was packaged correctly and the main class had the proper code for log4j. 一切都已正确打包,并且主类具有适用于log4j的代码。 The culprit was a class level object that was initialized before main executed. 罪魁祸首是在main执行之前初始化的类级别对象。 That object's constructor logged its creation. 该对象的构造函数记录了其创建。 This did not cause any error when debugging in Eclipse, but stopped the executable from running. 在Eclipse中进行调试时,这不会引起任何错误,但会阻止可执行文件运行。
Thanks @Andreas for giving me the ideal of starting over from a new project. 感谢@Andreas给了我从新项目重新开始的理想选择。

Don't know what you're doing wrong, but here is an MCVE . 不知道您在做什么错,但这是MCVE

Test.java

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Test {
    private static transient Logger log = LogManager.getLogger(Test.class);
    public static void main(String[] args) {
        log.info("Hello World");
    }
}

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

Add Apache Log4j 2 to Eclipse build path: log4j-api-2.7.jar and log4j-core-2.7.jar . Apache Log4j 2添加到Eclipse构建路径: log4j-api-2.7.jarlog4j-core-2.7.jar

Create jar file using Eclipse File > Export... > Runnable JAR file > Extract required libraries into generated JAR with name Test.jar . 使用Eclipse File > Export... > Runnable JAR file创建jar文件> Export... Extract required libraries into generated JAR名为Test.jar Extract required libraries into generated JAR

Run with: 运行:

java -Dlog4j.configurationFile=C:\path\to\log4j2.xml -jar Test.jar

Output 输出量

14:06:23.728 [main] INFO  Test - Hello World

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM