From fef993fbb5cbeddfa1ac29a6a33d3dfe2e833053 Mon Sep 17 00:00:00 2001 From: Henrik Brautaset Aronsen Date: Fri, 22 Jun 2018 14:45:26 +0200 Subject: [PATCH] Avoid NullPointerException in PropertiesUtil.reload() SystemPropertiesPropertySource.forEach(..) uses Property.getProperty(..) to resolve values. If that value is a non-String, the value will be null. Since `literal` is a ConcurrentHashMap, a put(..) with null value will yield a NullPointerException. This is especially hard to debug in the case of e.g. StatusLogger, which initializes PropertiesUtil as a static variable. The class is unable to load, throws a NoClassDefFoundError, and hides the NullPointerException. Here's what I got when I had a Property value that was a File: Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.logging.log4j.util.PropertiesUtil at org.apache.logging.log4j.status.StatusLogger.(StatusLogger.java:78) at org.apache.logging.log4j.LogManager.(LogManager.java:60) --- .../logging/log4j/util/PropertiesUtil.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java index f5e1ecb5610..f1c8f15bf05 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java @@ -330,13 +330,17 @@ private synchronized void reload() { source.forEach(new BiConsumer() { @Override public void accept(final String key, final String value) { - literal.put(key, value); - final List tokens = PropertySource.Util.tokenize(key); - if (tokens.isEmpty()) { - normalized.put(source.getNormalForm(Collections.singleton(key)), value); - } else { - normalized.put(source.getNormalForm(tokens), value); - tokenized.put(tokens, value); + if (value != null) { + literal.put(key, value); + final List tokens = PropertySource.Util.tokenize(key); + if (tokens.isEmpty()) { + normalized.put(source.getNormalForm(Collections.singleton(key)), value); + } else { + normalized.put(source.getNormalForm(tokens), value); + tokenized.put(tokens, value); + } + } else { + LowLevelLogUtil.log("Property " + key + " was skipped because of null value."); } } });