You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2015/09/18 17:38:50 UTC
logging-log4j2 git commit: [LOG4J2-1123] Core
Configurator.initialize(String, ClassLoader,
String) fails to work when config location is a file path. Replace
FileUtils.getCorrectedFilePathUri(String) with NetUtils.toURI(String).
Repository: logging-log4j2
Updated Branches:
refs/heads/master 55c787f4f -> 1542ec121
[LOG4J2-1123] Core Configurator.initialize(String, ClassLoader, String)
fails to work when config location is a file path. Replace
FileUtils.getCorrectedFilePathUri(String) with NetUtils.toURI(String).
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/1542ec12
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/1542ec12
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/1542ec12
Branch: refs/heads/master
Commit: 1542ec121cce478bccd7f51fec64c59d61bb9115
Parents: 55c787f
Author: ggregory <gg...@apache.org>
Authored: Fri Sep 18 08:38:42 2015 -0700
Committer: ggregory <gg...@apache.org>
Committed: Fri Sep 18 08:38:42 2015 -0700
----------------------------------------------------------------------
.../log4j/core/config/ConfigurationFactory.java | 3 +-
.../logging/log4j/core/config/Configurator.java | 630 +++++++++----------
.../core/config/status/StatusConfiguration.java | 3 +-
.../logging/log4j/core/util/FileUtils.java | 12 -
.../logging/log4j/core/util/NetUtils.java | 26 +
.../log4j/core/config/ConfiguratorTest.java | 47 ++
.../logging/log4j/core/util/FileUtilsTest.java | 18 -
.../logging/log4j/core/util/NetUtilsTest.java | 57 ++
log4j-core/src/test/resources/log4j-list.xml | 29 +
.../log4j/web/Log4jWebInitializerImpl.java | 532 ++++++++--------
src/changes/changes.xml | 3 +
11 files changed, 744 insertions(+), 616 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
----------------------------------------------------------------------
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 a6f5404..22327d8 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
@@ -42,6 +42,7 @@ import org.apache.logging.log4j.core.lookup.Interpolator;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.core.util.FileUtils;
import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.core.util.NetUtils;
import org.apache.logging.log4j.core.util.ReflectionUtil;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.LoaderUtil;
@@ -394,7 +395,7 @@ public abstract class ConfigurationFactory extends ConfigurationBuilderFactory {
if (configLocationStr != null) {
ConfigurationSource source = null;
try {
- source = getInputFromUri(FileUtils.getCorrectedFilePathUri(configLocationStr));
+ source = getInputFromUri(NetUtils.toURI(configLocationStr));
} catch (final Exception ex) {
// Ignore the error and try as a String.
LOGGER.catching(Level.DEBUG, ex);
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
index c038397..fe6a5d5 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/Configurator.java
@@ -1,318 +1,312 @@
-/*
- * 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.config;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Map;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.impl.Log4jContextFactory;
-import org.apache.logging.log4j.core.util.FileUtils;
-import org.apache.logging.log4j.spi.LoggerContextFactory;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * Initializes and configure the Logging system. This class provides several ways to construct a LoggerContext using
- * the location of a configuration file, a context name, and various optional parameters.
- */
-public final class Configurator {
-
- private static final String FQCN = Configurator.class.getName();
-
- private static final Logger LOGGER = StatusLogger.getLogger();
-
- private static Log4jContextFactory getFactory() {
- final LoggerContextFactory factory = LogManager.getFactory();
- if (factory instanceof Log4jContextFactory) {
- return (Log4jContextFactory) factory;
- } else if (factory != null) {
- LOGGER.error("LogManager returned an instance of {} which does not implement {}. Unable to initialize Log4j.",
- factory.getClass().getName(), Log4jContextFactory.class.getName());
- return null;
- } else {
- LOGGER.fatal("LogManager did not return a LoggerContextFactory. This indicates something has gone terribly wrong!");
- return null;
- }
- }
-
- /**
- * Initializes the Logging Context.
- * @param loader The ClassLoader for the Context (or null).
- * @param source The InputSource for the configuration.
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(final ClassLoader loader,
- final ConfigurationSource source) {
- return initialize(loader, source, null);
- }
-
- /**
- * Initializes the Logging Context.
- * @param loader The ClassLoader for the Context (or null).
- * @param source The InputSource for the configuration.
- * @param externalContext The external context to be attached to the LoggerContext.
- * @return The LoggerContext.
- */
-
- public static LoggerContext initialize(final ClassLoader loader,
- final ConfigurationSource source,
- final Object externalContext)
- {
-
- try {
- final Log4jContextFactory factory = getFactory();
- return factory == null ? null :
- factory.getContext(FQCN, loader, externalContext, false, source);
- } catch (final Exception ex) {
- LOGGER.error("There was a problem obtaining a LoggerContext using the configuration source [{}]", source, ex);
- }
- return null;
- }
-
- /**
- * Initializes the Logging Context.
- * @param name The Context name.
- * @param loader The ClassLoader for the Context (or null).
- * @param configLocation The configuration for the logging context.
- * @return The LoggerContext or null if an error occurred (check the status logger).
- */
- public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation) {
- return initialize(name, loader, configLocation, null);
-
- }
-
- /**
- * Initializes the Logging Context.
- * @param name The Context name.
- * @param loader The ClassLoader for the Context (or null).
- * @param configLocation The configuration for the logging context (or null, or blank).
- * @param externalContext The external context to be attached to the LoggerContext
- * @return The LoggerContext or null if an error occurred (check the status logger).
- */
- public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation,
- final Object externalContext) {
- try {
- final URI uri = Strings.isBlank(configLocation) ? null : FileUtils.getCorrectedFilePathUri(configLocation);
- return initialize(name, loader, uri, externalContext);
- } catch (final URISyntaxException ex) {
- LOGGER.error("There was a problem parsing the configuration location [{}].", configLocation, ex);
- }
- return null;
- }
-
- /**
- * Initializes the Logging Context.
- * @param name The Context name.
- * @param loader The ClassLoader for the Context (or null).
- * @param configLocation The configuration for the logging context.
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation) {
- return initialize(name, loader, configLocation, null);
- }
-
- /**
- * Initializes the Logging Context.
- * @param name The Context name.
- * @param loader The ClassLoader for the Context (or null).
- * @param configLocation The configuration for the logging context (or null).
- * @param externalContext The external context to be attached to the LoggerContext
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation,
- final Object externalContext) {
-
- try {
- final Log4jContextFactory factory = getFactory();
- return factory == null ? null :
- factory.getContext(FQCN, loader, externalContext, false, configLocation, name);
- } catch (final Exception ex) {
- LOGGER.error("There was a problem initializing the LoggerContext [{}] using configuration at [{}].",
- name, configLocation, ex);
- }
- return null;
- }
-
- /**
- * Initializes the Logging Context.
- * @param name The Context name.
- * @param configLocation The configuration for the logging context.
- * @return The LoggerContext or null if an error occurred (check the status logger).
- */
- public static LoggerContext initialize(final String name, final String configLocation) {
- return initialize(name, null, configLocation);
- }
-
- /**
- * Initializes the Logging Context.
- * @param configuration The Configuration.
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(Configuration configuration) {
- return initialize(null, configuration, null);
- }
-
- /**
- * Initializes the Logging Context.
- * @param loader The ClassLoader.
- * @param configuration The Configuration.
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(final ClassLoader loader, Configuration configuration) {
- return initialize(loader, configuration, null);
- }
-
- /**
- * Initializes the Logging Context.
- * @param loader The ClassLoader.
- * @param configuration The Configuration.
- * @param externalContext - The external context to be attached to the LoggerContext.
- * @return The LoggerContext.
- */
- public static LoggerContext initialize(final ClassLoader loader, Configuration configuration, final Object externalContext) {
- try {
- final Log4jContextFactory factory = getFactory();
- return factory == null ? null :
- factory.getContext(FQCN, loader, externalContext, false, configuration);
- } catch (final Exception ex) {
- LOGGER.error("There was a problem initializing the LoggerContext using configuration {}",
- configuration.getName(), ex);
- }
- return null;
- }
-
- /**
- * Sets the levels of <code>parentLogger</code> and all 'child' loggers to the given <code>level</code>.
- * @param parentLogger the parent logger
- * @param level the new level
- */
- public static void setAllLevels(final String parentLogger, final Level level) {
- // 1) get logger config
- // 2) if exact match, use it, if not, create it.
- // 3) set level on logger config
- // 4) update child logger configs with level
- // 5) update loggers
- final LoggerContext loggerContext = LoggerContext.getContext(false);
- final Configuration config = loggerContext.getConfiguration();
- boolean set = setLevel(parentLogger, level, config);
- for (final Map.Entry<String, LoggerConfig> entry : config.getLoggers().entrySet()) {
- if (entry.getKey().startsWith(parentLogger)) {
- set |= setLevel(entry.getValue(), level);
- }
- }
- if (set) {
- loggerContext.updateLoggers();
- }
- }
-
- private static boolean setLevel(final LoggerConfig loggerConfig, final Level level) {
- final boolean set = !loggerConfig.getLevel().equals(level);
- if (set) {
- loggerConfig.setLevel(level);
- }
- return set;
- }
-
- /**
- * Sets logger levels.
- *
- * @param levelMap
- * a levelMap where keys are level names and values are new
- * Levels.
- */
- public static void setLevel(final Map<String, Level> levelMap) {
- final LoggerContext loggerContext = LoggerContext.getContext(false);
- final Configuration config = loggerContext.getConfiguration();
- boolean set = false;
- for (final Map.Entry<String, Level> entry : levelMap.entrySet()) {
- final String loggerName = entry.getKey();
- final Level level = entry.getValue();
- set |= setLevel(loggerName, level, config);
- }
- if (set) {
- loggerContext.updateLoggers();
- }
- }
-
- /**
- * Sets a logger's level.
- *
- * @param loggerName
- * the logger name
- * @param level
- * the new level
- */
- public static void setLevel(final String loggerName, final Level level) {
- final LoggerContext loggerContext = LoggerContext.getContext(false);
- if (Strings.isEmpty(loggerName)) {
- setRootLevel(level);
- } else {
- if (setLevel(loggerName, level, loggerContext.getConfiguration())) {
- loggerContext.updateLoggers();
- }
- }
- }
-
- private static boolean setLevel(final String loggerName, final Level level, final Configuration config) {
- boolean set;
- LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
- if (!loggerName.equals(loggerConfig.getName())) {
- // TODO Should additivity be inherited?
- loggerConfig = new LoggerConfig(loggerName, level, true);
- config.addLogger(loggerName, loggerConfig);
- loggerConfig.setLevel(level);
- set = true;
- } else {
- set = setLevel(loggerConfig, level);
- }
- return set;
- }
-
- /**
- * Sets the root logger's level.
- *
- * @param level
- * the new level
- */
- public static void setRootLevel(final Level level) {
- final LoggerContext loggerContext = LoggerContext.getContext(false);
- final LoggerConfig loggerConfig = loggerContext.getConfiguration().getRootLogger();
- if (!loggerConfig.getLevel().equals(level)) {
- loggerConfig.setLevel(level);
- loggerContext.updateLoggers();
- }
- }
-
- /**
- * Shuts down the given logging context.
- * @param ctx the logging context to shut down, may be null.
- */
- public static void shutdown(final LoggerContext ctx) {
- if (ctx != null) {
- ctx.stop();
- }
- }
-
- private Configurator() {
- // empty
- }
-}
+/*
+ * 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.config;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
+import org.apache.logging.log4j.core.util.NetUtils;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
+
+/**
+ * Initializes and configure the Logging system. This class provides several ways to construct a LoggerContext using
+ * the location of a configuration file, a context name, and various optional parameters.
+ */
+public final class Configurator {
+
+ private static final String FQCN = Configurator.class.getName();
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private static Log4jContextFactory getFactory() {
+ final LoggerContextFactory factory = LogManager.getFactory();
+ if (factory instanceof Log4jContextFactory) {
+ return (Log4jContextFactory) factory;
+ } else if (factory != null) {
+ LOGGER.error("LogManager returned an instance of {} which does not implement {}. Unable to initialize Log4j.",
+ factory.getClass().getName(), Log4jContextFactory.class.getName());
+ return null;
+ } else {
+ LOGGER.fatal("LogManager did not return a LoggerContextFactory. This indicates something has gone terribly wrong!");
+ return null;
+ }
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param source The InputSource for the configuration.
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(final ClassLoader loader,
+ final ConfigurationSource source) {
+ return initialize(loader, source, null);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param source The InputSource for the configuration.
+ * @param externalContext The external context to be attached to the LoggerContext.
+ * @return The LoggerContext.
+ */
+
+ public static LoggerContext initialize(final ClassLoader loader,
+ final ConfigurationSource source,
+ final Object externalContext)
+ {
+
+ try {
+ final Log4jContextFactory factory = getFactory();
+ return factory == null ? null :
+ factory.getContext(FQCN, loader, externalContext, false, source);
+ } catch (final Exception ex) {
+ LOGGER.error("There was a problem obtaining a LoggerContext using the configuration source [{}]", source, ex);
+ }
+ return null;
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param name The Context name.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param configLocation The configuration for the logging context.
+ * @return The LoggerContext or null if an error occurred (check the status logger).
+ */
+ public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation) {
+ return initialize(name, loader, configLocation, null);
+
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param name The Context name.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param configLocation The configuration for the logging context (or null, or blank).
+ * @param externalContext The external context to be attached to the LoggerContext
+ * @return The LoggerContext or null if an error occurred (check the status logger).
+ */
+ public static LoggerContext initialize(final String name, final ClassLoader loader, final String configLocation,
+ final Object externalContext) {
+ final URI uri = Strings.isBlank(configLocation) ? null : NetUtils.toURI(configLocation);
+ return initialize(name, loader, uri, externalContext);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param name The Context name.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param configLocation The configuration for the logging context.
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation) {
+ return initialize(name, loader, configLocation, null);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param name The Context name.
+ * @param loader The ClassLoader for the Context (or null).
+ * @param configLocation The configuration for the logging context (or null).
+ * @param externalContext The external context to be attached to the LoggerContext
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(final String name, final ClassLoader loader, final URI configLocation,
+ final Object externalContext) {
+
+ try {
+ final Log4jContextFactory factory = getFactory();
+ return factory == null ? null :
+ factory.getContext(FQCN, loader, externalContext, false, configLocation, name);
+ } catch (final Exception ex) {
+ LOGGER.error("There was a problem initializing the LoggerContext [{}] using configuration at [{}].",
+ name, configLocation, ex);
+ }
+ return null;
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param name The Context name.
+ * @param configLocation The configuration for the logging context.
+ * @return The LoggerContext or null if an error occurred (check the status logger).
+ */
+ public static LoggerContext initialize(final String name, final String configLocation) {
+ return initialize(name, null, configLocation);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param configuration The Configuration.
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(Configuration configuration) {
+ return initialize(null, configuration, null);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param loader The ClassLoader.
+ * @param configuration The Configuration.
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(final ClassLoader loader, Configuration configuration) {
+ return initialize(loader, configuration, null);
+ }
+
+ /**
+ * Initializes the Logging Context.
+ * @param loader The ClassLoader.
+ * @param configuration The Configuration.
+ * @param externalContext - The external context to be attached to the LoggerContext.
+ * @return The LoggerContext.
+ */
+ public static LoggerContext initialize(final ClassLoader loader, Configuration configuration, final Object externalContext) {
+ try {
+ final Log4jContextFactory factory = getFactory();
+ return factory == null ? null :
+ factory.getContext(FQCN, loader, externalContext, false, configuration);
+ } catch (final Exception ex) {
+ LOGGER.error("There was a problem initializing the LoggerContext using configuration {}",
+ configuration.getName(), ex);
+ }
+ return null;
+ }
+
+ /**
+ * Sets the levels of <code>parentLogger</code> and all 'child' loggers to the given <code>level</code>.
+ * @param parentLogger the parent logger
+ * @param level the new level
+ */
+ public static void setAllLevels(final String parentLogger, final Level level) {
+ // 1) get logger config
+ // 2) if exact match, use it, if not, create it.
+ // 3) set level on logger config
+ // 4) update child logger configs with level
+ // 5) update loggers
+ final LoggerContext loggerContext = LoggerContext.getContext(false);
+ final Configuration config = loggerContext.getConfiguration();
+ boolean set = setLevel(parentLogger, level, config);
+ for (final Map.Entry<String, LoggerConfig> entry : config.getLoggers().entrySet()) {
+ if (entry.getKey().startsWith(parentLogger)) {
+ set |= setLevel(entry.getValue(), level);
+ }
+ }
+ if (set) {
+ loggerContext.updateLoggers();
+ }
+ }
+
+ private static boolean setLevel(final LoggerConfig loggerConfig, final Level level) {
+ final boolean set = !loggerConfig.getLevel().equals(level);
+ if (set) {
+ loggerConfig.setLevel(level);
+ }
+ return set;
+ }
+
+ /**
+ * Sets logger levels.
+ *
+ * @param levelMap
+ * a levelMap where keys are level names and values are new
+ * Levels.
+ */
+ public static void setLevel(final Map<String, Level> levelMap) {
+ final LoggerContext loggerContext = LoggerContext.getContext(false);
+ final Configuration config = loggerContext.getConfiguration();
+ boolean set = false;
+ for (final Map.Entry<String, Level> entry : levelMap.entrySet()) {
+ final String loggerName = entry.getKey();
+ final Level level = entry.getValue();
+ set |= setLevel(loggerName, level, config);
+ }
+ if (set) {
+ loggerContext.updateLoggers();
+ }
+ }
+
+ /**
+ * Sets a logger's level.
+ *
+ * @param loggerName
+ * the logger name
+ * @param level
+ * the new level
+ */
+ public static void setLevel(final String loggerName, final Level level) {
+ final LoggerContext loggerContext = LoggerContext.getContext(false);
+ if (Strings.isEmpty(loggerName)) {
+ setRootLevel(level);
+ } else {
+ if (setLevel(loggerName, level, loggerContext.getConfiguration())) {
+ loggerContext.updateLoggers();
+ }
+ }
+ }
+
+ private static boolean setLevel(final String loggerName, final Level level, final Configuration config) {
+ boolean set;
+ LoggerConfig loggerConfig = config.getLoggerConfig(loggerName);
+ if (!loggerName.equals(loggerConfig.getName())) {
+ // TODO Should additivity be inherited?
+ loggerConfig = new LoggerConfig(loggerName, level, true);
+ config.addLogger(loggerName, loggerConfig);
+ loggerConfig.setLevel(level);
+ set = true;
+ } else {
+ set = setLevel(loggerConfig, level);
+ }
+ return set;
+ }
+
+ /**
+ * Sets the root logger's level.
+ *
+ * @param level
+ * the new level
+ */
+ public static void setRootLevel(final Level level) {
+ final LoggerContext loggerContext = LoggerContext.getContext(false);
+ final LoggerConfig loggerConfig = loggerContext.getConfiguration().getRootLogger();
+ if (!loggerConfig.getLevel().equals(level)) {
+ loggerConfig.setLevel(level);
+ loggerContext.updateLoggers();
+ }
+ }
+
+ /**
+ * Shuts down the given logging context.
+ * @param ctx the logging context to shut down, may be null.
+ */
+ public static void shutdown(final LoggerContext ctx) {
+ if (ctx != null) {
+ ctx.stop();
+ }
+ }
+
+ private Configurator() {
+ // empty
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
index ce96d3f..16f5b08 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/status/StatusConfiguration.java
@@ -29,6 +29,7 @@ import java.util.LinkedList;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.core.util.NetUtils;
import org.apache.logging.log4j.status.StatusConsoleListener;
import org.apache.logging.log4j.status.StatusListener;
import org.apache.logging.log4j.status.StatusLogger;
@@ -113,7 +114,7 @@ public class StatusConfiguration {
if (name.equalsIgnoreCase("err")) {
return System.err;
}
- final URI destUri = FileUtils.getCorrectedFilePathUri(name);
+ final URI destUri = NetUtils.toURI(name);
final File output = FileUtils.fileFromUri(destUri);
if (output == null) {
// don't want any NPEs, no sir
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
index 54ac566..cab865c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/FileUtils.java
@@ -117,16 +117,4 @@ public final class FileUtils {
throw new IOException("File " + dir + " exists and is not a directory. Unable to create directory.");
}
}
-
- /**
- * Takes a given URI string which may contain backslashes (illegal in URIs) in it due to user input or variable
- * substitution and returns a URI with the backslashes replaced with forward slashes.
- *
- * @param uri The URI string
- * @return the URI.
- * @throws URISyntaxException if instantiating the URI threw a {@code URISyntaxException}.
- */
- public static URI getCorrectedFilePathUri(final String uri) throws URISyntaxException {
- return new URI(WINDOWS_DIRECTORY_SEPARATOR.matcher(uri).replaceAll("/"));
- }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java
index 41b6df4..e9c55f4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/NetUtils.java
@@ -16,9 +16,14 @@
*/
package org.apache.logging.log4j.core.util;
+import java.io.File;
import java.net.InetAddress;
+import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.net.UnknownHostException;
import java.util.Enumeration;
@@ -73,4 +78,25 @@ public final class NetUtils {
}
}
+ /**
+ * Converts a URI string or file path to a URI object
+ * @param path the URI string or path
+ * @return the URI object
+ */
+ public static URI toURI(final String path) {
+ try {
+ // Resolves absolute URI
+ return new URI(path);
+ } catch (final URISyntaxException e) {
+ // A file path or a Apache Commons VFS URL might contain blanks.
+ // A file path may start with a driver letter
+ try {
+ final URL url = new URL(path);
+ return new URI(url.getProtocol(), url.getHost(), url.getPath(), null);
+ } catch (MalformedURLException | URISyntaxException nestedEx) {
+ return new File(path).toURI();
+ }
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfiguratorTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfiguratorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfiguratorTest.java
new file mode 100644
index 0000000..6ce49dc
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfiguratorTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.config;
+
+import java.io.File;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ConfiguratorTest {
+
+ @Test
+ public void testInitializeFromAbsoluteFilePath() {
+ final String path = new File("src/test/resources/log4j-list.xml").getAbsolutePath();
+ testInitializeFromFilePath(path);
+ }
+
+ @Test
+ public void testInitializeFromRelativeFilePath() {
+ final String path = new File("src/test/resources/log4j-list.xml").toString();
+ testInitializeFromFilePath(path);
+ }
+
+ private void testInitializeFromFilePath(String path) {
+ final LoggerContext loggerContext = Configurator.initialize(getClass().getName(), null, path);
+ try {
+ Assert.assertNotNull(loggerContext.getConfiguration().getAppender("List"));
+ } finally {
+ loggerContext.stop();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java
index fdf2265..4294423 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/FileUtilsTest.java
@@ -25,7 +25,6 @@ import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URI;
-import java.net.URISyntaxException;
import org.junit.Test;
@@ -87,21 +86,4 @@ public class FileUtilsTest {
assertFalse("file does not exist", file.exists());
}
- @Test
- public void testGetCorrectedFilePathUriWithoutBackslashes() throws URISyntaxException {
- final String config = "file:///path/to/something/on/unix";
- final URI uri = FileUtils.getCorrectedFilePathUri(config);
-
- assertNotNull("The URI should not be null.", uri);
- assertEquals("The URI is not correct.", "file:///path/to/something/on/unix", uri.toString());
- }
-
- @Test
- public void testGetCorrectedFilePathUriWithBackslashes() throws URISyntaxException {
- final String config = "file:///D:\\path\\to\\something/on/windows";
- final URI uri = FileUtils.getCorrectedFilePathUri(config);
-
- assertNotNull("The URI should not be null.", uri);
- assertEquals("The URI is not correct.", "file:///D:/path/to/something/on/windows", uri.toString());
- }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
new file mode 100644
index 0000000..8702d1f
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.junit.Test;
+
+public class NetUtilsTest {
+
+ @Test
+ public void testToUriWithoutBackslashes() throws URISyntaxException {
+ final String config = "file:///path/to/something/on/unix";
+ final URI uri = NetUtils.toURI(config);
+
+ assertNotNull("The URI should not be null.", uri);
+ assertEquals("The URI is not correct.", "file:///path/to/something/on/unix", uri.toString());
+ }
+
+ @Test
+ public void testToUriWithBackslashes() throws URISyntaxException {
+ final String config = "file:///D:\\path\\to\\something/on/windows";
+ final URI uri = NetUtils.toURI(config);
+
+ assertNotNull("The URI should not be null.", uri);
+ assertEquals("The URI is not correct.", "file:///D:/path/to/something/on/windows", uri.toString());
+ }
+
+ @Test
+ public void testToUriWindowsAbsolutePath() throws URISyntaxException {
+ final String config = "D:\\path\\to\\something\\on\\windows";
+ final URI uri = NetUtils.toURI(config);
+
+ assertNotNull("The URI should not be null.", uri);
+ assertEquals("The URI is not correct.", "file:/D:/path/to/something/on/windows", uri.toString());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-core/src/test/resources/log4j-list.xml
----------------------------------------------------------------------
diff --git a/log4j-core/src/test/resources/log4j-list.xml b/log4j-core/src/test/resources/log4j-list.xml
new file mode 100644
index 0000000..c2a92c3
--- /dev/null
+++ b/log4j-core/src/test/resources/log4j-list.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+<Configuration status="WARN">
+ <Appenders>
+ <List name="List">
+ <PatternLayout pattern="[%-5level] %c{1.} %msg%n" />
+ </List>
+ </Appenders>
+ <Loggers>
+ <Root level="debug">
+ <AppenderRef ref="List" />
+ </Root>
+ </Loggers>
+</Configuration>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
----------------------------------------------------------------------
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
index a7d70d2..0ed011b 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebInitializerImpl.java
@@ -1,266 +1,266 @@
-/*
- * 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.web;
-
-import java.net.URI;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.ServletContext;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.AbstractLifeCycle;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.impl.ContextAnchor;
-import org.apache.logging.log4j.core.impl.Log4jContextFactory;
-import org.apache.logging.log4j.core.lookup.Interpolator;
-import org.apache.logging.log4j.core.lookup.StrSubstitutor;
-import org.apache.logging.log4j.core.selector.ContextSelector;
-import org.apache.logging.log4j.core.selector.NamedContextSelector;
-import org.apache.logging.log4j.core.util.FileUtils;
-import org.apache.logging.log4j.core.util.Loader;
-import org.apache.logging.log4j.core.util.NetUtils;
-import org.apache.logging.log4j.core.util.SetUtils;
-import org.apache.logging.log4j.spi.LoggerContextFactory;
-
-/**
- * This class initializes and deinitializes Log4j no matter how the initialization occurs.
- */
-final class Log4jWebInitializerImpl extends AbstractLifeCycle implements Log4jWebLifeCycle {
-
- private static final String WEB_INF = "/WEB-INF/";
-
- private static final long serialVersionUID = 1L;
-
- static {
- if (Loader.isClassAvailable("org.apache.logging.log4j.core.web.JNDIContextFilter")) {
- throw new IllegalStateException("You are using Log4j 2 in a web application with the old, extinct "
- + "log4j-web artifact. This is not supported and could cause serious runtime problems. Please"
- + "remove the log4j-web JAR file from your application.");
- }
- }
-
- private final Map<String, String> map = new ConcurrentHashMap<>();
- private final StrSubstitutor substitutor = new StrSubstitutor(new Interpolator(map));
- private final ServletContext servletContext;
-
- private String name;
- private NamedContextSelector namedContextSelector;
- private LoggerContext loggerContext;
-
- private Log4jWebInitializerImpl(final ServletContext servletContext) {
- this.servletContext = servletContext;
- this.map.put("hostName", NetUtils.getLocalHostname());
- }
-
- /**
- * Initializes the Log4jWebLifeCycle attribute of a ServletContext. Those who wish to obtain this object should use
- * the {@link org.apache.logging.log4j.web.WebLoggerContextUtils#getWebLifeCycle(javax.servlet.ServletContext)}
- * method instead.
- *
- * @param servletContext
- * the ServletContext to initialize
- * @return a new Log4jWebLifeCycle
- * @since 2.0.1
- */
- protected static Log4jWebInitializerImpl initialize(final ServletContext servletContext) {
- final Log4jWebInitializerImpl initializer = new Log4jWebInitializerImpl(servletContext);
- servletContext.setAttribute(SUPPORT_ATTRIBUTE, initializer);
- return initializer;
- }
-
- @Override
- public synchronized void start() {
- if (this.isStopped() || this.isStopping()) {
- throw new IllegalStateException("Cannot start this Log4jWebInitializerImpl after it was stopped.");
- }
-
- // only do this once
- if (this.isInitialized()) {
- super.setStarting();
-
- this.name = this.substitutor.replace(this.servletContext.getInitParameter(LOG4J_CONTEXT_NAME));
- final String location = this.substitutor.replace(this.servletContext
- .getInitParameter(LOG4J_CONFIG_LOCATION));
- final boolean isJndi = "true".equalsIgnoreCase(this.servletContext
- .getInitParameter(IS_LOG4J_CONTEXT_SELECTOR_NAMED));
-
- if (isJndi) {
- this.initializeJndi(location);
- } else {
- this.initializeNonJndi(location);
- }
-
- this.servletContext.setAttribute(CONTEXT_ATTRIBUTE, this.loggerContext);
- super.setStarted();
- }
- }
-
- private void initializeJndi(final String location) {
- final URI configLocation = getConfigURI(location);
-
- if (this.name == null) {
- throw new IllegalStateException("A log4jContextName context parameter is required");
- }
-
- LoggerContext context;
- final LoggerContextFactory factory = LogManager.getFactory();
- if (factory instanceof Log4jContextFactory) {
- final ContextSelector selector = ((Log4jContextFactory) factory).getSelector();
- if (selector instanceof NamedContextSelector) {
- this.namedContextSelector = (NamedContextSelector) selector;
- context = this.namedContextSelector.locateContext(this.name, this.servletContext, configLocation);
- ContextAnchor.THREAD_CONTEXT.set(context);
- if (context.isInitialized()) {
- context.start();
- }
- ContextAnchor.THREAD_CONTEXT.remove();
- } else {
- LOGGER.warn("Potential problem: Selector is not an instance of NamedContextSelector.");
- return;
- }
- } else {
- LOGGER.warn("Potential problem: LoggerContextFactory is not an instance of Log4jContextFactory.");
- return;
- }
- this.loggerContext = context;
- LOGGER.debug("Created logger context for [{}] using [{}].", this.name, context.getClass().getClassLoader());
- }
-
- private void initializeNonJndi(final String location) {
- if (this.name == null) {
- this.name = this.servletContext.getServletContextName();
- LOGGER.debug("Using the servlet context name \"{}\".", this.name);
- }
-
- if (this.name == null && location == null) {
- LOGGER.error("No Log4j context configuration provided. This is very unusual.");
- return;
- }
-
- final URI uri = getConfigURI(location);
- this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uri, this.servletContext);
- }
-
- private URI getConfigURI(final String location) {
- try {
- String configLocation = location;
- if (configLocation == null) {
- final String[] paths = SetUtils.prefixSet(servletContext.getResourcePaths(WEB_INF), WEB_INF + "log4j2");
- LOGGER.debug("getConfigURI found resource paths {} in servletConext at [{}]", Arrays.toString(paths), WEB_INF);
- if (paths.length == 1) {
- configLocation = paths[0];
- } else if (paths.length > 1) {
- final String prefix = WEB_INF + "log4j2-" + this.name + ".";
- boolean found = false;
- for (final String str : paths) {
- if (str.startsWith(prefix)) {
- configLocation = str;
- found = true;
- break;
- }
- }
- if (!found) {
- configLocation = paths[0];
- }
- }
- }
- if (configLocation != null) {
- final URL url = servletContext.getResource(configLocation);
- if (url != null) {
- final URI uri = url.toURI();
- LOGGER.debug("getConfigURI found resource [{}] in servletConext at [{}]", uri, configLocation);
- return uri;
- }
- }
- } catch (final Exception ex) {
- // Just try passing the location.
- }
- if (location != null) {
- try {
- final URI correctedFilePathUri = FileUtils.getCorrectedFilePathUri(location);
- LOGGER.debug("getConfigURI found [{}] in servletConext at [{}]", correctedFilePathUri, location);
- return correctedFilePathUri;
- } catch (final Exception e) {
- LOGGER.error("Unable to convert configuration location [{}] to a URI", location, e);
- }
- }
- return null;
- }
-
- @Override
- public synchronized void stop() {
- if (!this.isStarted() && !this.isStopped()) {
- throw new IllegalStateException("Cannot stop this Log4jWebInitializer because it has not started.");
- }
-
- // only do this once
- if (this.isStarted()) {
- this.setStopping();
- if (this.loggerContext != null) {
- LOGGER.debug("Removing LoggerContext for [{}].", this.name);
- this.servletContext.removeAttribute(CONTEXT_ATTRIBUTE);
- if (this.namedContextSelector != null) {
- this.namedContextSelector.removeContext(this.name);
- }
- this.loggerContext.stop();
- this.loggerContext.setExternalContext(null);
- this.loggerContext = null;
- }
- this.setStopped();
- }
- }
-
- @Override
- public void setLoggerContext() {
- if (this.loggerContext != null) {
- ContextAnchor.THREAD_CONTEXT.set(this.loggerContext);
- }
- }
-
- @Override
- public void clearLoggerContext() {
- ContextAnchor.THREAD_CONTEXT.remove();
- }
-
- @Override
- public void wrapExecution(final Runnable runnable) {
- this.setLoggerContext();
-
- try {
- runnable.run();
- } finally {
- this.clearLoggerContext();
- }
- }
-
- private ClassLoader getClassLoader() {
- try {
- // if container is Servlet 3.0, use its getClassLoader method
- // this may look odd, but the call below will throw NoSuchMethodError if user is on Servlet 2.5
- // we compile against 3.0 to support Log4jServletContainerInitializer, but we don't require 3.0
- return this.servletContext.getClassLoader();
- } catch (final Throwable ignore) {
- // otherwise, use this class's class loader
- return Log4jWebInitializerImpl.class.getClassLoader();
- }
- }
-
-}
+/*
+ * 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.web;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.servlet.ServletContext;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.AbstractLifeCycle;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.impl.ContextAnchor;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
+import org.apache.logging.log4j.core.lookup.Interpolator;
+import org.apache.logging.log4j.core.lookup.StrSubstitutor;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.core.selector.NamedContextSelector;
+import org.apache.logging.log4j.core.util.FileUtils;
+import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.core.util.NetUtils;
+import org.apache.logging.log4j.core.util.SetUtils;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+
+/**
+ * This class initializes and deinitializes Log4j no matter how the initialization occurs.
+ */
+final class Log4jWebInitializerImpl extends AbstractLifeCycle implements Log4jWebLifeCycle {
+
+ private static final String WEB_INF = "/WEB-INF/";
+
+ private static final long serialVersionUID = 1L;
+
+ static {
+ if (Loader.isClassAvailable("org.apache.logging.log4j.core.web.JNDIContextFilter")) {
+ throw new IllegalStateException("You are using Log4j 2 in a web application with the old, extinct "
+ + "log4j-web artifact. This is not supported and could cause serious runtime problems. Please"
+ + "remove the log4j-web JAR file from your application.");
+ }
+ }
+
+ private final Map<String, String> map = new ConcurrentHashMap<>();
+ private final StrSubstitutor substitutor = new StrSubstitutor(new Interpolator(map));
+ private final ServletContext servletContext;
+
+ private String name;
+ private NamedContextSelector namedContextSelector;
+ private LoggerContext loggerContext;
+
+ private Log4jWebInitializerImpl(final ServletContext servletContext) {
+ this.servletContext = servletContext;
+ this.map.put("hostName", NetUtils.getLocalHostname());
+ }
+
+ /**
+ * Initializes the Log4jWebLifeCycle attribute of a ServletContext. Those who wish to obtain this object should use
+ * the {@link org.apache.logging.log4j.web.WebLoggerContextUtils#getWebLifeCycle(javax.servlet.ServletContext)}
+ * method instead.
+ *
+ * @param servletContext
+ * the ServletContext to initialize
+ * @return a new Log4jWebLifeCycle
+ * @since 2.0.1
+ */
+ protected static Log4jWebInitializerImpl initialize(final ServletContext servletContext) {
+ final Log4jWebInitializerImpl initializer = new Log4jWebInitializerImpl(servletContext);
+ servletContext.setAttribute(SUPPORT_ATTRIBUTE, initializer);
+ return initializer;
+ }
+
+ @Override
+ public synchronized void start() {
+ if (this.isStopped() || this.isStopping()) {
+ throw new IllegalStateException("Cannot start this Log4jWebInitializerImpl after it was stopped.");
+ }
+
+ // only do this once
+ if (this.isInitialized()) {
+ super.setStarting();
+
+ this.name = this.substitutor.replace(this.servletContext.getInitParameter(LOG4J_CONTEXT_NAME));
+ final String location = this.substitutor.replace(this.servletContext
+ .getInitParameter(LOG4J_CONFIG_LOCATION));
+ final boolean isJndi = "true".equalsIgnoreCase(this.servletContext
+ .getInitParameter(IS_LOG4J_CONTEXT_SELECTOR_NAMED));
+
+ if (isJndi) {
+ this.initializeJndi(location);
+ } else {
+ this.initializeNonJndi(location);
+ }
+
+ this.servletContext.setAttribute(CONTEXT_ATTRIBUTE, this.loggerContext);
+ super.setStarted();
+ }
+ }
+
+ private void initializeJndi(final String location) {
+ final URI configLocation = getConfigURI(location);
+
+ if (this.name == null) {
+ throw new IllegalStateException("A log4jContextName context parameter is required");
+ }
+
+ LoggerContext context;
+ final LoggerContextFactory factory = LogManager.getFactory();
+ if (factory instanceof Log4jContextFactory) {
+ final ContextSelector selector = ((Log4jContextFactory) factory).getSelector();
+ if (selector instanceof NamedContextSelector) {
+ this.namedContextSelector = (NamedContextSelector) selector;
+ context = this.namedContextSelector.locateContext(this.name, this.servletContext, configLocation);
+ ContextAnchor.THREAD_CONTEXT.set(context);
+ if (context.isInitialized()) {
+ context.start();
+ }
+ ContextAnchor.THREAD_CONTEXT.remove();
+ } else {
+ LOGGER.warn("Potential problem: Selector is not an instance of NamedContextSelector.");
+ return;
+ }
+ } else {
+ LOGGER.warn("Potential problem: LoggerContextFactory is not an instance of Log4jContextFactory.");
+ return;
+ }
+ this.loggerContext = context;
+ LOGGER.debug("Created logger context for [{}] using [{}].", this.name, context.getClass().getClassLoader());
+ }
+
+ private void initializeNonJndi(final String location) {
+ if (this.name == null) {
+ this.name = this.servletContext.getServletContextName();
+ LOGGER.debug("Using the servlet context name \"{}\".", this.name);
+ }
+
+ if (this.name == null && location == null) {
+ LOGGER.error("No Log4j context configuration provided. This is very unusual.");
+ return;
+ }
+
+ final URI uri = getConfigURI(location);
+ this.loggerContext = Configurator.initialize(this.name, this.getClassLoader(), uri, this.servletContext);
+ }
+
+ private URI getConfigURI(final String location) {
+ try {
+ String configLocation = location;
+ if (configLocation == null) {
+ final String[] paths = SetUtils.prefixSet(servletContext.getResourcePaths(WEB_INF), WEB_INF + "log4j2");
+ LOGGER.debug("getConfigURI found resource paths {} in servletConext at [{}]", Arrays.toString(paths), WEB_INF);
+ if (paths.length == 1) {
+ configLocation = paths[0];
+ } else if (paths.length > 1) {
+ final String prefix = WEB_INF + "log4j2-" + this.name + ".";
+ boolean found = false;
+ for (final String str : paths) {
+ if (str.startsWith(prefix)) {
+ configLocation = str;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ configLocation = paths[0];
+ }
+ }
+ }
+ if (configLocation != null) {
+ final URL url = servletContext.getResource(configLocation);
+ if (url != null) {
+ final URI uri = url.toURI();
+ LOGGER.debug("getConfigURI found resource [{}] in servletConext at [{}]", uri, configLocation);
+ return uri;
+ }
+ }
+ } catch (final Exception ex) {
+ // Just try passing the location.
+ }
+ if (location != null) {
+ try {
+ final URI correctedFilePathUri = NetUtils.toURI(location);
+ LOGGER.debug("getConfigURI found [{}] in servletConext at [{}]", correctedFilePathUri, location);
+ return correctedFilePathUri;
+ } catch (final Exception e) {
+ LOGGER.error("Unable to convert configuration location [{}] to a URI", location, e);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (!this.isStarted() && !this.isStopped()) {
+ throw new IllegalStateException("Cannot stop this Log4jWebInitializer because it has not started.");
+ }
+
+ // only do this once
+ if (this.isStarted()) {
+ this.setStopping();
+ if (this.loggerContext != null) {
+ LOGGER.debug("Removing LoggerContext for [{}].", this.name);
+ this.servletContext.removeAttribute(CONTEXT_ATTRIBUTE);
+ if (this.namedContextSelector != null) {
+ this.namedContextSelector.removeContext(this.name);
+ }
+ this.loggerContext.stop();
+ this.loggerContext.setExternalContext(null);
+ this.loggerContext = null;
+ }
+ this.setStopped();
+ }
+ }
+
+ @Override
+ public void setLoggerContext() {
+ if (this.loggerContext != null) {
+ ContextAnchor.THREAD_CONTEXT.set(this.loggerContext);
+ }
+ }
+
+ @Override
+ public void clearLoggerContext() {
+ ContextAnchor.THREAD_CONTEXT.remove();
+ }
+
+ @Override
+ public void wrapExecution(final Runnable runnable) {
+ this.setLoggerContext();
+
+ try {
+ runnable.run();
+ } finally {
+ this.clearLoggerContext();
+ }
+ }
+
+ private ClassLoader getClassLoader() {
+ try {
+ // if container is Servlet 3.0, use its getClassLoader method
+ // this may look odd, but the call below will throw NoSuchMethodError if user is on Servlet 2.5
+ // we compile against 3.0 to support Log4jServletContainerInitializer, but we don't require 3.0
+ return this.servletContext.getClassLoader();
+ } catch (final Throwable ignore) {
+ // otherwise, use this class's class loader
+ return Log4jWebInitializerImpl.class.getClassLoader();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1542ec12/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 85cc20f..3779165 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -66,6 +66,9 @@
<action issue="LOG4J2-1114" dev="ggregory" type="update">
Add thread name to status logger layout.
</action>
+ <action issue="LOG4J2-1123" dev="ggregory" type="fix" due-to="Gary Gregory">
+ Core Configurator.initialize(String, ClassLoader, String) fails to work when config location is a file path.
+ </action>
<action issue="LOG4J2-1117" dev="ggregory" type="fix" due-to="Marcus Thiesen">
OutputStreamManager in ConsoleAppender leaking managers.
</action>