This is an automated email from the ASF dual-hosted git repository.
rgoers pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/main by this push:
new 19d64c3e64 1799 - Spring shutdown fails due to ClassCastException.
Spring 33450 - Spring shutdown fails due to IllegalStateException (#2062)
19d64c3e64 is described below
commit 19d64c3e64443d9b7e416da2c96557933b086fcc
Author: Ralph Goers <[email protected]>
AuthorDate: Mon Dec 4 21:58:02 2023 -0700
1799 - Spring shutdown fails due to ClassCastException. Spring 33450 -
Spring shutdown fails due to IllegalStateException (#2062)
---
.../logging/log4j/util/PropertiesUtilTest.java | 38 +++
.../apache/logging/log4j/util/PropertiesUtil.java | 58 ++++-
.../logging/log4j/util/PropertyEnvironment.java | 6 +
.../logging/log4j/core/LoggerContextTest.java | 46 ++++
.../log4j/core/config/MissingRootLoggerTest.java | 6 +-
.../java/org/apache/logging/log4j/core/Logger.java | 11 +
.../apache/logging/log4j/core/LoggerContext.java | 10 +
.../log4j/core/config/ConfigurationFactory.java | 12 +
.../log4j/core/impl/Log4jContextFactory.java | 219 +++++++++-------
.../core/impl/internal/InternalLoggerContext.java | 290 +++++++++++++++++++++
.../org/apache/logging/log4j/core/jmx/Server.java | 12 +-
.../.3.x.x/1799_ignore _propertysource_errors.xml | 10 +
12 files changed, 608 insertions(+), 110 deletions(-)
diff --git
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
index 5aef842655..cb836fd617 100644
---
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
+++
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
@@ -140,6 +140,23 @@ public class PropertiesUtilTest {
assertEquals("Log4j", value);
}
+ @Test
+ @ResourceLock(Resources.SYSTEM_PROPERTIES)
+ public void testBadPropertysource() {
+ final String key1 = "testKey";
+ System.getProperties().put(key1, "test");
+ final PropertiesUtil util = new PropertiesUtil(new Properties());
+ ErrorPropertySource source = new ErrorPropertySource();
+ util.addPropertySource(source);
+ try {
+ assertEquals("test", util.getStringProperty(key1));
+ assertTrue(source.exceptionThrown);
+ } finally {
+ util.removePropertySource(source);
+ System.getProperties().remove(key1);
+ }
+ }
+
private static final String[][] data = {
{null, "org.apache.logging.log4j.level"},
{null, "Log4jAnotherProperty"},
@@ -184,4 +201,25 @@ public class PropertiesUtilTest {
final PropertiesUtil util = new PropertiesUtil(props);
assertNull(util.getStringProperty(correct));
}
+
+ private class ErrorPropertySource implements PropertySource {
+ public boolean exceptionThrown = false;
+
+ @Override
+ public int getPriority() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public String getProperty(String key) {
+ exceptionThrown = true;
+ throw new InstantiationError("Test");
+ }
+
+ @Override
+ public boolean containsProperty(String key) {
+ exceptionThrown = true;
+ throw new InstantiationError("Test");
+ }
+ }
}
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 cf4e011ab5..dcb1a4fbad 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
@@ -199,6 +199,13 @@ public class PropertiesUtil implements PropertyEnvironment
{
}
}
+ @Override
+ public void removePropertySource(final PropertySource propertySource) {
+ if (environment != null) {
+ environment.removePropertySource(propertySource);
+ }
+ }
+
/**
* Returns {@code true} if the specified property is defined, regardless
of its value (it may not have a value).
*
@@ -683,6 +690,11 @@ public class PropertiesUtil implements PropertyEnvironment
{
sources.add(propertySource);
}
+ @Override
+ public void removePropertySource(final PropertySource propertySource) {
+ sources.remove(propertySource);
+ }
+
private void reload() {
literal.clear();
sources.forEach((s) -> {
@@ -700,14 +712,14 @@ public class PropertiesUtil implements
PropertyEnvironment {
sources.forEach(source -> {
if (source instanceof ContextAwarePropertySource) {
final ContextAwarePropertySource src =
Cast.cast(source);
- if (src.containsProperty(contextName, contextKey))
{
+ if (sourceContainsProperty(src, contextName,
contextKey)) {
literal.putIfAbsent(key,
src.getProperty(contextName, contextKey));
}
}
});
}
sources.forEach(source -> {
- if (source.containsProperty(contextKey)) {
+ if (sourceContainsProperty(source, contextKey)) {
literal.putIfAbsent(key,
source.getProperty(contextKey));
}
});
@@ -727,7 +739,7 @@ public class PropertiesUtil implements PropertyEnvironment {
while (source != null) {
if (source instanceof ContextAwarePropertySource) {
final ContextAwarePropertySource src =
Cast.cast(source);
- result = src.getProperty(contextName, contextKey);
+ result = sourceGetProperty(src, contextName,
contextKey);
}
if (result != null) {
return result;
@@ -737,7 +749,7 @@ public class PropertiesUtil implements PropertyEnvironment {
}
PropertySource source = sources.first();
while (source != null) {
- result = source.getProperty(contextKey);
+ result = sourceGetProperty(source, contextKey);
if (result != null) {
return result;
}
@@ -746,6 +758,22 @@ public class PropertiesUtil implements PropertyEnvironment
{
return result;
}
+ private String sourceGetProperty(ContextAwarePropertySource source,
String contextName, String key) {
+ try {
+ return source.getProperty(contextName, key);
+ } catch (Throwable ex) {
+ return null;
+ }
+ }
+
+ private String sourceGetProperty(PropertySource source, String key) {
+ try {
+ return source.getProperty(key);
+ } catch (Throwable ex) {
+ return null;
+ }
+ }
+
@Override
public boolean hasProperty(final String key) {
if (literal.containsKey(key)) {
@@ -758,7 +786,7 @@ public class PropertiesUtil implements PropertyEnvironment {
while (source != null) {
if (source instanceof ContextAwarePropertySource) {
final ContextAwarePropertySource src =
Cast.cast(source);
- if (src.containsProperty(contextName, contextKey)) {
+ if (sourceContainsProperty(src, contextName,
contextKey)) {
return true;
}
}
@@ -769,9 +797,9 @@ public class PropertiesUtil implements PropertyEnvironment {
while (source != null) {
if (source instanceof ContextAwarePropertySource) {
final ContextAwarePropertySource src = Cast.cast(source);
- if (src.containsProperty(contextName, contextKey)
+ if (sourceContainsProperty(src, contextName, contextKey)
||
(!contextName.equals(PropertySource.SYSTEM_CONTEXT)
- &&
src.containsProperty(PropertySource.SYSTEM_CONTEXT, contextKey))) {
+ && sourceContainsProperty(src,
PropertySource.SYSTEM_CONTEXT, contextKey))) {
return true;
}
} else {
@@ -784,6 +812,22 @@ public class PropertiesUtil implements PropertyEnvironment
{
return false;
}
+ private boolean sourceContainsProperty(ContextAwarePropertySource
source, String contextName, String key) {
+ try {
+ return source.containsProperty(contextName, key);
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
+
+ private boolean sourceContainsProperty(PropertySource source, String
key) {
+ try {
+ return source.containsProperty(key);
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
+
private String getContextKey(final String key) {
String keyToCheck = key;
if (keyToCheck.startsWith(PropertySource.PREFIX)) {
diff --git
a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertyEnvironment.java
b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertyEnvironment.java
index 3947e7ab62..701bcf6955 100644
---
a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertyEnvironment.java
+++
b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertyEnvironment.java
@@ -28,6 +28,12 @@ public interface PropertyEnvironment {
*/
void addPropertySource(PropertySource propertySource);
+ /**
+ * Allows a PropertySource that was added to be removed.
+ * @param propertySource the PropertySource to remove.
+ */
+ void removePropertySource(PropertySource propertySource);
+
/**
* Returns {@code true} if the specified property is defined, regardless
of its value (it may not have a value).
*
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerContextTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerContextTest.java
new file mode 100644
index 0000000000..4b2f417de1
--- /dev/null
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerContextTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.core;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
+import org.apache.logging.log4j.core.impl.internal.InternalLoggerContext;
+import org.apache.logging.log4j.core.util.DefaultShutdownCallbackRegistry;
+import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Validate Logging after Shutdown.
+ */
+public class LoggerContextTest {
+
+ @Test
+ public void shutdownTest() {
+ LoggerContextFactory contextFactory = LogManager.getFactory();
+ assertTrue(contextFactory instanceof Log4jContextFactory);
+ Log4jContextFactory factory = (Log4jContextFactory) contextFactory;
+ ShutdownCallbackRegistry registry =
factory.getShutdownCallbackRegistry();
+ assertTrue(registry instanceof DefaultShutdownCallbackRegistry);
+ ((DefaultShutdownCallbackRegistry) registry).start();
+ ((DefaultShutdownCallbackRegistry) registry).stop();
+ LoggerContext loggerContext =
factory.getContext(LoggerContextTest.class.getName(), null, null, false);
+ assertTrue(loggerContext instanceof InternalLoggerContext);
+ }
+}
diff --git
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
index de0ce39370..b1d5778e97 100644
---
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
@@ -21,6 +21,7 @@ import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Map;
@@ -48,7 +49,7 @@ public class MissingRootLoggerTest {
assertNotNull(map, "Appenders not null");
assertThat("There should only be two appenders", map, hasSize(2));
assertThat(map, hasKey("List"));
- assertThat(map, hasKey("DefaultConsole-2"));
+ assertThat(map, hasKey(startsWith("DefaultConsole-")));
final Map<String, LoggerConfig> loggerMap = config.getLoggers();
assertNotNull(loggerMap, "loggerMap not null");
@@ -67,7 +68,8 @@ public class MissingRootLoggerTest {
final Map<String, Appender> rootAppenders = root.getAppenders();
assertThat("The root logger should only have one appender",
rootAppenders, hasSize(1));
// root only has Console appender!
- assertThat("The root appender should be a ConsoleAppender",
rootAppenders, hasKey("DefaultConsole-2"));
+ assertThat(
+ "The root appender should be a ConsoleAppender",
rootAppenders, hasKey(startsWith("DefaultConsole-")));
assertEquals(Level.ERROR, root.getLevel());
}
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
index d7a0c532ce..1ab8eae227 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/Logger.java
@@ -66,6 +66,17 @@ public class Logger extends AbstractLogger implements
Supplier<LoggerConfig> {
privateConfig = new PrivateConfig(context.getConfiguration(), this);
}
+ /**
+ * This is used to construct an InternalLoggerContext, which makes
SimpleLoggerContext conmpatible with core.
+ * @param context the InternalLoggerContext.
+ * @param name the Logger name.
+ */
+ protected Logger(final LoggerContext context, final String name) {
+ super(name);
+ this.context = context;
+ privateConfig = null;
+ }
+
/**
* This method is only used for 1.x compatibility. Returns the parent of
this Logger. If it doesn't already exist
* return a temporary Logger.
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
index c0da220b40..7a70e0a61c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java
@@ -99,6 +99,15 @@ public class LoggerContext extends AbstractLifeCycle
private final Lock configLock = new ReentrantLock();
+ /**
+ * Constructor used to create an InternalLoggerContext.
+ */
+ protected LoggerContext() {
+ setStarted();
+ instanceFactory = null;
+ this.nullConfiguration = null;
+ }
+
/**
* Constructor taking only a name.
*
@@ -428,6 +437,7 @@ public class LoggerContext extends AbstractLifeCycle
}
this.setStopping();
+ String name = getName();
try {
Server.unregisterLoggerContext(getName()); // LOG4J2-406,
LOG4J2-500
} catch (final LinkageError | Exception e) {
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
index 257a61a5d6..0898b7a98f 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
@@ -21,12 +21,15 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import
org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.impl.Log4jPropertyKey;
+import org.apache.logging.log4j.core.util.AuthorizationProvider;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory;
import org.apache.logging.log4j.plugins.di.Key;
import org.apache.logging.log4j.plugins.model.PluginNamespace;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.PropertyEnvironment;
import org.apache.logging.log4j.util.PropertyKey;
/**
@@ -118,6 +121,15 @@ public abstract class ConfigurationFactory extends
ConfigurationBuilderFactory {
return true;
}
+ /**
+ * Required for Spring Boot.
+ * @param props PropertiesUtil.
+ * @return the AuthorizationProvider, if any.
+ */
+ public static AuthorizationProvider authorizationProvider(final
PropertiesUtil props) {
+ return
AuthorizationProvider.getAuthorizationProvider((PropertyEnvironment) props);
+ }
+
public abstract Configuration getConfiguration(final LoggerContext
loggerContext, ConfigurationSource source);
/**
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
index 59e2de4ac6..e805c843f0 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java
@@ -30,6 +30,7 @@ import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
+import org.apache.logging.log4j.core.impl.internal.InternalLoggerContext;
import org.apache.logging.log4j.core.selector.ContextSelector;
import org.apache.logging.log4j.core.util.Cancellable;
import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry;
@@ -54,6 +55,8 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
private final ContextSelector selector;
private final ShutdownCallbackRegistry shutdownCallbackRegistry;
+ private final LoggerContext internalContext = new InternalLoggerContext();
+
/**
* Initializes the ContextSelector from system property {@link
Log4jPropertyKey#CONTEXT_SELECTOR_CLASS_NAME}.
*/
@@ -146,8 +149,12 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
if (externalContext != null && ctx.getExternalContext() == null) {
ctx.setExternalContext(externalContext);
}
- if (ctx.getState() == LifeCycle.State.INITIALIZED) {
- startContext(ctx, classLoader);
+ try {
+ if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+ startContext(ctx, classLoader);
+ }
+ } catch (IllegalStateException ex) {
+ return internalContext;
}
return ctx;
}
@@ -223,23 +230,27 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
if (externalContext != null && ctx.getExternalContext() == null) {
ctx.setExternalContext(externalContext);
}
- if (ctx.getState() == LifeCycle.State.INITIALIZED) {
- ContextAnchor.THREAD_CONTEXT.set(ctx);
- boolean setProperties = false;
- try {
- if (ctx.getProperties() == null) {
- final PropertiesUtil props =
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
- ctx.setProperties(props);
- PropertiesUtil.setThreadProperties(props);
- setProperties = true;
- }
- ctx.start(configuration);
- } finally {
- if (setProperties) {
- PropertiesUtil.clearThreadProperties();
+ try {
+ if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+ ContextAnchor.THREAD_CONTEXT.set(ctx);
+ boolean setProperties = false;
+ try {
+ if (ctx.getProperties() == null) {
+ final PropertiesUtil props =
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
+ ctx.setProperties(props);
+ PropertiesUtil.setThreadProperties(props);
+ setProperties = true;
+ }
+ ctx.start(configuration);
+ } finally {
+ if (setProperties) {
+ PropertiesUtil.clearThreadProperties();
+ }
+ ContextAnchor.THREAD_CONTEXT.remove();
}
- ContextAnchor.THREAD_CONTEXT.remove();
}
+ } catch (IllegalStateException ex) {
+ return internalContext;
}
return ctx;
}
@@ -271,29 +282,34 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
if (name != null) {
ctx.setName(name);
}
- if (ctx.getState() == LifeCycle.State.INITIALIZED) {
- if (configLocation != null || name != null) {
- ContextAnchor.THREAD_CONTEXT.set(ctx);
- boolean setProperties = false;
- try {
- if (ctx.getProperties() == null) {
- final PropertiesUtil props =
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
- ctx.setProperties(props);
- PropertiesUtil.setThreadProperties(props);
- setProperties = true;
- }
- final Configuration config = ctx.getConfiguration(name,
configLocation);
- LOGGER.debug("Starting {} from configuration at {}", ctx,
configLocation);
- ctx.start(config);
- } finally {
- if (setProperties) {
- PropertiesUtil.clearThreadProperties();
+ try {
+ if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+ if (configLocation != null || name != null) {
+ ContextAnchor.THREAD_CONTEXT.set(ctx);
+ boolean setProperties = false;
+ try {
+ if (ctx.getProperties() == null) {
+ final PropertiesUtil props =
+
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
+ ctx.setProperties(props);
+ PropertiesUtil.setThreadProperties(props);
+ setProperties = true;
+ }
+ final Configuration config =
ctx.getConfiguration(name, configLocation);
+ LOGGER.debug("Starting {} from configuration at {}",
ctx, configLocation);
+ ctx.start(config);
+ } finally {
+ if (setProperties) {
+ PropertiesUtil.clearThreadProperties();
+ }
+ ContextAnchor.THREAD_CONTEXT.remove();
}
- ContextAnchor.THREAD_CONTEXT.remove();
+ } else {
+ startContext(ctx, classLoader);
}
- } else {
- startContext(ctx, classLoader);
}
+ } catch (IllegalStateException ex) {
+ return internalContext;
}
return ctx;
}
@@ -311,29 +327,34 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
if (name != null) {
ctx.setName(name);
}
- if (ctx.getState() == LifeCycle.State.INITIALIZED) {
- if (configLocation != null || name != null) {
- boolean setProperties = false;
- try {
- if (ctx.getProperties() == null) {
- final PropertiesUtil props =
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
- ctx.setProperties(props);
- PropertiesUtil.setThreadProperties(props);
- setProperties = true;
- }
- ContextAnchor.THREAD_CONTEXT.set(ctx);
- final Configuration config = ctx.getConfiguration(name,
configLocation);
- LOGGER.debug("Starting {} from configuration at {}", ctx,
configLocation);
- ctx.start(config);
- } finally {
- if (setProperties) {
- PropertiesUtil.clearThreadProperties();
+ try {
+ if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+ if (configLocation != null || name != null) {
+ boolean setProperties = false;
+ try {
+ if (ctx.getProperties() == null) {
+ final PropertiesUtil props =
+
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
+ ctx.setProperties(props);
+ PropertiesUtil.setThreadProperties(props);
+ setProperties = true;
+ }
+ ContextAnchor.THREAD_CONTEXT.set(ctx);
+ final Configuration config =
ctx.getConfiguration(name, configLocation);
+ LOGGER.debug("Starting {} from configuration at {}",
ctx, configLocation);
+ ctx.start(config);
+ } finally {
+ if (setProperties) {
+ PropertiesUtil.clearThreadProperties();
+ }
+ ContextAnchor.THREAD_CONTEXT.remove();
}
- ContextAnchor.THREAD_CONTEXT.remove();
+ } else {
+ startContext(ctx, classLoader);
}
- } else {
- startContext(ctx, classLoader);
}
+ } catch (IllegalStateException ex) {
+ return internalContext;
}
return ctx;
}
@@ -355,52 +376,58 @@ public class Log4jContextFactory implements
LoggerContextFactory, ShutdownCallba
if (name != null) {
ctx.setName(name);
}
- if (ctx.getState() == LifeCycle.State.INITIALIZED) {
- if ((configLocations != null && !configLocations.isEmpty())) {
- ContextAnchor.THREAD_CONTEXT.set(ctx);
- boolean setProperties = false;
- try {
- final List<AbstractConfiguration> configurations = new
ArrayList<>(configLocations.size());
- if (ctx.getProperties() == null) {
- final PropertiesUtil props =
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
- ctx.setProperties(props);
- PropertiesUtil.setThreadProperties(props);
- setProperties = true;
- }
- for (final URI configLocation : configLocations) {
- final Configuration currentReadConfiguration =
ctx.getConfiguration(name, configLocation);
- if (currentReadConfiguration != null) {
- if (currentReadConfiguration instanceof
DefaultConfiguration) {
- LOGGER.warn("Unable to locate configuration
{}, ignoring", configLocation.toString());
- } else if (currentReadConfiguration instanceof
AbstractConfiguration) {
- configurations.add((AbstractConfiguration)
currentReadConfiguration);
+ try {
+ if (ctx.getState() == LifeCycle.State.INITIALIZED) {
+ if ((configLocations != null && !configLocations.isEmpty())) {
+ ContextAnchor.THREAD_CONTEXT.set(ctx);
+ boolean setProperties = false;
+ try {
+ final List<AbstractConfiguration> configurations = new
ArrayList<>(configLocations.size());
+ if (ctx.getProperties() == null) {
+ final PropertiesUtil props =
+
PropertiesUtil.getContextProperties(classLoader, ctx.getName());
+ ctx.setProperties(props);
+ PropertiesUtil.setThreadProperties(props);
+ setProperties = true;
+ }
+ for (final URI configLocation : configLocations) {
+ final Configuration currentReadConfiguration =
ctx.getConfiguration(name, configLocation);
+ if (currentReadConfiguration != null) {
+ if (currentReadConfiguration instanceof
DefaultConfiguration) {
+ LOGGER.warn(
+ "Unable to locate configuration
{}, ignoring", configLocation.toString());
+ } else if (currentReadConfiguration instanceof
AbstractConfiguration) {
+ configurations.add((AbstractConfiguration)
currentReadConfiguration);
+ } else {
+ LOGGER.error(
+ "Found configuration {}, which is
not an AbstractConfiguration and can't be handled by CompositeConfiguration",
+ configLocation);
+ }
} else {
- LOGGER.error(
- "Found configuration {}, which is not
an AbstractConfiguration and can't be handled by CompositeConfiguration",
- configLocation);
+ LOGGER.info("Unable to access configuration
{}, ignoring", configLocation.toString());
}
+ }
+ if (configurations.isEmpty()) {
+ LOGGER.error("No configurations could be created
for {}", configLocations.toString());
+ } else if (configurations.size() == 1) {
+ ctx.start(configurations.get(0));
} else {
- LOGGER.info("Unable to access configuration {},
ignoring", configLocation.toString());
+ final CompositeConfiguration
compositeConfiguration =
+ new CompositeConfiguration(configurations);
+ ctx.start(compositeConfiguration);
}
+ } finally {
+ if (setProperties) {
+ PropertiesUtil.clearThreadProperties();
+ }
+ ContextAnchor.THREAD_CONTEXT.remove();
}
- if (configurations.isEmpty()) {
- LOGGER.error("No configurations could be created for
{}", configLocations.toString());
- } else if (configurations.size() == 1) {
- ctx.start(configurations.get(0));
- } else {
- final CompositeConfiguration compositeConfiguration =
- new CompositeConfiguration(configurations);
- ctx.start(compositeConfiguration);
- }
- } finally {
- if (setProperties) {
- PropertiesUtil.clearThreadProperties();
- }
- ContextAnchor.THREAD_CONTEXT.remove();
+ } else {
+ startContext(ctx, classLoader);
}
- } else {
- startContext(ctx, classLoader);
}
+ } catch (IllegalStateException ex) {
+ return internalContext;
}
return ctx;
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/internal/InternalLoggerContext.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/internal/InternalLoggerContext.java
new file mode 100644
index 0000000000..9f7f247721
--- /dev/null
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/internal/InternalLoggerContext.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.logging.log4j.core.impl.internal;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogBuilder;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.simple.SimpleLoggerContext;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+
+/**
+ * Creates a SimpleLoggerContext compatible with log4j-core. This class is
internal to Log4j.
+ */
+public class InternalLoggerContext extends LoggerContext {
+
+ private final SimpleLoggerContext simpleLoggerContext = new
SimpleLoggerContext();
+
+ private static final LoggerConfig LOGGER_CONFIG = new
LoggerConfig.RootLogger();
+
+ public InternalLoggerContext() {
+ super();
+ setStarted();
+ }
+
+ @Override
+ protected Logger newInstance(final LoggerContext ctx, final String name,
final MessageFactory messageFactory) {
+ return new InternalLogger(this, name);
+ }
+
+ @Override
+ public boolean stop(final long timeout, final TimeUnit timeUnit) {
+ return false;
+ }
+
+ private class InternalLogger extends Logger {
+ private final ExtendedLogger logger;
+ private final InternalLoggerContext loggerContext;
+
+ public InternalLogger(InternalLoggerContext loggerContext, String
name) {
+ super(loggerContext, name);
+ this.loggerContext = loggerContext;
+ this.logger = simpleLoggerContext.getLogger(name);
+ }
+
+ @Override
+ public Logger getParent() {
+ return null;
+ }
+
+ @Override
+ public LoggerContext getContext() {
+ return loggerContext;
+ }
+
+ @Override
+ public void setLevel(final Level level) {}
+
+ @Override
+ public LoggerConfig get() {
+ return LOGGER_CONFIG;
+ }
+
+ @Override
+ protected boolean requiresLocation() {
+ return false;
+ }
+
+ @Override
+ public void logMessage(String fqcn, Level level, Marker marker,
Message message, Throwable t) {}
+
+ @Override
+ protected void log(
+ Level level,
+ Marker marker,
+ String fqcn,
+ StackTraceElement location,
+ Message message,
+ Throwable throwable) {
+ logger.log(level, marker, message, throwable);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message,
Throwable t) {
+ return logger.isEnabled(level, marker, message, t);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message) {
+ return logger.isEnabled(level, marker, message);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message,
Object... params) {
+ return logger.isEnabled(level, marker, message, params);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message,
Object p0) {
+ return logger.isEnabled(level, marker, message, p0);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message,
Object p0, Object p1) {
+ return logger.isEnabled(level, marker, message, p0, p1);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, String message,
Object p0, Object p1, Object p2) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level, Marker marker, String message, Object p0, Object
p1, Object p2, Object p3) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level, Marker marker, String message, Object p0, Object
p1, Object p2, Object p3, Object p4) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level,
+ Marker marker,
+ String message,
+ Object p0,
+ Object p1,
+ Object p2,
+ Object p3,
+ Object p4,
+ Object p5) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4, p5);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level,
+ Marker marker,
+ String message,
+ Object p0,
+ Object p1,
+ Object p2,
+ Object p3,
+ Object p4,
+ Object p5,
+ Object p6) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4, p5, p6);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level,
+ Marker marker,
+ String message,
+ Object p0,
+ Object p1,
+ Object p2,
+ Object p3,
+ Object p4,
+ Object p5,
+ Object p6,
+ Object p7) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4, p5, p6, p7);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level,
+ Marker marker,
+ String message,
+ Object p0,
+ Object p1,
+ Object p2,
+ Object p3,
+ Object p4,
+ Object p5,
+ Object p6,
+ Object p7,
+ Object p8) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4, p5, p6, p7, p8);
+ }
+
+ @Override
+ public boolean isEnabled(
+ Level level,
+ Marker marker,
+ String message,
+ Object p0,
+ Object p1,
+ Object p2,
+ Object p3,
+ Object p4,
+ Object p5,
+ Object p6,
+ Object p7,
+ Object p8,
+ Object p9) {
+ return logger.isEnabled(level, marker, message, p0, p1, p2, p3,
p4, p5, p6, p7, p8, p9);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, CharSequence
message, Throwable t) {
+ return logger.isEnabled(level, marker, message, t);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, Object message,
Throwable t) {
+ return logger.isEnabled(level, marker, message, t);
+ }
+
+ @Override
+ public boolean isEnabled(Level level, Marker marker, Message message,
Throwable t) {
+ return logger.isEnabled(level, marker, message, t);
+ }
+
+ @Override
+ public void addAppender(Appender appender) {}
+
+ @Override
+ public void removeAppender(Appender appender) {}
+
+ @Override
+ public Map<String, Appender> getAppenders() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Iterator<Filter> getFilters() {
+ return Collections.emptyIterator();
+ }
+
+ @Override
+ public Level getLevel() {
+ return logger.getLevel();
+ }
+
+ @Override
+ public int filterCount() {
+ return 0;
+ }
+
+ @Override
+ public void addFilter(Filter filter) {}
+
+ @Override
+ public boolean isAdditive() {
+ return false;
+ }
+
+ @Override
+ public void setAdditive(boolean additive) {}
+
+ @Override
+ public LogBuilder atLevel(Level level) {
+ return logger.atLevel(level);
+ }
+
+ @Override
+ protected void updateConfiguration(Configuration newConfig) {}
+ }
+}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
index 1a4a7ed744..e7ee25c3d4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java
@@ -238,12 +238,14 @@ public final class Server {
* @param loggerContextName name of the logger context to unregister
*/
public static void unregisterLoggerContext(final String loggerContextName)
{
- if (isJmxDisabled()) {
- LOGGER.debug("JMX disabled for Log4j2. Not unregistering MBeans.");
- return;
+ if (loggerContextName != null) {
+ if (isJmxDisabled()) {
+ LOGGER.debug("JMX disabled for Log4j2. Not unregistering
MBeans.");
+ return;
+ }
+ final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ unregisterLoggerContext(loggerContextName, mbs);
}
- final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- unregisterLoggerContext(loggerContextName, mbs);
}
/**
diff --git a/src/changelog/.3.x.x/1799_ignore _propertysource_errors.xml
b/src/changelog/.3.x.x/1799_ignore _propertysource_errors.xml
new file mode 100644
index 0000000000..5810ca6b6f
--- /dev/null
+++ b/src/changelog/.3.x.x/1799_ignore _propertysource_errors.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://logging.apache.org/log4j/changelog"
+ xsi:schemaLocation="http://logging.apache.org/log4j/changelog
https://logging.apache.org/log4j/changelog-0.1.2.xsd"
+ type="changed">
+ <issue id="Spring-33450"
link="https://github.com/spring-projects/spring-boot/issues/33450"/>
+ <issue id="1799"
link="https://github.com/apache/logging-log4j2/issues/1799"/>
+ <author id="rgoers"/>
+ <description format="asciidoc">Ignore exceptions thrown by PropertySources.
Eliminate ClassCastException when SimpleLoggerContext is used.</description>
+</entry>