Skip to content

Commit e6c7f19

Browse files
committed
Disable programmatic configuration if log4j1.compatibility is false
Closes #2778.
1 parent dd5df4b commit e6c7f19

27 files changed

+268
-668
lines changed

log4j-1.2-api/src/main/java/org/apache/log4j/PropertyConfigurator.java

Lines changed: 91 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@
4747
import org.apache.log4j.spi.RendererSupport;
4848
import org.apache.log4j.spi.ThrowableRenderer;
4949
import org.apache.log4j.spi.ThrowableRendererSupport;
50-
import org.apache.logging.log4j.core.config.Configuration;
50+
import org.apache.logging.log4j.core.config.ConfigurationFactory;
5151
import org.apache.logging.log4j.core.net.UrlConnectionFactory;
52+
import org.apache.logging.log4j.util.PropertiesUtil;
5253
import org.apache.logging.log4j.util.StackLocatorUtil;
5354

5455
/**
@@ -119,15 +120,12 @@ public Object nextElement() {
119120
}
120121
}
121122

122-
static final String CATEGORY_PREFIX = "log4j.category.";
123-
static final String LOGGER_PREFIX = "log4j.logger.";
124-
static final String FACTORY_PREFIX = "log4j.factory";
125-
static final String ADDITIVITY_PREFIX = "log4j.additivity.";
126-
static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory";
127-
static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger";
128-
static final String APPENDER_PREFIX = "log4j.appender.";
129-
static final String RENDERER_PREFIX = "log4j.renderer.";
130-
static final String THRESHOLD_PREFIX = "log4j.threshold";
123+
private static final String CATEGORY_PREFIX = "log4j.category.";
124+
private static final String LOGGER_PREFIX = "log4j.logger.";
125+
private static final String FACTORY_PREFIX = "log4j.factory";
126+
private static final String ADDITIVITY_PREFIX = "log4j.additivity.";
127+
private static final String APPENDER_PREFIX = "log4j.appender.";
128+
private static final String RENDERER_PREFIX = "log4j.renderer.";
131129

132130
private static final String THROWABLE_RENDERER_PREFIX = "log4j.throwableRenderer";
133131
private static final String LOGGER_REF = "logger-ref";
@@ -147,6 +145,16 @@ public Object nextElement() {
147145

148146
private static final String INTERNAL_ROOT_NAME = "root";
149147

148+
private static boolean isFullCompatibilityEnabled() {
149+
return PropertiesUtil.getProperties().getBooleanProperty(ConfigurationFactory.LOG4J1_EXPERIMENTAL);
150+
}
151+
152+
private static void warnFullCompatibilityDisabled() {
153+
LogLog.warn(
154+
"Ignoring `PropertyConfigurator` call, since `log4j1.compatibility` is not enabled.\n"
155+
+ "See https://logging.staged.apache.org/log4j/2.x/migrate-from-log4j1.html#log4j1.compatibility for details.");
156+
}
157+
150158
/**
151159
* Reads configuration options from an InputStream.
152160
*
@@ -212,15 +220,15 @@ public static void configureAndWatch(final String configFilename, final long del
212220
configureAndWatch(configFilename, delayMillis, StackLocatorUtil.getCallerClassLoader(2));
213221
}
214222

215-
static void configureAndWatch(final String configFilename, final long delay, final ClassLoader classLoader) {
216-
final PropertyWatchdog watchdog = new PropertyWatchdog(configFilename, classLoader);
217-
watchdog.setDelay(delay);
218-
watchdog.start();
219-
}
220-
221-
private static Configuration reconfigure(final Configuration configuration) {
222-
org.apache.logging.log4j.core.config.Configurator.reconfigure(configuration);
223-
return configuration;
223+
private static void configureAndWatch(
224+
final String configFilename, final long delay, final ClassLoader classLoader) {
225+
if (isFullCompatibilityEnabled()) {
226+
final PropertyWatchdog watchdog = new PropertyWatchdog(configFilename, classLoader);
227+
watchdog.setDelay(delay);
228+
watchdog.start();
229+
} else {
230+
warnFullCompatibilityDisabled();
231+
}
224232
}
225233

226234
/**
@@ -240,31 +248,16 @@ private static Configuration reconfigure(final Configuration configuration) {
240248
* @see #parseCatsAndRenderers
241249
*/
242250
protected void configureLoggerFactory(final Properties properties) {
243-
final String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, properties);
244-
if (factoryClassName != null) {
245-
LogLog.debug("Setting category factory to [" + factoryClassName + "].");
246-
loggerFactory = (LoggerFactory)
247-
OptionConverter.instantiateByClassName(factoryClassName, LoggerFactory.class, loggerFactory);
248-
PropertySetter.setProperties(loggerFactory, properties, FACTORY_PREFIX + ".");
249-
}
250-
}
251-
252-
void configureRootCategory(final Properties properties, final LoggerRepository loggerRepository) {
253-
String effectiveFrefix = ROOT_LOGGER_PREFIX;
254-
String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, properties);
255-
256-
if (value == null) {
257-
value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, properties);
258-
effectiveFrefix = ROOT_CATEGORY_PREFIX;
259-
}
260-
261-
if (value == null) {
262-
LogLog.debug("Could not find root logger information. Is this OK?");
263-
} else {
264-
final Logger root = loggerRepository.getRootLogger();
265-
synchronized (root) {
266-
parseCategory(properties, root, effectiveFrefix, INTERNAL_ROOT_NAME, value);
251+
if (isFullCompatibilityEnabled()) {
252+
final String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, properties);
253+
if (factoryClassName != null) {
254+
LogLog.debug("Setting category factory to [" + factoryClassName + "].");
255+
loggerFactory = (LoggerFactory)
256+
OptionConverter.instantiateByClassName(factoryClassName, LoggerFactory.class, loggerFactory);
257+
PropertySetter.setProperties(loggerFactory, properties, FACTORY_PREFIX + ".");
267258
}
259+
} else {
260+
warnFullCompatibilityDisabled();
268261
}
269262
}
270263

