Index: log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java
===================================================================
--- log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java	(révision 1619479)
+++ log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationFactory.java	(copie de travail)
@@ -61,7 +61,7 @@
  * factory to be the first one inspected. See
  * {@linkplain org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory} for an example.</li>
  * </ol>
- *
+ * <p/>
  * If the ConfigurationFactory that was added returns null on a call to
  * getConfiguration the any other ConfigurationFactories found as plugins will
  * be called in their respective order. DefaultConfiguration is always called
@@ -113,6 +113,7 @@
 
     /**
      * Returns the ConfigurationFactory.
+     *
      * @return the ConfigurationFactory.
      */
     public static ConfigurationFactory getInstance() {
@@ -134,7 +135,7 @@
                     for (final PluginType<?> type : plugins.values()) {
                         try {
                             @SuppressWarnings("unchecked")
-                            final Class<ConfigurationFactory> clazz = (Class<ConfigurationFactory>)type.getPluginClass();
+                            final Class<ConfigurationFactory> clazz = (Class<ConfigurationFactory>) type.getPluginClass();
                             final Order order = clazz.getAnnotation(Order.class);
                             if (order != null) {
                                 final int weight = order.value();
@@ -180,6 +181,7 @@
 
     /**
      * Set the configuration factory. This method is not intended for general use and may not be thread safe.
+     *
      * @param factory the ConfigurationFactory.
      */
     public static void setConfigurationFactory(final ConfigurationFactory factory) {
@@ -196,6 +198,7 @@
 
     /**
      * Remove the ConfigurationFactory. This method is not intended for general use and may not be thread safe.
+     *
      * @param factory The factory to remove.
      */
     public static void removeConfigurationFactory(final ConfigurationFactory factory) {
@@ -214,7 +217,8 @@
 
     /**
      * Returns the Configuration.
-     * @param name The configuration name.
+     *
+     * @param name           The configuration name.
      * @param configLocation The configuration location.
      * @return The Configuration.
      */
@@ -233,6 +237,7 @@
 
     /**
      * Load the configuration from a URI.
+     *
      * @param configLocation A URI representing the location of the configuration.
      * @return The ConfigurationSource for the configuration.
      */
@@ -277,6 +282,7 @@
 
     /**
      * Load the configuration from the location represented by the String.
+     *
      * @param config The configuration location.
      * @param loader The default ClassLoader to use.
      * @return The InputSource to use to read the configuration.
@@ -302,8 +308,9 @@
 
     /**
      * Retrieve the configuration via the ClassLoader.
+     *
      * @param resource The resource to load.
-     * @param loader The default ClassLoader to use.
+     * @param loader   The default ClassLoader to use.
      * @return The ConfigurationSource for the configuration.
      */
     protected ConfigurationSource getInputFromResource(final String resource, final ClassLoader loader) {
@@ -334,6 +341,17 @@
     }
 
     /**
+     * this method is more or less internal and allows to reuse config lookup logic
+     *
+     * @param name           classloader name most of the time or config name more generically
+     * @param configLocation config location uri (most of the time null)
+     * @return the config factory/config source pair for these parameters
+     */
+    public ConfigEntry getConfigurationLocation(final String name, final URI configLocation) {
+        return configFactory.getConfigurationLocation(name, configLocation);
+    }
+
+    /**
      * Factory that chooses a ConfigurationFactory based on weighting.
      */
     private static class WeightedFactory implements Comparable<WeightedFactory> {
@@ -342,8 +360,9 @@
 
         /**
          * Constructor.
+         *
          * @param weight The weight.
-         * @param clazz The class.
+         * @param clazz  The class.
          */
         public WeightedFactory(final int weight, final Class<ConfigurationFactory> clazz) {
             this.weight = weight;
@@ -370,16 +389,27 @@
 
         /**
          * Default Factory Constructor.
-         * @param name The configuration name.
+         *
+         * @param name           The configuration name.
          * @param configLocation The configuration location.
          * @return The Configuration.
          */
         @Override
         public Configuration getConfiguration(final String name, final URI configLocation) {
+            final ConfigEntry config = getConfigurationLocation(name, configLocation);
+            if (config != null) {
+                return config.build();
+            }
 
+            LOGGER.error("No log4j2 configuration file found. Using default configuration: logging only errors to the console.");
+            return new DefaultConfiguration();
+        }
+
+        @Override
+        public ConfigEntry getConfigurationLocation(final String name, final URI configLocation) {
             if (configLocation == null) {
                 final String config = this.substitutor.replace(
-                    PropertiesUtil.getProperties().getStringProperty(CONFIGURATION_FILE_PROPERTY));
+                        PropertiesUtil.getProperties().getStringProperty(CONFIGURATION_FILE_PROPERTY));
                 if (config != null) {
                     ConfigurationSource source = null;
                     try {
@@ -398,10 +428,7 @@
                             if (types != null) {
                                 for (final String type : types) {
                                     if (type.equals("*") || config.endsWith(type)) {
-                                        final Configuration c = factory.getConfiguration(source);
-                                        if (c != null) {
-                                            return c;
-                                        }
+                                        return new ConfigEntry(factory, source);
                                     }
                                 }
                             }
@@ -414,9 +441,11 @@
                     if (types != null) {
                         for (final String type : types) {
                             if (type.equals("*") || configLocation.toString().endsWith(type)) {
-                                final Configuration config = factory.getConfiguration(name, configLocation);
-                                if (config != null) {
-                                    return config;
+                                if (isActive()) {
+                                    final ConfigurationSource source = getInputFromUri(configLocation);
+                                    if (source != null) {
+                                        return new ConfigEntry(factory, source);
+                                    }
                                 }
                             }
                         }
@@ -424,13 +453,13 @@
                 }
             }
 
-            Configuration config = getConfiguration(true, name);
+            ConfigEntry config = getConfigurationLocation(true, name);
             if (config == null) {
-                config = getConfiguration(true, null);
+                config = getConfigurationLocation(true, null);
                 if (config == null) {
-                    config = getConfiguration(false, name);
+                    config = getConfigurationLocation(false, name);
                     if (config == null) {
-                        config = getConfiguration(false, null);
+                        config = getConfigurationLocation(false, null);
                     }
                 }
             }
@@ -437,17 +466,16 @@
             if (config != null) {
                 return config;
             }
-            LOGGER.error("No log4j2 configuration file found. Using default configuration: logging only errors to the console.");
-            return new DefaultConfiguration();
+            return null;
         }
 
-        private Configuration getConfiguration(final boolean isTest, final String name) {
+        private ConfigEntry getConfigurationLocation(final boolean isTest, final String name) {
             final boolean named = name != null && name.length() > 0;
             final ClassLoader loader = this.getClass().getClassLoader();
             for (final ConfigurationFactory factory : factories) {
                 String configName;
                 final String prefix = isTest ? TEST_PREFIX : DEFAULT_PREFIX;
-                final String [] types = factory.getSupportedTypes();
+                final String[] types = factory.getSupportedTypes();
                 if (types == null) {
                     continue;
                 }
@@ -460,7 +488,7 @@
 
                     final ConfigurationSource source = getInputFromResource(configName, loader);
                     if (source != null) {
-                        return factory.getConfiguration(source);
+                        return new ConfigEntry(factory, source);
                     }
                 }
             }
@@ -497,4 +525,26 @@
             return null;
         }
     }
+
+    public static class ConfigEntry {
+        private final ConfigurationFactory factory;
+        private final ConfigurationSource source;
+
+        public ConfigEntry(final ConfigurationFactory factory, final ConfigurationSource source) {
+            this.factory = factory;
+            this.source = source;
+        }
+
+        public ConfigurationFactory getFactory() {
+            return factory;
+        }
+
+        public ConfigurationSource getSource() {
+            return source;
+        }
+
+        public Configuration build() {
+            return factory.getConfiguration(source);
+        }
+    }
 }
Index: log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
===================================================================
--- log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java	(révision 1619479)
+++ log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java	(copie de travail)
@@ -23,7 +23,10 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
 
 import org.apache.logging.log4j.core.util.Assert;
 
@@ -34,7 +37,7 @@
     public static final ConfigurationSource NULL_SOURCE = new ConfigurationSource(new byte[0]);
 
     private final File file;
-    private final URL url;
+    private final URL url; // has to be not null
     private final String location;
     private final InputStream stream;
     private final byte[] data;
@@ -74,7 +77,29 @@
         this.data = Assert.requireNonNull(data, "data is null");
         this.stream = new ByteArrayInputStream(data);
         this.file = null;
-        this.url = null;
+
+        URL tmp = null;
+        try {
+            tmp = new URL("log4j2", null, 0, "bytes", new URLStreamHandler() {
+                @Override
+                protected URLConnection openConnection(final URL u) throws IOException {
+                    return new URLConnection(u) {
+                        @Override
+                        public void connect() throws IOException {
+                            // no-op
+                        }
+
+                        @Override
+                        public InputStream getInputStream() throws IOException {
+                            return new ByteArrayInputStream(data);
+                        }
+                    };
+                }
+            });
+        } catch (final MalformedURLException e) {
+            // no-op
+        }
+        this.url = tmp;
         this.location = null;
     }
 
@@ -89,7 +114,15 @@
         this.stream = Assert.requireNonNull(stream, "stream is null");
         this.file = Assert.requireNonNull(file, "file is null");
         this.location = file.getAbsolutePath();
-        this.url = null;
+
+        URL tmp = null;
+        try {
+            tmp = file.toURI().toURL();
+        } catch (final MalformedURLException e) {
+            // no-op
+        }
+        this.url = tmp;
+
         this.data = null;
     }
 
Index: log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java
===================================================================
--- log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java	(révision 1619479)
+++ log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java	(copie de travail)
@@ -18,6 +18,7 @@
 
 import java.lang.ref.WeakReference;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -28,6 +29,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.impl.ContextAnchor;
 import org.apache.logging.log4j.core.impl.ReflectiveCallerClassUtility;
 import org.apache.logging.log4j.core.util.Loader;
@@ -182,40 +184,51 @@
         final ClassLoader loader = loaderOrNull != null ? loaderOrNull : ClassLoader.getSystemClassLoader();
         final String name = loader.toString();
         AtomicReference<WeakReference<LoggerContext>> ref = CONTEXT_MAP.get(name);
+
+        URI specificConfig = configLocation;
         if (ref == null) {
             if (configLocation == null) {
-                ClassLoader parent = loader.getParent();
-                while (parent != null) {
+                final ConfigurationFactory.ConfigEntry entry = ConfigurationFactory.getInstance().getConfigurationLocation(name, null);
+                if (entry != null) {
+                    try {
+                        specificConfig = entry.getSource().getURL().toURI();
+                    } catch (final URISyntaxException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+                } else {
+                    ClassLoader parent = loader.getParent();
+                    while (parent != null) {
 
-                    ref = CONTEXT_MAP.get(parent.toString());
-                    if (ref != null) {
-                        final WeakReference<LoggerContext> r = ref.get();
-                        final LoggerContext ctx = r.get();
-                        if (ctx != null) {
-                            return ctx;
+                        ref = CONTEXT_MAP.get(parent.toString());
+                        if (ref != null) {
+                            final WeakReference<LoggerContext> r = ref.get();
+                            final LoggerContext ctx = r.get();
+                            if (ctx != null) {
+                                return ctx;
+                            }
                         }
-                    }
-                    parent = parent.getParent();
-                    /*  In Tomcat 6 the parent of the JSP classloader is the webapp classloader which would be
-                    configured by the WebAppContextListener. The WebAppClassLoader is also the ThreadContextClassLoader.
-                    In JBoss 5 the parent of the JSP ClassLoader is the WebAppClassLoader which is also the
-                    ThreadContextClassLoader. However, the parent of the WebAppClassLoader is the ClassLoader
-                    that is configured by the WebAppContextListener.
+                        parent = parent.getParent();
+                        /*  In Tomcat 6 the parent of the JSP classloader is the webapp classloader which would be
+                        configured by the WebAppContextListener. The WebAppClassLoader is also the ThreadContextClassLoader.
+                        In JBoss 5 the parent of the JSP ClassLoader is the WebAppClassLoader which is also the
+                        ThreadContextClassLoader. However, the parent of the WebAppClassLoader is the ClassLoader
+                        that is configured by the WebAppContextListener.
 
-                    ClassLoader threadLoader = null;
-                    try {
-                        threadLoader = Thread.currentThread().getContextClassLoader();
-                    } catch (Exception ex) {
-                        // Ignore SecurityException
+                        ClassLoader threadLoader = null;
+                        try {
+                            threadLoader = Thread.currentThread().getContextClassLoader();
+                        } catch (Exception ex) {
+                            // Ignore SecurityException
+                        }
+                        if (threadLoader != null && threadLoader == parent) {
+                            break;
+                        } else {
+                            parent = parent.getParent();
+                        } */
                     }
-                    if (threadLoader != null && threadLoader == parent) {
-                        break;
-                    } else {
-                        parent = parent.getParent();
-                    } */
                 }
             }
-            LoggerContext ctx = new LoggerContext(name, null, configLocation);
+            LoggerContext ctx = new LoggerContext(name, null, specificConfig);
             final AtomicReference<WeakReference<LoggerContext>> r =
                 new AtomicReference<WeakReference<LoggerContext>>();
             r.set(new WeakReference<LoggerContext>(ctx));
@@ -226,12 +239,12 @@
         final WeakReference<LoggerContext> r = ref.get();
         LoggerContext ctx = r.get();
         if (ctx != null) {
-            if (ctx.getConfigLocation() == null && configLocation != null) {
-                LOGGER.debug("Setting configuration to {}", configLocation);
-                ctx.setConfigLocation(configLocation);
-            } else if (ctx.getConfigLocation() != null && configLocation != null &&
-                !ctx.getConfigLocation().equals(configLocation)) {
-                LOGGER.warn("locateContext called with URI {}. Existing LoggerContext has URI {}", configLocation,
+            if (ctx.getConfigLocation() == null && specificConfig != null) {
+                LOGGER.debug("Setting configuration to {}", specificConfig);
+                ctx.setConfigLocation(specificConfig);
+            } else if (ctx.getConfigLocation() != null && specificConfig != null &&
+                !ctx.getConfigLocation().equals(specificConfig)) {
+                LOGGER.warn("locateContext called with URI {}. Existing LoggerContext has URI {}", specificConfig,
                     ctx.getConfigLocation());
             }
             return ctx;
Index: log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
===================================================================
--- log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java	(révision 1619479)
+++ log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java	(copie de travail)
@@ -21,6 +21,9 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.ReflectPermission;
 import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.status.StatusLogger;
@@ -114,9 +117,20 @@
             ClassLoader classLoader = getTcl();
             if (classLoader != null) {
                 LOGGER.trace("Trying to find [{}] using context class loader {}.", resource, classLoader);
-                final URL url = classLoader.getResource(resource);
-                if (url != null) {
-                    return url;
+                final Collection<URL> url = new HashSet<URL>(Collections.list(classLoader.getResources(resource)));
+                if (!url.isEmpty()) {
+                    if (url.size() > 1) { // remove parent ones to keep only the most specific one
+                        final ClassLoader parent = classLoader.getParent();
+                        if (parent != null) {
+                            final Collection<URL> child = new HashSet<URL>(url);
+                            child.removeAll(Collections.list(parent.getResources(resource)));
+                            if (!child.isEmpty()) {
+                                return child.iterator().next();
+                            }
+                        }
+                    }
+                    // only child config, we are safe to use one of them
+                    return url.iterator().next();
                 }
             }
 
Index: log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractJpaAppenderTest.java
===================================================================
--- log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractJpaAppenderTest.java	(révision 1619479)
+++ log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/AbstractJpaAppenderTest.java	(copie de travail)
@@ -68,6 +68,7 @@
             ((JpaAppender) appender).getManager().release();
         } finally {
             System.clearProperty(ConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+            context.setConfigLocation(null);
             context.reconfigure();
             StatusLogger.getLogger().reset();
 
