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 2016/03/08 05:27:12 UTC

logging-log4j2 git commit: [LOG4J2-1309] Configuration file error does not show cause exception.

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 7769eadaa -> 2be4de9b5


[LOG4J2-1309] Configuration file error does not show cause exception.

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/2be4de9b
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/2be4de9b
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/2be4de9b

Branch: refs/heads/master
Commit: 2be4de9b510f8a62a114a9aa31109f20e4a80795
Parents: 7769ead
Author: ggregory <gg...@apache.org>
Authored: Mon Mar 7 20:27:02 2016 -0800
Committer: ggregory <gg...@apache.org>
Committed: Mon Mar 7 20:27:02 2016 -0800

----------------------------------------------------------------------
 .../core/config/json/JsonConfiguration.java     | 550 +++++++++----------
 .../log4j/core/config/xml/XmlConfiguration.java |   2 +-
 src/changes/changes.xml                         |   3 +
 3 files changed, 279 insertions(+), 276 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2be4de9b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
index fcde1d5..0efef68 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java
@@ -1,275 +1,275 @@
-/*
- * 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.json;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.logging.log4j.core.config.AbstractConfiguration;
-import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.ConfigurationSource;
-import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
-import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.core.config.Node;
-import org.apache.logging.log4j.core.config.Reconfigurable;
-import org.apache.logging.log4j.core.config.plugins.util.PluginType;
-import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
-import org.apache.logging.log4j.core.config.status.StatusConfiguration;
-import org.apache.logging.log4j.core.util.FileWatcher;
-import org.apache.logging.log4j.core.util.Patterns;
-
-/**
- * Creates a Node hierarchy from a JSON file.
- */
-public class JsonConfiguration extends AbstractConfiguration implements Reconfigurable {
-
-    private static final String[] VERBOSE_CLASSES = new String[] { ResolverUtil.class.getName() };
-    private final List<Status> status = new ArrayList<>();
-    private JsonNode root;
-
-    public JsonConfiguration(final ConfigurationSource configSource) {
-        super(configSource);
-        final File configFile = configSource.getFile();
-        byte[] buffer;
-        try {
-            try (final InputStream configStream = configSource.getInputStream()) {
-                buffer = toByteArray(configStream);
-            }
-            final InputStream is = new ByteArrayInputStream(buffer);
-            root = getObjectMapper().readTree(is);
-            if (root.size() == 1) {
-                for (final JsonNode node : root) {
-                    root = node;
-                }
-            }
-            processAttributes(rootNode, root);
-            final StatusConfiguration statusConfig = new StatusConfiguration().withVerboseClasses(VERBOSE_CLASSES)
-                    .withStatus(getDefaultStatus());
-            for (final Map.Entry<String, String> entry : rootNode.getAttributes().entrySet()) {
-                final String key = entry.getKey();
-                final String value = getStrSubstitutor().replace(entry.getValue());
-                // TODO: this duplicates a lot of the XmlConfiguration constructor
-                if ("status".equalsIgnoreCase(key)) {
-                    statusConfig.withStatus(value);
-                } else if ("dest".equalsIgnoreCase(key)) {
-                    statusConfig.withDestination(value);
-                } else if ("shutdownHook".equalsIgnoreCase(key)) {
-                    isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
-                } else if ("verbose".equalsIgnoreCase(entry.getKey())) {
-                    statusConfig.withVerbosity(value);
-                } else if ("packages".equalsIgnoreCase(key)) {
-                    pluginPackages.addAll(Arrays.asList(value.split(Patterns.COMMA_SEPARATOR)));
-                } else if ("name".equalsIgnoreCase(key)) {
-                    setName(value);
-                } else if ("monitorInterval".equalsIgnoreCase(key)) {
-                    final int intervalSeconds = Integer.parseInt(value);
-                    if (intervalSeconds > 0) {
-                        getWatchManager().setIntervalSeconds(intervalSeconds);
-                        if (configFile != null) {
-                            FileWatcher watcher = new ConfiguratonFileWatcher(this, listeners);
-                            getWatchManager().watchFile(configFile, watcher);
-                        }
-                    }
-                } else if ("advertiser".equalsIgnoreCase(key)) {
-                    createAdvertiser(value, configSource, buffer, "application/json");
-                }
-            }
-            statusConfig.initialize();
-            if (getName() == null) {
-                setName(configSource.getLocation());
-            }
-        } catch (final Exception ex) {
-            LOGGER.error("Error parsing {}", configSource.getLocation(), ex);
-        }
-    }
-
-    protected ObjectMapper getObjectMapper() {
-        return new ObjectMapper().configure(JsonParser.Feature.ALLOW_COMMENTS, true);
-    }
-
-    @Override
-    public void setup() {
-        final Iterator<Map.Entry<String, JsonNode>> iter = root.fields();
-        final List<Node> children = rootNode.getChildren();
-        while (iter.hasNext()) {
-            final Map.Entry<String, JsonNode> entry = iter.next();
-            final JsonNode n = entry.getValue();
-            if (n.isObject()) {
-                LOGGER.debug("Processing node for object {}", entry.getKey());
-                children.add(constructNode(entry.getKey(), rootNode, n));
-            } else if (n.isArray()) {
-                LOGGER.error("Arrays are not supported at the root configuration.");
-            }
-        }
-        LOGGER.debug("Completed parsing configuration");
-        if (status.size() > 0) {
-            for (final Status s : status) {
-                LOGGER.error("Error processing element " + s.name + ": " + s.errorType);
-            }
-        }
-    }
-
-    @Override
-    public Configuration reconfigure() {
-        try {
-            final ConfigurationSource source = getConfigurationSource().resetInputStream();
-            if (source == null) {
-                return null;
-            }
-            return new JsonConfiguration(source);
-        } catch (final IOException ex) {
-            LOGGER.error("Cannot locate file {}", getConfigurationSource(), ex);
-        }
-        return null;
-    }
-
-    private Node constructNode(final String name, final Node parent, final JsonNode jsonNode) {
-        final PluginType<?> type = pluginManager.getPluginType(name);
-        final Node node = new Node(parent, name, type);
-        processAttributes(node, jsonNode);
-        final Iterator<Map.Entry<String, JsonNode>> iter = jsonNode.fields();
-        final List<Node> children = node.getChildren();
-        while (iter.hasNext()) {
-            final Map.Entry<String, JsonNode> entry = iter.next();
-            final JsonNode n = entry.getValue();
-            if (n.isArray() || n.isObject()) {
-                if (type == null) {
-                    status.add(new Status(name, n, ErrorType.CLASS_NOT_FOUND));
-                }
-                if (n.isArray()) {
-                    LOGGER.debug("Processing node for array {}", entry.getKey());
-                    for (int i = 0; i < n.size(); ++i) {
-                        final String pluginType = getType(n.get(i), entry.getKey());
-                        final PluginType<?> entryType = pluginManager.getPluginType(pluginType);
-                        final Node item = new Node(node, entry.getKey(), entryType);
-                        processAttributes(item, n.get(i));
-                        if (pluginType.equals(entry.getKey())) {
-                            LOGGER.debug("Processing {}[{}]", entry.getKey(), i);
-                        } else {
-                            LOGGER.debug("Processing {} {}[{}]", pluginType, entry.getKey(), i);
-                        }
-                        final Iterator<Map.Entry<String, JsonNode>> itemIter = n.get(i).fields();
-                        final List<Node> itemChildren = item.getChildren();
-                        while (itemIter.hasNext()) {
-                            final Map.Entry<String, JsonNode> itemEntry = itemIter.next();
-                            if (itemEntry.getValue().isObject()) {
-                                LOGGER.debug("Processing node for object {}", itemEntry.getKey());
-                                itemChildren.add(constructNode(itemEntry.getKey(), item, itemEntry.getValue()));
-                            } else if (itemEntry.getValue().isArray()) {
-                                final JsonNode array = itemEntry.getValue();
-                                final String entryName = itemEntry.getKey();
-                                LOGGER.debug("Processing array for object {}", entryName);
-                                for (int j = 0; j < array.size(); ++j) {
-                                    itemChildren.add(constructNode(entryName, item, array.get(j)));
-                                }
-                            }
-
-                        }
-                        children.add(item);
-                    }
-                } else {
-                    LOGGER.debug("Processing node for object {}", entry.getKey());
-                    children.add(constructNode(entry.getKey(), node, n));
-                }
-            } else {
-                LOGGER.debug("Node {} is of type {}", entry.getKey(), n.getNodeType());
-            }
-        }
-
-        String t;
-        if (type == null) {
-            t = "null";
-        } else {
-            t = type.getElementName() + ':' + type.getPluginClass();
-        }
-
-        final String p = node.getParent() == null ? "null"
-                : node.getParent().getName() == null ? LoggerConfig.ROOT : node.getParent().getName();
-        LOGGER.debug("Returning {} with parent {} of type {}", node.getName(), p, t);
-        return node;
-    }
-
-    private String getType(final JsonNode node, final String name) {
-        final Iterator<Map.Entry<String, JsonNode>> iter = node.fields();
-        while (iter.hasNext()) {
-            final Map.Entry<String, JsonNode> entry = iter.next();
-            if (entry.getKey().equalsIgnoreCase("type")) {
-                final JsonNode n = entry.getValue();
-                if (n.isValueNode()) {
-                    return n.asText();
-                }
-            }
-        }
-        return name;
-    }
-
-    private void processAttributes(final Node parent, final JsonNode node) {
-        final Map<String, String> attrs = parent.getAttributes();
-        final Iterator<Map.Entry<String, JsonNode>> iter = node.fields();
-        while (iter.hasNext()) {
-            final Map.Entry<String, JsonNode> entry = iter.next();
-            if (!entry.getKey().equalsIgnoreCase("type")) {
-                final JsonNode n = entry.getValue();
-                if (n.isValueNode()) {
-                    attrs.put(entry.getKey(), n.asText());
-                }
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[location=" + getConfigurationSource() + "]";
-    }
-
-    /**
-     * The error that occurred.
-     */
-    private enum ErrorType {
-        CLASS_NOT_FOUND
-    }
-
-    /**
-     * Status for recording errors.
-     */
-    private static class Status {
-        private final JsonNode node;
-        private final String name;
-        private final ErrorType errorType;
-
-        public Status(final String name, final JsonNode node, final ErrorType errorType) {
-            this.name = name;
-            this.node = node;
-            this.errorType = errorType;
-        }
-
-        @Override
-        public String toString() {
-            return "Status [name=" + name + ", errorType=" + errorType + ", node=" + node + "]";
-        }
-    }
-}
+/*
+ * 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.json;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.logging.log4j.core.config.AbstractConfiguration;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.ConfiguratonFileWatcher;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.Reconfigurable;
+import org.apache.logging.log4j.core.config.plugins.util.PluginType;
+import org.apache.logging.log4j.core.config.plugins.util.ResolverUtil;
+import org.apache.logging.log4j.core.config.status.StatusConfiguration;
+import org.apache.logging.log4j.core.util.FileWatcher;
+import org.apache.logging.log4j.core.util.Patterns;
+
+/**
+ * Creates a Node hierarchy from a JSON file.
+ */
+public class JsonConfiguration extends AbstractConfiguration implements Reconfigurable {
+
+    private static final String[] VERBOSE_CLASSES = new String[] { ResolverUtil.class.getName() };
+    private final List<Status> status = new ArrayList<>();
+    private JsonNode root;
+
+    public JsonConfiguration(final ConfigurationSource configSource) {
+        super(configSource);
+        final File configFile = configSource.getFile();
+        byte[] buffer;
+        try {
+            try (final InputStream configStream = configSource.getInputStream()) {
+                buffer = toByteArray(configStream);
+            }
+            final InputStream is = new ByteArrayInputStream(buffer);
+            root = getObjectMapper().readTree(is);
+            if (root.size() == 1) {
+                for (final JsonNode node : root) {
+                    root = node;
+                }
+            }
+            processAttributes(rootNode, root);
+            final StatusConfiguration statusConfig = new StatusConfiguration().withVerboseClasses(VERBOSE_CLASSES)
+                    .withStatus(getDefaultStatus());
+            for (final Map.Entry<String, String> entry : rootNode.getAttributes().entrySet()) {
+                final String key = entry.getKey();
+                final String value = getStrSubstitutor().replace(entry.getValue());
+                // TODO: this duplicates a lot of the XmlConfiguration constructor
+                if ("status".equalsIgnoreCase(key)) {
+                    statusConfig.withStatus(value);
+                } else if ("dest".equalsIgnoreCase(key)) {
+                    statusConfig.withDestination(value);
+                } else if ("shutdownHook".equalsIgnoreCase(key)) {
+                    isShutdownHookEnabled = !"disable".equalsIgnoreCase(value);
+                } else if ("verbose".equalsIgnoreCase(entry.getKey())) {
+                    statusConfig.withVerbosity(value);
+                } else if ("packages".equalsIgnoreCase(key)) {
+                    pluginPackages.addAll(Arrays.asList(value.split(Patterns.COMMA_SEPARATOR)));
+                } else if ("name".equalsIgnoreCase(key)) {
+                    setName(value);
+                } else if ("monitorInterval".equalsIgnoreCase(key)) {
+                    final int intervalSeconds = Integer.parseInt(value);
+                    if (intervalSeconds > 0) {
+                        getWatchManager().setIntervalSeconds(intervalSeconds);
+                        if (configFile != null) {
+                            FileWatcher watcher = new ConfiguratonFileWatcher(this, listeners);
+                            getWatchManager().watchFile(configFile, watcher);
+                        }
+                    }
+                } else if ("advertiser".equalsIgnoreCase(key)) {
+                    createAdvertiser(value, configSource, buffer, "application/json");
+                }
+            }
+            statusConfig.initialize();
+            if (getName() == null) {
+                setName(configSource.getLocation());
+            }
+        } catch (final Exception ex) {
+            LOGGER.error("Error parsing " + configSource.getLocation(), ex);
+        }
+    }
+
+    protected ObjectMapper getObjectMapper() {
+        return new ObjectMapper().configure(JsonParser.Feature.ALLOW_COMMENTS, true);
+    }
+
+    @Override
+    public void setup() {
+        final Iterator<Map.Entry<String, JsonNode>> iter = root.fields();
+        final List<Node> children = rootNode.getChildren();
+        while (iter.hasNext()) {
+            final Map.Entry<String, JsonNode> entry = iter.next();
+            final JsonNode n = entry.getValue();
+            if (n.isObject()) {
+                LOGGER.debug("Processing node for object {}", entry.getKey());
+                children.add(constructNode(entry.getKey(), rootNode, n));
+            } else if (n.isArray()) {
+                LOGGER.error("Arrays are not supported at the root configuration.");
+            }
+        }
+        LOGGER.debug("Completed parsing configuration");
+        if (status.size() > 0) {
+            for (final Status s : status) {
+                LOGGER.error("Error processing element " + s.name + ": " + s.errorType);
+            }
+        }
+    }
+
+    @Override
+    public Configuration reconfigure() {
+        try {
+            final ConfigurationSource source = getConfigurationSource().resetInputStream();
+            if (source == null) {
+                return null;
+            }
+            return new JsonConfiguration(source);
+        } catch (final IOException ex) {
+            LOGGER.error("Cannot locate file {}", getConfigurationSource(), ex);
+        }
+        return null;
+    }
+
+    private Node constructNode(final String name, final Node parent, final JsonNode jsonNode) {
+        final PluginType<?> type = pluginManager.getPluginType(name);
+        final Node node = new Node(parent, name, type);
+        processAttributes(node, jsonNode);
+        final Iterator<Map.Entry<String, JsonNode>> iter = jsonNode.fields();
+        final List<Node> children = node.getChildren();
+        while (iter.hasNext()) {
+            final Map.Entry<String, JsonNode> entry = iter.next();
+            final JsonNode n = entry.getValue();
+            if (n.isArray() || n.isObject()) {
+                if (type == null) {
+                    status.add(new Status(name, n, ErrorType.CLASS_NOT_FOUND));
+                }
+                if (n.isArray()) {
+                    LOGGER.debug("Processing node for array {}", entry.getKey());
+                    for (int i = 0; i < n.size(); ++i) {
+                        final String pluginType = getType(n.get(i), entry.getKey());
+                        final PluginType<?> entryType = pluginManager.getPluginType(pluginType);
+                        final Node item = new Node(node, entry.getKey(), entryType);
+                        processAttributes(item, n.get(i));
+                        if (pluginType.equals(entry.getKey())) {
+                            LOGGER.debug("Processing {}[{}]", entry.getKey(), i);
+                        } else {
+                            LOGGER.debug("Processing {} {}[{}]", pluginType, entry.getKey(), i);
+                        }
+                        final Iterator<Map.Entry<String, JsonNode>> itemIter = n.get(i).fields();
+                        final List<Node> itemChildren = item.getChildren();
+                        while (itemIter.hasNext()) {
+                            final Map.Entry<String, JsonNode> itemEntry = itemIter.next();
+                            if (itemEntry.getValue().isObject()) {
+                                LOGGER.debug("Processing node for object {}", itemEntry.getKey());
+                                itemChildren.add(constructNode(itemEntry.getKey(), item, itemEntry.getValue()));
+                            } else if (itemEntry.getValue().isArray()) {
+                                final JsonNode array = itemEntry.getValue();
+                                final String entryName = itemEntry.getKey();
+                                LOGGER.debug("Processing array for object {}", entryName);
+                                for (int j = 0; j < array.size(); ++j) {
+                                    itemChildren.add(constructNode(entryName, item, array.get(j)));
+                                }
+                            }
+
+                        }
+                        children.add(item);
+                    }
+                } else {
+                    LOGGER.debug("Processing node for object {}", entry.getKey());
+                    children.add(constructNode(entry.getKey(), node, n));
+                }
+            } else {
+                LOGGER.debug("Node {} is of type {}", entry.getKey(), n.getNodeType());
+            }
+        }
+
+        String t;
+        if (type == null) {
+            t = "null";
+        } else {
+            t = type.getElementName() + ':' + type.getPluginClass();
+        }
+
+        final String p = node.getParent() == null ? "null"
+                : node.getParent().getName() == null ? LoggerConfig.ROOT : node.getParent().getName();
+        LOGGER.debug("Returning {} with parent {} of type {}", node.getName(), p, t);
+        return node;
+    }
+
+    private String getType(final JsonNode node, final String name) {
+        final Iterator<Map.Entry<String, JsonNode>> iter = node.fields();
+        while (iter.hasNext()) {
+            final Map.Entry<String, JsonNode> entry = iter.next();
+            if (entry.getKey().equalsIgnoreCase("type")) {
+                final JsonNode n = entry.getValue();
+                if (n.isValueNode()) {
+                    return n.asText();
+                }
+            }
+        }
+        return name;
+    }
+
+    private void processAttributes(final Node parent, final JsonNode node) {
+        final Map<String, String> attrs = parent.getAttributes();
+        final Iterator<Map.Entry<String, JsonNode>> iter = node.fields();
+        while (iter.hasNext()) {
+            final Map.Entry<String, JsonNode> entry = iter.next();
+            if (!entry.getKey().equalsIgnoreCase("type")) {
+                final JsonNode n = entry.getValue();
+                if (n.isValueNode()) {
+                    attrs.put(entry.getKey(), n.asText());
+                }
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[location=" + getConfigurationSource() + "]";
+    }
+
+    /**
+     * The error that occurred.
+     */
+    private enum ErrorType {
+        CLASS_NOT_FOUND
+    }
+
+    /**
+     * Status for recording errors.
+     */
+    private static class Status {
+        private final JsonNode node;
+        private final String name;
+        private final ErrorType errorType;
+
+        public Status(final String name, final JsonNode node, final ErrorType errorType) {
+            this.name = name;
+            this.node = node;
+            this.errorType = errorType;
+        }
+
+        @Override
+        public String toString() {
+            return "Status [name=" + name + ", errorType=" + errorType + ", node=" + node + "]";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2be4de9b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
index 87ef688..ca2c0a0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/xml/XmlConfiguration.java
@@ -144,7 +144,7 @@ public class XmlConfiguration extends AbstractConfiguration implements Reconfigu
             }
             statusConfig.initialize();
         } catch (final SAXException | IOException | ParserConfigurationException e) {
-            LOGGER.error("Error parsing {}", configSource.getLocation(), e);
+            LOGGER.error("Error parsing " + configSource.getLocation(), e);
         }
         if (strict && schemaResource != null && buffer != null) {
             InputStream is = null;

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/2be4de9b/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 8174a4d..1543f45 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -24,6 +24,9 @@
   </properties>
   <body>
     <release version="2.6" date="2016-MM-DD" description="GA Release 2.6">
+      <action issue="LOG4J2-1309" dev="ggregory" type="fix">
+        Configuration file error does not show cause exception.
+      </action>
       <action issue="LOG4J2-1299" dev="ggregory" type="add">
         Add pattern converter for thread id and priority in PatternLayout.
       </action>