Java-Note-记一次log4j配置文件无法加载问题的解决过程

起因

在一次由于其他原因更改了POM文件配置的操作后发现: spring boot项目中配置的log4j2.yml文件无法正常加载, 显示错误如下:

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

分析过程

发现在更改POM文件过程中删除了几个依赖. 其中有一个是:

1
2
3
4
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

进入com.fasterxml.jackson.dataformat.yaml包中, 发现与解析yml文件相关的类YAMLParser, debug该类的构造器, 发现org.apache.logging.log4j.core包中的JsonConfigurationFactory对象初始化时会加载com.fasterxml.jackson.dataformat.yaml包中的类. 具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class JsonConfigurationFactory extends ConfigurationFactory {
...
private static final String[] dependencies = new String[] {
"com.fasterxml.jackson.databind.ObjectMapper",
"com.fasterxml.jackson.databind.JsonNode",
"com.fasterxml.jackson.core.JsonParser"
};

private final boolean isActive;

// 尝试加载com.fasterxml.jackson.dataformat.yaml包中的dependencies类, 如果失败, 将isActive置false
public JsonConfigurationFactory() {
for (final String dependency : dependencies) {
if (!Loader.isClassAvailable(dependency)) {
LOGGER.debug("Missing dependencies for Json support");
isActive = false;
return;
}
}
isActive = true;
}
...
// 如果isActive置false, 则返回null, 使用default configuration
public Configuration getConfiguration(final ConfigurationSource source) {
if (!isActive) {
return null;
}
return new JsonConfiguration(source);
}
...
}

public abstract class ConfigurationFactory extends ConfigurationBuilderFactory {
...
private static class Factory extends ConfigurationFactory {
...
public Configuration getConfiguration(final String name, final URI configLocation) {
...
Configuration config = getConfiguration(true, name);
if (config == null) {
config = getConfiguration(true, null);
if (config == null) {
config = getConfiguration(false, name);
if (config == null) {
// 从这里进入上面的getConfiguration方法
config = getConfiguration(false, null);
}
}
}
if (config != null) {
return config;
}
// 此处为起因中的语句
LOGGER.error("No log4j2 configuration file found. Using default configuration: logging only errors to the console.");
return new DefaultConfiguration();
}
}
}

由上面的代码可知, 当无法加载com.fasterxml.jackson.dataformat.yaml包中的类时, 会弹出起因中的错误

解决方案

POM文件中增加com.fasterxml.jackson.dataformat.yaml依赖

总结

遇到这种框架问题, 可以尝试初步定位问题原因, 再通过debug框架源码来精确定位问题所在位置从而找到解决方案