【发布时间】:2017-03-16 09:45:33
【问题描述】:
// 更新 1:
我做了一些更多的测试,删除了大部分库并注释掉了库特定的代码,导致相同的行为让我得出结论,这个问题不是(直接)由这些库引起的,但似乎是一般我的代码和/或设置中的问题。
这里的主要问题是我不明白为什么它在从 Eclipse 中启动时完美运行(即时启动、高性能等),而当我在 Eclipse 之外启动它时,相同的代码就会出现所描述的问题(如使用相同 JDK 的可运行 JAR!)。
有人可以阐明可能存在的差异吗?
// 更新 1 结束
// 原帖:
来自我在这里提出的一个较老的问题:Wrapped .exe with launch4j and jdk8 takes very long to start. Using jdk7 instead starts almost instant
现在我知道它与带有 jdk8 的 launch4j 无关,但它似乎是由 log4j 在我的应用程序中结合 jdk8 引起的。在这里讨论了类似的问题:Log4j 2 hangs when creating logger 和这里:log4j LogManager.getLogger get's stuck in an infinite loop。
但是没有一个解决方案适合我。这个问题对我来说也有点不同。 我们开始:
我的应用程序的主要方法在初始化 Logger 对象之前做了一些初始化工作(比如清理旧的日志文件等)。每个步骤都通过 System.out.println 打印出来用于调试目的。这是一个简化的示例:
public class MyTestCase {
private static Logger logger;
public static void main(String[] args) throws Exception {
System.out.println("Executing MyTestCase...");
doInitstuff1();
doInitstuff2();
System.out.println("Initializing Logger...");
logger = LogManager.getLogger(MyTestCase.class.getName());
System.out.println("Init complete!");
doTheRealStuff();
}
private void doInitstuff1() {
System.out.println("Init Stuff 1...");
}
private void doInitstuff2() {
System.out.println("Init Stuff 2...");
}
private void doTheRealStuff() {
System.out.println("Launching GUI...");
}
}
当我在 Eclipse 中执行代码时(调试或运行配置无关紧要),即时输出(开始和完成
正在执行 MyTestCase...
初始化材料 1...
初始化材料 2...
正在初始化记录器...
初始化完成!
正在启动 GUI...
当我创建可运行的 JAR 或包装的 .exe(使用 l4j)并使用安装在目标平台上的 JDK 或 JRE 8 执行应用程序时,结果如下:
正在执行 MyTestCase...
初始化材料 1...
初始化材料 2...
正在初始化记录器...
应用程序挂起/停止大约 10-45 秒,具体取决于设备
初始化完成!
正在启动 GUI...
当我执行针对 JDK 7 编译的完全相同的操作时,“已部署”可执行文件的启动速度与在 Eclipse 中一样快。这真的很奇怪,我不知道该怎么做。
我用于测试和实验的构建路径/库:
CJWizards-0.22
commons-codec-1.10
commons-io-2.4
commons-lang3-3.4
commons-logging-1.2
guava-20.0
itext-2.1.7
JDatePicker-1.3.5
jna-4.3.0
jna-platform-4.3.0
log4j-api-2.8.1
log4j-core-2.8.1
sl4j-api-1.7.22
slf4j-nop-1.7.22
swingx-all-1.6.5-1
表格布局
vlcj-3.10.1
zip4j_1.3.2
知道是什么原因造成的吗?
回顾:
-
从 eclipse 中运行不会出现这个问题(无论使用 jdk 7 还是 8)
-
使用 JDK 或 JRE 7 作为可运行的 jar 或 exe 运行时不会出现问题
-
使用 JDK 或 JRE 8 作为可运行的 jar 或 exe 运行时会出现问题
这是我的 log4j2.xml 配置文件的内容,以防你也需要它:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error">
<appenders>
<File name="MyTestCase.debug" fileName="${sys:user.home}/.mtc/log/MyTestCase.debug.log">
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="ACCEPT"/>
<PatternLayout pattern="%d{yyyy-MM-dd | HH:mm:ss.SSS} | [%t] %-5level | %logger{42} | %msg%n"/>
</File>
<Async name="Async.debug">
<appender-ref ref="MyTestCase.debug"/>
</Async>
<File name="MyTestCase.error" fileName="${sys:user.home}/.mtc/log/MyTestCase.error.log">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy-MM-dd | HH:mm:ss.SSS} | [%t] %-5level | %logger{42} | %msg%n"/>
</File>
<Async name="Async.error">
<appender-ref ref="MyTestCase.error"/>
</Async>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="Async.debug" level="debug"/>
<appender-ref ref="Async.error" level="error"/>
</root>
</loggers>
</configuration>
【问题讨论】:
-
您是否尝试使用 org.apache.log4j.Logger.getLogger(MyTestCase.class) 初始化您的记录器?
-
@Ulathar 你先升级到
2.8.1怎么样 - 据我所知这是最新的 -
@GAlexMES:现在使用“Logger org.apache.logging.log4j.LogManager.getLogger(String name)”。
-
使用
jstack在等待时获取跟踪。或使用调试器单步执行有问题的代码。或者如果它实际上正在消耗 CPU 时间,则使用分析器。有很多诊断问题的工具,使用它们 -
您可以通过将配置文件更改为以
<Configuration status="trace">开头来调查发生的情况。这会将内部 Log4j2 日志打印到控制台。
标签: java eclipse logging java-8 log4j2