@@ -279,9 +272,9 @@ public void doConfigure(final InputStream inputStream, final LoggerRepository lo
279272
doConfigure(inputStream, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
280273
}
281274

282-
Configuration doConfigure(
275+
private void doConfigure(
283276
final InputStream inputStream, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
284-
return doConfigure(loadProperties(inputStream), loggerRepository, classLoader);
277+
doConfigure(loadProperties(inputStream), loggerRepository, classLoader);
285278
}
286279

287280
/**
@@ -298,54 +291,29 @@ public void doConfigure(final Properties properties, final LoggerRepository logg
298291

299292
/**
300293
* Reads configuration options from <code>properties</code>.
301-
*
294+
* <p>
302295
* See {@link #doConfigure(String, LoggerRepository)} for the expected format.
303296
*
304-
* @param properties The properties
297+
* @param properties The properties
305298
* @param loggerRepository The hierarchy
306299
*/
307-
Configuration doConfigure(
300+
private void doConfigure(
308301
final Properties properties, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
309-
final PropertiesConfiguration configuration =
310-
new PropertiesConfiguration(LogManager.getContext(classLoader), properties);
311-
configuration.doConfigure();
312-
313-
repository = loggerRepository;
314-
// String value = properties.getProperty(LogLog.DEBUG_KEY);
315-
// if (value == null) {
316-
// value = properties.getProperty("log4j.configDebug");
317-
// if (value != null) {
318-
// LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead.");
319-
// }
320-
// }
321-
//
322-
// if (value != null) {
323-
// LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true));
324-
// }
325-
//
326-
// //
327-
// // if log4j.reset=true then
328-
// // reset hierarchy
329-
// final String reset = properties.getProperty(RESET_KEY);
330-
// if (reset != null && OptionConverter.toBoolean(reset, false)) {
331-
// hierarchy.resetConfiguration();
332-
// }
333-
//
334-
// final String thresholdStr = OptionConverter.findAndSubst(THRESHOLD_PREFIX, properties);
335-
// if (thresholdStr != null) {
336-
// hierarchy.setThreshold(OptionConverter.toLevel(thresholdStr, (Level) Level.ALL));
337-
// LogLog.debug("Hierarchy threshold set to [" + hierarchy.getThreshold() + "].");
338-
// }
339-
//
340-
// configureRootCategory(properties, hierarchy);
341-
// configureLoggerFactory(properties);
342-
// parseCatsAndRenderers(properties, hierarchy);
343-
//
344-
// We don't want to hold references to appenders preventing their
345-
// garbage collection.
346-
registry.clear();
347-
348-
return reconfigure(configuration);
302+
if (isFullCompatibilityEnabled()) {
303+
final PropertiesConfiguration configuration =
304+
new PropertiesConfiguration(LogManager.getContext(classLoader), properties);
305+
configuration.doConfigure();
306+
307+
repository = loggerRepository;
308+
309+
// We don't want to hold references to appenders preventing their
310+
// garbage collection.
311+
registry.clear();
312+
313+
org.apache.logging.log4j.core.config.Configurator.reconfigure(configuration);
314+
} else {
315+
warnFullCompatibilityDisabled();
316+
}
349317
}
350318

351319
/**
@@ -365,17 +333,20 @@ public void doConfigure(final String fileName, final LoggerRepository loggerRepo
365333
* @param loggerRepository The hierarchy
366334
*/
367335
@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "The filename comes from a system property.")
368-
Configuration doConfigure(
336+
private void doConfigure(
369337
final String fileName, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
370-
try (final InputStream inputStream = Files.newInputStream(Paths.get(fileName))) {
371-
return doConfigure(inputStream, loggerRepository, classLoader);
372-
} catch (final Exception e) {
373-
if (e instanceof InterruptedIOException || e instanceof InterruptedException) {
374-
Thread.currentThread().interrupt();
338+
if (isFullCompatibilityEnabled()) {
339+
try (final InputStream inputStream = Files.newInputStream(Paths.get(fileName))) {
340+
doConfigure(inputStream, loggerRepository, classLoader);
341+
} catch (final Exception e) {
342+
if (e instanceof InterruptedIOException) {
343+
Thread.currentThread().interrupt();
344+
}
345+
LogLog.error("Could not read configuration file [" + fileName + "].", e);
346+
LogLog.error("Ignoring configuration file [" + fileName + "].");
375347
}
376-
LogLog.error("Could not read configuration file [" + fileName + "].", e);
377-
LogLog.error("Ignoring configuration file [" + fileName + "].");
378-
return null;
348+
} else {
349+
warnFullCompatibilityDisabled();
379350
}
380351
}
381352

@@ -390,17 +361,20 @@ public void doConfigure(final URL url, final LoggerRepository loggerRepository)
390361
doConfigure(url, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
391362
}
392363

393-
Configuration doConfigure(final URL url, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
394-
LogLog.debug("Reading configuration from URL " + url);
395-
try {
396-
final URLConnection urlConnection = UrlConnectionFactory.createConnection(url);
397-
try (final InputStream inputStream = urlConnection.getInputStream()) {
398-
return doConfigure(inputStream, loggerRepository, classLoader);
364+
private void doConfigure(final URL url, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
365+
if (isFullCompatibilityEnabled()) {
366+
LogLog.debug("Reading configuration from URL " + url);
367+
try {
368+
final URLConnection urlConnection = UrlConnectionFactory.createConnection(url);
369+
try (final InputStream inputStream = urlConnection.getInputStream()) {
370+
doConfigure(inputStream, loggerRepository, classLoader);
371+
}
372+
} catch (final IOException e) {
373+
LogLog.error("Could not read configuration file from URL [" + url + "].", e);
374+
LogLog.error("Ignoring configuration file [" + url + "].");
399375
}
400-
} catch (final IOException e) {
401-
LogLog.error("Could not read configuration file from URL [" + url + "].", e);
402-
LogLog.error("Ignoring configuration file [" + url + "].");
403-
return null;
376+
} else {
377+
warnFullCompatibilityDisabled();
404378
}
405379
}
406380

@@ -422,7 +396,7 @@ private Properties loadProperties(final InputStream inputStream) {
422396
/**
423397
* Parse the additivity option for a non-root category.
424398
*/
425-
void parseAdditivityForLogger(final Properties properties, final Logger logger, final String loggerName) {
399+
private void parseAdditivityForLogger(final Properties properties, final Logger logger, final String loggerName) {
426400
final String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, properties);
427401
LogLog.debug("Handling " + ADDITIVITY_PREFIX + loggerName + "=[" + value + "]");
428402
// touch additivity only if necessary
@@ -433,8 +407,8 @@ void parseAdditivityForLogger(final Properties properties, final Logger logger,
433407
}
434408
}
435409

436-
Appender parseAppender(final Properties properties, final String appenderName) {
437-
Appender appender = registryGet(appenderName);
410+
private Appender parseAppender(final Properties properties, final String appenderName) {
411+
Appender appender = (Appender) registry.get(appenderName);
438412
if ((appender != null)) {
439413
LogLog.debug("Appender \"" + appenderName + "\" was already parsed.");
440414
return appender;
@@ -499,11 +473,11 @@ Appender parseAppender(final Properties properties, final String appenderName) {
499473
LogLog.debug("Parsed \"" + appenderName + "\" options.");
500474
}
501475
parseAppenderFilters(properties, appenderName, appender);
502-
registryPut(appender);
476+
registry.put(appender.getName(), appender);
503477
return appender;
504478
}
505479

506-
void parseAppenderFilters(final Properties properties, final String appenderName, final Appender appender) {
480+
private void parseAppenderFilters(final Properties properties, final String appenderName, final Appender appender) {
507481
// extract filters and filter options from props into a hashtable mapping
508482
// the property name defining the filter class to a list of pre-parsed
509483
// name-value pairs associated to that filter
@@ -567,7 +541,7 @@ void parseAppenderFilters(final Properties properties, final String appenderName
567541
/**
568542
* This method must work for the root category as well.
569543
*/
570-
void parseCategory(
544+
private void parseCategory(
571545
final Properties properties,
572546
final Logger logger,
573547
final String optionKey,
@@ -628,6 +602,10 @@ void parseCategory(
628602
* Parse non-root elements, such non-root categories and renderers.
629603
*/
630604
protected void parseCatsAndRenderers(final Properties properties, final LoggerRepository loggerRepository) {
605+
if (!isFullCompatibilityEnabled()) {
606+
warnFullCompatibilityDisabled();
607+
return;
608+
}
631609
final Enumeration enumeration = properties.propertyNames();
632610
while (enumeration.hasMoreElements()) {
633611
final String key = (String) enumeration.nextElement();
@@ -693,12 +671,4 @@ private void parseErrorHandler(
693671
}
694672
}
695673
}
696-
697-
Appender registryGet(final String name) {
698-
return (Appender) registry.get(name);
699-
}
700-
701-
void registryPut(final Appender appender) {
702-
registry.put(appender.getName(), appender);
703-
}
704674
}

0 commit comments

Comments
 (0)