Skip to content

Commit ceb7964

Browse files
rgoersppkarwasz
authored andcommitted
Spring 33450 - Spring shutdown fails due to IllegalStateException (#2062)
1 parent b7f42b1 commit ceb7964

File tree

4 files changed

+99
-19
lines changed

4 files changed

+99
-19
lines changed

log4j-api-test/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,23 @@ public void testPublish() {
188188
assertEquals("Log4j", value);
189189
}
190190

191+
@Test
192+
@ResourceLock(Resources.SYSTEM_PROPERTIES)
193+
public void testBadPropertysource() {
194+
final String key1 = "testKey";
195+
System.getProperties().put(key1, "test");
196+
final PropertiesUtil util = new PropertiesUtil(new Properties());
197+
ErrorPropertySource source = new ErrorPropertySource();
198+
util.addPropertySource(source);
199+
try {
200+
assertEquals("test", util.getStringProperty(key1));
201+
assertTrue(source.exceptionThrown);
202+
} finally {
203+
util.removePropertySource(source);
204+
System.getProperties().remove(key1);
205+
}
206+
}
207+
191208
private static final String[][] data = {
192209
{null, "org.apache.logging.log4j.level"},
193210
{null, "Log4jAnotherProperty"},
@@ -231,4 +248,25 @@ public void testLog4jProperty() {
231248
final PropertiesUtil util = new PropertiesUtil(props);
232249
assertEquals(correct, util.getStringProperty(correct));
233250
}
251+
252+
private class ErrorPropertySource implements PropertySource {
253+
public boolean exceptionThrown = false;
254+
255+
@Override
256+
public int getPriority() {
257+
return Integer.MIN_VALUE;
258+
}
259+
260+
@Override
261+
public String getProperty(String key) {
262+
exceptionThrown = true;
263+
throw new InstantiationError("Test");
264+
}
265+
266+
@Override
267+
public boolean containsProperty(String key) {
268+
exceptionThrown = true;
269+
throw new InstantiationError("Test");
270+
}
271+
}
234272
}

log4j-api/src/main/java/org/apache/logging/log4j/util/PropertiesUtil.java

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,27 @@ public static PropertiesUtil getProperties() {
139139
}
140140

141141
/**
142-
* Allows a PropertySource to be added after PropertiesUtil has been created.
143-
* @param propertySource the PropertySource to add.
142+
* Allows a {@link PropertySource} to be added after PropertiesUtil has been created.
143+
* @param propertySource the {@code PropertySource} to add.
144+
* @since 2.19.0
144145
*/
145146
public void addPropertySource(final PropertySource propertySource) {
146147
if (environment != null) {
147148
environment.addPropertySource(propertySource);
148149
}
149150
}
150151

152+
/**
153+
* Removes a {@link PropertySource}.
154+
* @param propertySource the {@code PropertySource} to remove.
155+
* @since 2.24.0
156+
*/
157+
public void removePropertySource(final PropertySource propertySource) {
158+
if (environment != null) {
159+
environment.removePropertySource(propertySource);
160+
}
161+
}
162+
151163
/**
152164
* Returns {@code true} if the specified property is defined, regardless of its value (it may not have a value).
153165
*
@@ -529,6 +541,10 @@ public void addPropertySource(final PropertySource propertySource) {
529541
sources.add(propertySource);
530542
}
531543

544+
private void removePropertySource(final PropertySource propertySource) {
545+
sources.remove(propertySource);
546+
}
547+
532548
private synchronized void reload() {
533549
literal.clear();
534550
tokenized.clear();
@@ -540,18 +556,18 @@ private synchronized void reload() {
540556
final List<CharSequence> tokens = PropertySource.Util.tokenize(key);
541557
final boolean hasTokens = !tokens.isEmpty();
542558
sources.forEach(source -> {
543-
if (source.containsProperty(key)) {
544-
final String value = source.getProperty(key);
559+
if (sourceContainsProperty(source, key)) {
560+
final String value = sourceGetProperty(source, key);
545561
if (hasTokens) {
546562
tokenized.putIfAbsent(tokens, value);
547563
}
548564
}
549565
if (hasTokens) {
550566
final String normalKey = Objects.toString(source.getNormalForm(tokens), null);
551-
if (normalKey != null && source.containsProperty(normalKey)) {
552-
literal.putIfAbsent(key, source.getProperty(normalKey));
553-
} else if (source.containsProperty(key)) {
554-
literal.putIfAbsent(key, source.getProperty(key));
567+
if (normalKey != null && sourceContainsProperty(source, normalKey)) {
568+
literal.putIfAbsent(key, sourceGetProperty(source, normalKey));
569+
} else if (sourceContainsProperty(source, key)) {
570+
literal.putIfAbsent(key, sourceGetProperty(source, key));
555571
}
556572
}
557573
});
@@ -567,25 +583,41 @@ private String get(final String key) {
567583
for (final PropertySource source : sources) {
568584
if (hasTokens) {
569585
final String normalKey = Objects.toString(source.getNormalForm(tokens), null);
570-
if (normalKey != null && source.containsProperty(normalKey)) {
571-
return source.getProperty(normalKey);
586+
if (normalKey != null && sourceContainsProperty(source, normalKey)) {
587+
return sourceGetProperty(source, normalKey);
572588
}
573589
}
574-
if (source.containsProperty(key)) {
575-
return source.getProperty(key);
590+
if (sourceContainsProperty(source, key)) {
591+
return sourceGetProperty(source, key);
576592
}
577593
}
578594
return tokenized.get(tokens);
579595
}
580596

597+
private boolean sourceContainsProperty(final PropertySource source, final String key) {
598+
try {
599+
return source.containsProperty(key);
600+
} catch (final Throwable ex) {
601+
return false;
602+
}
603+
}
604+
605+
private String sourceGetProperty(final PropertySource source, final String key) {
606+
try {
607+
return source.getProperty(key);
608+
} catch (final Throwable ex) {
609+
return null;
610+
}
611+
}
612+
581613
private boolean containsKey(final String key) {
582614
final List<CharSequence> tokens = PropertySource.Util.tokenize(key);
583615
return literal.containsKey(key)
584616
|| tokenized.containsKey(tokens)
585617
|| sources.stream().anyMatch(s -> {
586618
final CharSequence normalizedKey = s.getNormalForm(tokens);
587-
return s.containsProperty(key)
588-
|| (normalizedKey != null && s.containsProperty(normalizedKey.toString()));
619+
return sourceContainsProperty(s, key)
620+
|| (normalizedKey != null && sourceContainsProperty(s, normalizedKey.toString()));
589621
});
590622
}
591623
}

log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,14 @@ private static ContextSelector getContextSelector() {
240240
* @param loggerContextName name of the logger context to unregister
241241
*/
242242
public static void unregisterLoggerContext(final String loggerContextName) {
243-
if (isJmxDisabled()) {
244-
LOGGER.debug("JMX disabled for Log4j2. Not unregistering MBeans.");
245-
return;
243+
if (loggerContextName != null) {
244+
if (isJmxDisabled()) {
245+
LOGGER.debug("JMX disabled for Log4j2. Not unregistering MBeans.");
246+
return;
247+
}
248+
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
249+
unregisterLoggerContext(loggerContextName, mbs);
246250
}
247-
final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
248-
unregisterLoggerContext(loggerContextName, mbs);
249251
}
250252

251253
/**
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://logging.apache.org/log4j/changelog"
4+
xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.3.xsd"
5+
type="changed">
6+
<issue id="Spring-33450" link="https://github.com/spring-projects/spring-boot/issues/33450"/>
7+
<description format="asciidoc">Ignore exceptions thrown by PropertySources.</description>
8+
</entry>

0 commit comments

Comments
 (0)