http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlMarkerMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlMarkerMixIn.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlMarkerMixIn.java
new file mode 100644
index 0000000..9fa0e8a
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlMarkerMixIn.java
@@ -0,0 +1,79 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.jackson.MarkerMixIn;
+import org.apache.logging.log4j.core.jackson.XmlConstants;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+/**
+ * Jackson mix-in for {@link Marker}.
+ * <p>
+ * If we want to deal with more than one {@link Marker} implementation then 
recode these annotations to include
+ * metadata.
+ * </p>
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * <p>
+ * Example XML:
+ * </p>
+ *
+ * <pre>
+&lt;Marker name=&quot;Marker1&quot;&gt;
+    &lt;Parents&gt;
+        &lt;Marker name=&quot;ParentMarker1&quot;&gt;
+            &lt;Parents&gt;
+                &lt;Marker name=&quot;GrandMotherMarker&quot;/&gt;
+                &lt;Marker name=&quot;GrandFatherMarker&quot;/&gt;
+            &lt;/Parents&gt;
+        &lt;/Marker&gt;
+        &lt;Marker name=&quot;ParentMarker2&quot;/&gt;
+    &lt;/Parents&gt;
+&lt;/Marker&gt;
+ * </pre>
+ *
+ * @see Marker
+ */
+// Alternate for multiple Marker implementation.
+// @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = 
JsonTypeInfo.As.PROPERTY, property = "@class")
+@JsonDeserialize(as = org.apache.logging.log4j.MarkerManager.Log4jMarker.class)
+abstract class XmlMarkerMixIn extends MarkerMixIn {
+    public static final String ATTR_NAME = "name";
+    private static final long serialVersionUID = 1L;
+
+    @JsonCreator
+    protected XmlMarkerMixIn(@JsonProperty(ATTR_NAME) final String name) {
+        super(name);
+    }
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true)
+    public abstract String getName();
+
+    @Override
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_PARENTS)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_MARKER)
+    public abstract Marker[] getParents();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
new file mode 100644
index 0000000..442f9ab
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
@@ -0,0 +1,42 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.jackson.ExtendedStackTraceElementMixIn;
+import org.apache.logging.log4j.core.jackson.LevelMixIn;
+import org.apache.logging.log4j.core.jackson.ThrowableProxyMixIn;
+import 
org.apache.logging.log4j.core.jackson.ThrowableProxyWithStacktraceAsStringMixIn;
+import 
org.apache.logging.log4j.core.jackson.ThrowableProxyWithoutStacktraceMixIn;
+import org.apache.logging.log4j.core.time.Instant;
+
+import com.fasterxml.jackson.databind.Module.SetupContext;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * Used to set up {@link SetupContext} from different {@link SimpleModule}s.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+class XmlSetupContextInitializer {
+
+    public void setupModule(final SetupContext context, final boolean 
includeStacktrace,
+            final boolean stacktraceAsString) {
+        // JRE classes: we cannot edit those with Jackson annotations
+        context.setMixInAnnotations(StackTraceElement.class, 
XmlStackTraceElementMixIn.class);
+        // Log4j API classes: we do not want to edit those with Jackson 
annotations because the API module should not
+        // depend on Jackson.
+        context.setMixInAnnotations(Marker.class, XmlMarkerMixIn.class);
+        context.setMixInAnnotations(Level.class, LevelMixIn.class);
+        context.setMixInAnnotations(Instant.class, XmlInstantMixIn.class);
+        context.setMixInAnnotations(LogEvent.class, 
XmlLogEventWithContextListMixIn.class);
+        // Log4j Core classes: we do not want to bring in Jackson at runtime 
if we do not have to.
+        context.setMixInAnnotations(ExtendedStackTraceElement.class, 
ExtendedStackTraceElementMixIn.class);
+        context.setMixInAnnotations(ThrowableProxy.class, includeStacktrace
+                ? (stacktraceAsString ? 
ThrowableProxyWithStacktraceAsStringMixIn.class : ThrowableProxyMixIn.class)
+                : ThrowableProxyWithoutStacktraceMixIn.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlStackTraceElementMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlStackTraceElementMixIn.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlStackTraceElementMixIn.java
new file mode 100644
index 0000000..abdba98
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/XmlStackTraceElementMixIn.java
@@ -0,0 +1,39 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.core.jackson.StackTraceElementMixIn;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+abstract class XmlStackTraceElementMixIn extends StackTraceElementMixIn {
+
+    @JsonCreator
+    protected XmlStackTraceElementMixIn(
+    // @formatter:off
+            @JsonProperty(ATTR_CLASS) final String declaringClass,
+            @JsonProperty(ATTR_METHOD) final String methodName,
+            @JsonProperty(ATTR_FILE) final String fileName,
+            @JsonProperty(ATTR_LINE) final int lineNumber)
+            // @formatter:on
+    {
+        super(declaringClass, methodName, fileName, lineNumber);
+    }
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_CLASS, isAttribute = true)
+    protected abstract String getClassName();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_FILE, isAttribute = true)
+    protected abstract String getFileName();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_LINE, isAttribute = true)
+    protected abstract int getLineNumber();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_METHOD, isAttribute = true)
+    protected abstract String getMethodName();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
new file mode 100644
index 0000000..24c5ef0
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
@@ -0,0 +1,41 @@
+package org.apache.logging.log4j.jackson.xml.layout;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.XMLStreamWriter2;
+
+import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
+
+/**
+ * When &lt;Event&gt;s are written into a XML file; the "Event" object is not 
the root element, but an element named
+ * &lt;Events&gt; created using {@link XmlLayout#getHeader()} and {@link 
XmlLayout#getFooter()} methods.
+ * <p>
+ * {@link com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter} 
is used to print the Event object into
+ * XML; hence it assumes &lt;Event&gt; tag as the root element, so it prints 
the &lt;Event&gt; tag without any
+ * indentation. To add an indentation to the &lt;Event&gt; tag; hence an 
additional indentation for any
+ * sub-elements, this class is written. As an additional task, to avoid the 
blank line printed after the ending
+ * &lt;/Event&gt; tag, {@link #writePrologLinefeed(XMLStreamWriter2)} method 
is also overridden.
+ * </p>
+ */
+class Log4jXmlPrettyPrinter extends DefaultXmlPrettyPrinter {
+
+    private static final long serialVersionUID = 1L;
+
+    Log4jXmlPrettyPrinter(final int nesting) {
+        _nesting = nesting;
+    }
+
+    /**
+     * Sets the nesting level to 1 rather than 0, so the "Event" tag will get 
indentation of next level below root.
+     */
+    @Override
+    public DefaultXmlPrettyPrinter createInstance() {
+        return new Log4jXmlPrettyPrinter(XmlJacksonFactory.DEFAULT_INDENT);
+    }
+
+    @Override
+    public void writePrologLinefeed(final XMLStreamWriter2 sw) throws 
XMLStreamException {
+        // nothing
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
new file mode 100644
index 0000000..0289c71
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
@@ -0,0 +1,54 @@
+package org.apache.logging.log4j.jackson.xml.layout;
+
+import org.apache.logging.log4j.core.jackson.AbstractJacksonFactory;
+import org.apache.logging.log4j.core.jackson.JsonConstants;
+import org.apache.logging.log4j.core.jackson.XmlConstants;
+import org.apache.logging.log4j.jackson.xml.Log4jXmlObjectMapper;
+
+import com.fasterxml.jackson.core.PrettyPrinter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+class XmlJacksonFactory extends AbstractJacksonFactory {
+
+    static final int DEFAULT_INDENT = 1;
+
+    public XmlJacksonFactory(final boolean includeStacktrace, final boolean 
stacktraceAsString) {
+        super(includeStacktrace, stacktraceAsString);
+    }
+
+    @Override
+    protected String getPropertyNameForContextMap() {
+        return XmlConstants.ELT_CONTEXT_MAP;
+    }
+
+    @Override
+    protected String getPropertyNameForNanoTime() {
+        return JsonConstants.ELT_NANO_TIME;
+    }
+
+    @Override
+    protected String getPropertyNameForSource() {
+        return XmlConstants.ELT_SOURCE;
+    }
+
+    @Override
+    protected String getPropertyNameForStackTrace() {
+        return XmlConstants.ELT_EXTENDED_STACK_TRACE;
+    }
+
+    @Override
+    protected PrettyPrinter newCompactPrinter() {
+        // Yes, null is the proper answer.
+        return null;
+    }
+
+    @Override
+    protected ObjectMapper newObjectMapper() {
+        return new Log4jXmlObjectMapper(includeStacktrace, stacktraceAsString);
+    }
+
+    @Override
+    protected PrettyPrinter newPrettyPrinter() {
+        return new Log4jXmlPrettyPrinter(DEFAULT_INDENT);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
new file mode 100644
index 0000000..c305c33
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
@@ -0,0 +1,226 @@
+/*
+ * 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.jackson.xml.layout;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
+import org.apache.logging.log4j.core.jackson.AbstractJacksonLayout;
+import org.apache.logging.log4j.core.jackson.XmlConstants;
+import org.apache.logging.log4j.core.util.KeyValuePair;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+/**
+ * Appends a series of {@code event} elements as defined in the <a 
href="log4j.dtd">log4j.dtd</a>.
+ *
+ * <h3>Complete well-formed XML vs. fragment XML</h3>
+ * <p>
+ * If you configure {@code complete="true"}, the appender outputs a 
well-formed XML document where the default namespace
+ * is the log4j namespace {@value XmlConstants#XML_NAMESPACE}. By default, 
with {@code complete="false"}, you should
+ * include the output as an <em>external entity</em> in a separate file to 
form a well-formed XML document.
+ * </p>
+ * <p>
+ * If {@code complete="false"}, the appender does not write the XML processing 
instruction and the root element.
+ * </p>
+ * <h3>Encoding</h3>
+ * <p>
+ * Appenders using this layout should have their {@code charset} set to {@code 
UTF-8} or {@code UTF-16}, otherwise
+ * events containing non-ASCII characters could result in corrupted log files.
+ * </p>
+ * <h3>Pretty vs. compact XML</h3>
+ * <p>
+ * By default, the XML layout is not compact (compact = not "pretty") with 
{@code compact="false"}, which means the
+ * appender uses end-of-line characters and indents lines to format the XML. 
If {@code compact="true"}, then no
+ * end-of-line or indentation is used. Message content may contain, of course, 
end-of-lines.
+ * </p>
+ * <h3>Additional Fields</h3>
+ * <p>
+ * This property allows addition of custom fields into generated JSON.
+ * {@code <XmlLayout><KeyValuePair key="foo" value="bar"/></XmlLayout>} 
inserts {@code <foo>bar</foo>} directly into XML
+ * output. Supports Lookup expressions.
+ * </p>
+ */
+@Plugin(name = "XmlLayout", category = Node.CATEGORY, elementType = 
Layout.ELEMENT_TYPE, printObject = true)
+public final class XmlLayout extends AbstractJacksonLayout {
+
+    public static class Builder<B extends Builder<B>> extends 
AbstractJacksonLayout.Builder<B>
+            implements org.apache.logging.log4j.core.util.Builder<XmlLayout> {
+
+        public Builder() {
+            super();
+            setCharset(StandardCharsets.UTF_8);
+        }
+
+        @Override
+        public XmlLayout build() {
+            return new XmlLayout(getConfiguration(), isLocationInfo(), 
isProperties(), isComplete(), isCompact(),
+                    getCharset(), isIncludeStacktrace(), 
isStacktraceAsString(), isIncludeNullDelimiter(),
+                    getAdditionalFields());
+        }
+    }
+
+    @JacksonXmlRootElement(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_EVENT)
+    public static class XmlLogEventWithAdditionalFields extends 
LogEventWithAdditionalFields {
+
+        public XmlLogEventWithAdditionalFields(final Object logEvent, final 
Map<String, String> additionalFields) {
+            super(logEvent, additionalFields);
+        }
+
+    }
+
+    private static final String ROOT_TAG = "Events";
+
+    /**
+     * Creates an XML Layout using the default settings.
+     *
+     * @return an XML Layout.
+     */
+    public static XmlLayout createDefaultLayout() {
+        return new XmlLayout(null, false, false, false, false, 
StandardCharsets.UTF_8, true, false, false, null);
+    }
+
+    /**
+     * Creates an XML Layout.
+     *
+     * @param locationInfo
+     *            If "true", includes the location information in the 
generated XML.
+     * @param properties
+     *            If "true", includes the thread context map in the generated 
XML.
+     * @param complete
+     *            If "true", includes the XML header and footer, defaults to 
"false".
+     * @param compact
+     *            If "true", does not use end-of-lines and indentation, 
defaults to "false".
+     * @param charset
+     *            The character set to use, if {@code null}, uses "UTF-8".
+     * @param includeStacktrace
+     *            If "true", includes the stacktrace of any Throwable in the 
generated XML, defaults to "true".
+     * @return An XML Layout.
+     *
+     * @deprecated Use {@link #newBuilder()} instead
+     */
+    @Deprecated
+    public static XmlLayout createLayout(final boolean locationInfo, final 
boolean properties, final boolean complete,
+            final boolean compact, final Charset charset, final boolean 
includeStacktrace) {
+        return new XmlLayout(null, locationInfo, properties, complete, 
compact, charset, includeStacktrace, false,
+                false, null);
+    }
+
+    @PluginBuilderFactory
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
+    }
+
+    /**
+     * @deprecated Use {@link #newBuilder()} instead
+     */
+    @Deprecated
+    protected XmlLayout(final boolean locationInfo, final boolean properties, 
final boolean complete,
+            final boolean compact, final Charset charset, final boolean 
includeStacktrace) {
+        this(null, locationInfo, properties, complete, compact, charset, 
includeStacktrace, false, false, null);
+    }
+
+    private XmlLayout(final Configuration config, final boolean locationInfo, 
final boolean properties,
+            final boolean complete, final boolean compact, final Charset 
charset, final boolean includeStacktrace,
+            final boolean stacktraceAsString, final boolean 
includeNullDelimiter,
+            final KeyValuePair[] additionalFields) {
+        super(config,
+                new XmlJacksonFactory(includeStacktrace, 
stacktraceAsString).newWriter(locationInfo, properties,
+                        compact),
+                charset, compact, complete, false, null, null, 
includeNullDelimiter, additionalFields);
+    }
+
+    @Override
+    protected LogEventWithAdditionalFields 
createLogEventWithAdditionalFields(final LogEvent event,
+            final Map<String, String> additionalFieldsMap) {
+        return new XmlLogEventWithAdditionalFields(event, additionalFieldsMap);
+    }
+
+    /**
+     * Gets this XmlLayout's content format. Specified by:
+     * <ul>
+     * <li>Key: "dtd" Value: "log4j-events.dtd"</li>
+     * <li>Key: "version" Value: "2.0"</li>
+     * </ul>
+     *
+     * @return Map of content format keys supporting XmlLayout
+     */
+    @Override
+    public Map<String, String> getContentFormat() {
+        final Map<String, String> result = new HashMap<>();
+        // result.put("dtd", "log4j-events.dtd");
+        result.put("xsd", "log4j-events.xsd");
+        result.put("version", "2.0");
+        return result;
+    }
+
+    /**
+     * @return The content type.
+     */
+    @Override
+    public String getContentType() {
+        return "text/xml; charset=" + this.getCharset();
+    }
+
+    /**
+     * Returns appropriate XML footer.
+     *
+     * @return a byte array containing the footer, closing the XML root 
element.
+     */
+    @Override
+    public byte[] getFooter() {
+        if (!complete) {
+            return null;
+        }
+        return getBytes("</" + ROOT_TAG + '>' + this.eol);
+    }
+
+    /**
+     * Returns appropriate XML headers.
+     * <ol>
+     * <li>XML processing instruction</li>
+     * <li>XML root element</li>
+     * </ol>
+     *
+     * @return a byte array containing the header.
+     */
+    @Override
+    public byte[] getHeader() {
+        if (!complete) {
+            return null;
+        }
+        final StringBuilder buf = new StringBuilder();
+        buf.append("<?xml version=\"1.0\" encoding=\"");
+        buf.append(this.getCharset().name());
+        buf.append("\"?>");
+        buf.append(this.eol);
+        // Make the log4j namespace the default namespace, no need to use more 
space with a namespace prefix.
+        buf.append('<');
+        buf.append(ROOT_TAG);
+        buf.append(" xmlns=\"" + XmlConstants.XML_NAMESPACE + "\">");
+        buf.append(this.eol);
+        return buf.toString().getBytes(this.getCharset());
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/parser/XmlLogEventParser.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/parser/XmlLogEventParser.java
 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/parser/XmlLogEventParser.java
new file mode 100644
index 0000000..32776a2
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/java/org/apache/logging/log4j/jackson/xml/parser/XmlLogEventParser.java
@@ -0,0 +1,32 @@
+/*
+ * 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.jackson.xml.parser;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.parser.AbstractJacksonLogEventParser;
+import org.apache.logging.log4j.jackson.xml.Log4jXmlObjectMapper;
+
+/**
+ * Parses the output from XmlLayout layout into instances of {@link LogEvent}.
+ */
+public class XmlLogEventParser extends AbstractJacksonLogEventParser {
+
+    public XmlLogEventParser() {
+        super(new Log4jXmlObjectMapper());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-layout-jackson-xml/pom.xml b/log4j-layout-jackson-xml/pom.xml
new file mode 100644
index 0000000..4a8989d
--- /dev/null
+++ b/log4j-layout-jackson-xml/pom.xml
@@ -0,0 +1,171 @@
+<?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. -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>log4j-layout-jackson-xml</artifactId>
+  <name>Apache Log4j Layout for Jackson XML</name>
+  <description>
+    Apache Log4j Layout for Jackson XML.
+  </description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>Log4j Layout for Jackson XML Documentation</docLabel>
+    <projectDir>/log4j-layout-xml</projectDir>
+    <module.name>org.apache.logging.log4j.jackson.xml</module.name>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-layout-jackson</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.dataformat</groupId>
+      <artifactId>jackson-dataformat-xml</artifactId>
+    </dependency>
+    <!-- Test Dependencies -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <type>test-jar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <type>test-jar</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-layout-jackson</artifactId>
+      <type>test-jar</type>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Fragment-Host>org.apache.logging.log4j.jackson.xml</Fragment-Host>
+            <Export-Package>*</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-changes-plugin</artifactId>
+        <version>${changes.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>changes-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+        <configuration>
+          <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+          <useJql>true</useJql>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${checkstyle.plugin.version}</version>
+        <configuration>
+          
<!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation>
 -->
+          <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+          
<suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+          <enableRulesSummary>false</enableRulesSummary>
+          <propertyExpansion>basedir=${basedir}</propertyExpansion>
+          
<propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <version>${javadoc.plugin.version}</version>
+        <configuration>
+          <bottom><![CDATA[<p align="center">Copyright &#169; 
{inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+            Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather 
logo, the Apache Logging project logo,
+            and the Apache Log4j logo are trademarks of The Apache Software 
Foundation.</p>]]></bottom>
+          <!-- module link generation is completely broken in the javadoc 
plugin for a multi-module non-aggregating project -->
+          <detectOfflineLinks>false</detectOfflineLinks>
+          <linksource>true</linksource>
+        </configuration>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>javadoc</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>${findbugs.plugin.version}</version>
+        <configuration>
+          <fork>true</fork>
+          <jvmArgs>-Duser.language=en</jvmArgs>
+          <threshold>Normal</threshold>
+          <effort>Default</effort>
+          
<excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>${jxr.plugin.version}</version>
+        <reportSets>
+          <reportSet>
+            <id>non-aggregate</id>
+            <reports>
+              <report>jxr</report>
+            </reports>
+          </reportSet>
+          <reportSet>
+            <id>aggregate</id>
+            <reports>
+              <report>aggregate</report>
+            </reports>
+          </reportSet>
+        </reportSets>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>${pmd.plugin.version}</version>
+        <configuration>
+          <targetJdk>${maven.compiler.target}</targetJdk>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+</project>

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/AbstractLogEventXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/AbstractLogEventXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/AbstractLogEventXmlMixIn.java
new file mode 100644
index 0000000..9d8687d
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/AbstractLogEventXmlMixIn.java
@@ -0,0 +1,135 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext.ContextStack;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.jackson.AbstractLogEventMixIn;
+import org.apache.logging.log4j.jackson.ContextDataAsEntryListDeserializer;
+import org.apache.logging.log4j.jackson.Log4jStackTraceElementDeserializer;
+import org.apache.logging.log4j.jackson.MessageSerializer;
+import org.apache.logging.log4j.jackson.SimpleMessageDeserializer;
+import org.apache.logging.log4j.jackson.XmlConstants;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import com.fasterxml.jackson.annotation.JsonFilter;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+/**
+* <pre>AbstractLogEventMixIn
+*├─ XmlLogEventMixIn
+*├──── XmlLogEventWithContextListMixIn
+*├──── XmlLogEventWithContextMapMixIn
+*├─ JsonLogEventMixIn
+*├──── JsonLogEventWithContextListMixIn
+*├──── JsonLogEventWithContextMapMixIn</pre>
+*/
+@JacksonXmlRootElement(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_EVENT)
+@JsonFilter(AbstractLogEventMixIn.JSON_FILTER_ID)
+@JsonPropertyOrder({
+    // @formatter:off
+    AbstractLogEventMixIn.ATTR_THREAD,
+    AbstractLogEventMixIn.ATTR_LEVEL,
+    AbstractLogEventMixIn.ATTR_LOGGER_NAME,
+    AbstractLogEventMixIn.ATTR_LOGGER_FQCN,
+    AbstractLogEventMixIn.ATTR_END_OF_BATCH,
+    XmlConstants.ELT_INSTANT,
+    XmlConstants.ELT_MARKER,
+    XmlConstants.ELT_MESSAGE,
+    AbstractLogEventXmlMixIn.ELT_THROWN,
+    XmlConstants.ELT_CONTEXT_MAP,
+    XmlConstants.ELT_CONTEXT_STACK,
+    XmlConstants.ELT_SOURCE})
+    // @formatter:on
+public abstract class AbstractLogEventXmlMixIn extends AbstractLogEventMixIn {
+
+    public static final String ELT_THROWN = "Thrown";
+
+    private static final long serialVersionUID = 1L;
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CONTEXT_MAP)
+    @JsonSerialize(using = ContextDataAsEntryListXmlSerializer.class)
+    @JsonDeserialize(using = ContextDataAsEntryListDeserializer.class)
+    @Override
+    public abstract ReadOnlyStringMap getContextData();
+
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_CONTEXT_STACK)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CONTEXT_STACK_ITEM)
+    @Override
+    public abstract ContextStack getContextStack();
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_INSTANT)
+    @Override
+    public abstract Instant getInstant();
+
+    @JacksonXmlProperty(isAttribute = true)
+    @Override
+    public abstract Level getLevel();
+
+    @JacksonXmlProperty(isAttribute = true)
+    @Override
+    public abstract String getLoggerFqcn();
+
+    @JacksonXmlProperty(isAttribute = true)
+    @Override
+    public abstract String getLoggerName();
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_MARKER)
+    @Override
+    public abstract Marker getMarker();
+
+    @JsonSerialize(using = MessageSerializer.class)
+    @JsonDeserialize(using = SimpleMessageDeserializer.class)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_MESSAGE)
+    @Override
+    public abstract Message getMessage();
+
+    @JsonDeserialize(using = Log4jStackTraceElementDeserializer.class)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_SOURCE)
+    @Override
+    public abstract StackTraceElement getSource();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true, localName = ATTR_THREAD_ID)
+    public abstract long getThreadId();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true, localName = ATTR_THREAD)
+    public abstract String getThreadName();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true, localName = ATTR_THREAD_PRIORITY)
+    public abstract int getThreadPriority();
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_THROWN)
+    @Override
+    public abstract ThrowableProxy getThrownProxy();
+
+    @JacksonXmlProperty(isAttribute = true)
+    @Override
+    public abstract boolean isEndOfBatch();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ContextDataAsEntryListXmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ContextDataAsEntryListXmlSerializer.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ContextDataAsEntryListXmlSerializer.java
new file mode 100644
index 0000000..b916c44
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ContextDataAsEntryListXmlSerializer.java
@@ -0,0 +1,37 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.jackson.ContextDataAsEntryListSerializer;
+import org.apache.logging.log4j.jackson.MapEntry;
+
+public class ContextDataAsEntryListXmlSerializer extends 
ContextDataAsEntryListSerializer {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected MapEntry createMapEntry(final String key, final String value) {
+        return new XmlMapEntry(key, value);
+    }
+
+    @Override
+    protected MapEntry[] createMapEntryArray(final int size) {
+        return new XmlMapEntry[size];
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
new file mode 100644
index 0000000..224ef40
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
@@ -0,0 +1,68 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.core.impl.ExtendedClassInfo;
+import org.apache.logging.log4j.jackson.ExtendedStackTraceElementMixIn;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+public abstract class ExtendedStackTraceElementXmlMixIn extends 
ExtendedStackTraceElementMixIn {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonCreator
+    public ExtendedStackTraceElementXmlMixIn(
+    // @formatter:off
+            @JsonProperty(ATTR_CLASS) final String declaringClass,
+            @JsonProperty(ATTR_METHOD) final String methodName,
+            @JsonProperty(ATTR_FILE) final String fileName,
+            @JsonProperty(ATTR_LINE) final int lineNumber,
+            @JsonProperty(ATTR_EXACT) final boolean exact,
+            @JsonProperty(ATTR_LOCATION) final String location,
+            @JsonProperty(ATTR_VERSION) final String version
+   // @formatter:on
+    ) {
+        super(declaringClass, methodName, fileName, lineNumber, exact, 
location, version);
+    }
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_CLASS, isAttribute = true)
+    public abstract String getClassName();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true)
+    public abstract boolean getExact();
+
+    @Override
+    @JsonIgnore
+    public abstract ExtendedClassInfo getExtraClassInfo();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_FILE, isAttribute = true)
+    public abstract String getFileName();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_LINE, isAttribute = true)
+    public abstract int getLineNumber();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true)
+    public abstract String getLocation();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_METHOD, isAttribute = true)
+    public abstract String getMethodName();
+
+    @JsonIgnore
+    abstract StackTraceElement getStackTraceElement();
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true)
+    public abstract String getVersion();
+
+    @Override
+    @JsonIgnore
+    public abstract boolean isNativeMethod();
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/InstantXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/InstantXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/InstantXmlMixIn.java
new file mode 100644
index 0000000..df5a5ce
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/InstantXmlMixIn.java
@@ -0,0 +1,56 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.jackson.InstantMixIn;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+/**
+ * Jackson mix-in for {@link Instant}.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ *
+ * @see Marker
+ */
+abstract class InstantXmlMixIn extends InstantMixIn {
+
+    @JsonCreator
+    protected InstantXmlMixIn(
+    // @formatter:off
+            @JsonProperty(ATTR_EPOCH_SECOND) final long epochSecond,
+            @JsonProperty(ATTR_NANO_OF_SECOND) final int nanoOfSecond)
+    // @formatter:on
+    {
+        super(epochSecond, nanoOfSecond);
+    }
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_EPOCH_SECOND, isAttribute = true)
+    public abstract long getEpochSecond();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_NANO_OF_SECOND, isAttribute = true)
+    public abstract int getNanoOfSecond();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlModule.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlModule.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlModule.java
new file mode 100644
index 0000000..76166b0
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlModule.java
@@ -0,0 +1,52 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.jackson.SimpleModuleInitializer;
+
+import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
+
+/**
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * <p>
+ * Extends Jackson's {@link JacksonXmlModule} for Log4j XML's specific needs.
+ * </p>
+ */
+final class Log4jXmlModule extends JacksonXmlModule {
+
+    private static final long serialVersionUID = 1L;
+    private final boolean includeStacktrace;
+    private final boolean stacktraceAsString;
+
+    Log4jXmlModule(final boolean includeStacktrace, final boolean 
stacktraceAsString) {
+        super();
+        this.includeStacktrace = includeStacktrace;
+        this.stacktraceAsString = stacktraceAsString;
+        // MUST init here.
+        // Calling this from setupModule is too late!
+        new SimpleModuleInitializer().initialize(this, false);
+    }
+
+    @Override
+    public void setupModule(final SetupContext context) {
+        // Calling super is a MUST!
+        super.setupModule(context);
+        new XmlSetupContextInitializer().setupModule(context, 
includeStacktrace, stacktraceAsString);
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlObjectMapper.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlObjectMapper.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlObjectMapper.java
new file mode 100644
index 0000000..ec802f4
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/Log4jXmlObjectMapper.java
@@ -0,0 +1,48 @@
+/*
+ * 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.jackson.xml;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+
+/**
+ * A Jackson XML {@link ObjectMapper} initialized for Log4j.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+public class Log4jXmlObjectMapper extends XmlMapper {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Create a new instance using the {@code Log4jXmlModule}.
+     */
+    public Log4jXmlObjectMapper() {
+        this(true, false);
+    }
+
+    /**
+     * Create a new instance using the {@code Log4jXmlModule}.
+     */
+    public Log4jXmlObjectMapper(final boolean includeStacktrace, final boolean 
stacktraceAsString) {
+        super(new Log4jXmlModule(includeStacktrace, stacktraceAsString));
+        this.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/LogEventWithContextListXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/LogEventWithContextListXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/LogEventWithContextListXmlMixIn.java
new file mode 100644
index 0000000..04f1d3d
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/LogEventWithContextListXmlMixIn.java
@@ -0,0 +1,48 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.jackson.ContextDataAsEntryListDeserializer;
+import org.apache.logging.log4j.jackson.XmlConstants;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+/**
+ * <pre>
+ * AbstractLogEventMixIn
+*├─ AbstractLogEventXmlMixIn
+*├──── LogEventWithContextListXmlMixIn
+*├──── LogEventWithContextMapXmlMixIn
+*├─ JsonLogEventMixIn
+*├──── JsonLogEventWithContextListMixIn
+*├──── JsonLogEventWithContextMapMixIn
+ * </pre>
+ */
+public abstract class LogEventWithContextListXmlMixIn extends 
AbstractLogEventXmlMixIn {
+
+    private static final long serialVersionUID = 1L;
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CONTEXT_MAP)
+    @JsonSerialize(using = ContextDataAsEntryListXmlSerializer.class)
+    @JsonDeserialize(using = ContextDataAsEntryListDeserializer.class)
+    @Override
+    public abstract ReadOnlyStringMap getContextData();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/MarkerXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/MarkerXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/MarkerXmlMixIn.java
new file mode 100644
index 0000000..a101ed5
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/MarkerXmlMixIn.java
@@ -0,0 +1,79 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.jackson.MarkerMixIn;
+import org.apache.logging.log4j.jackson.XmlConstants;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+/**
+ * Jackson mix-in for {@link Marker}.
+ * <p>
+ * If we want to deal with more than one {@link Marker} implementation then 
recode these annotations to include
+ * metadata.
+ * </p>
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ * <p>
+ * Example XML:
+ * </p>
+ *
+ * <pre>
+&lt;Marker name=&quot;Marker1&quot;&gt;
+    &lt;Parents&gt;
+        &lt;Marker name=&quot;ParentMarker1&quot;&gt;
+            &lt;Parents&gt;
+                &lt;Marker name=&quot;GrandMotherMarker&quot;/&gt;
+                &lt;Marker name=&quot;GrandFatherMarker&quot;/&gt;
+            &lt;/Parents&gt;
+        &lt;/Marker&gt;
+        &lt;Marker name=&quot;ParentMarker2&quot;/&gt;
+    &lt;/Parents&gt;
+&lt;/Marker&gt;
+ * </pre>
+ *
+ * @see Marker
+ */
+// Alternate for multiple Marker implementation.
+// @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = 
JsonTypeInfo.As.PROPERTY, property = "@class")
+@JsonDeserialize(as = org.apache.logging.log4j.MarkerManager.Log4jMarker.class)
+abstract class MarkerXmlMixIn extends MarkerMixIn {
+    public static final String ATTR_NAME = "name";
+    private static final long serialVersionUID = 1L;
+
+    @JsonCreator
+    protected MarkerXmlMixIn(@JsonProperty(ATTR_NAME) final String name) {
+        super(name);
+    }
+
+    @Override
+    @JacksonXmlProperty(isAttribute = true)
+    public abstract String getName();
+
+    @Override
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_PARENTS)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_MARKER)
+    public abstract Marker[] getParents();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
new file mode 100644
index 0000000..93a3a45
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
@@ -0,0 +1,40 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.jackson.StackTraceElementConstants;
+import org.apache.logging.log4j.jackson.StackTraceElementMixIn;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+abstract class StackTraceElementXmlMixIn extends StackTraceElementMixIn {
+
+    @JsonCreator
+    protected StackTraceElementXmlMixIn(
+    // @formatter:off
+            @JsonProperty(StackTraceElementConstants.ATTR_CLASS) final String 
declaringClass,
+            @JsonProperty(StackTraceElementConstants.ATTR_METHOD) final String 
methodName,
+            @JsonProperty(StackTraceElementConstants.ATTR_FILE) final String 
fileName,
+            @JsonProperty(StackTraceElementConstants.ATTR_LINE) final int 
lineNumber)
+    // @formatter:on
+    {
+        super(declaringClass, methodName, fileName, lineNumber);
+    }
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_CLASS, 
isAttribute = true)
+    protected abstract String getClassName();
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_FILE, 
isAttribute = true)
+    protected abstract String getFileName();
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_LINE, 
isAttribute = true)
+    protected abstract int getLineNumber();
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_METHOD, 
isAttribute = true)
+    protected abstract String getMethodName();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithStacktraceAsStringXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithStacktraceAsStringXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithStacktraceAsStringXmlMixIn.java
new file mode 100644
index 0000000..9cc85c3
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithStacktraceAsStringXmlMixIn.java
@@ -0,0 +1,77 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import 
org.apache.logging.log4j.jackson.ThrowableProxyWithStacktraceAsStringMixIn;
+import org.apache.logging.log4j.jackson.XmlConstants;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+public abstract class ThrowableProxyWithStacktraceAsStringXmlMixIn extends 
ThrowableProxyWithStacktraceAsStringMixIn {
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CAUSE)
+    private ThrowableProxyWithStacktraceAsStringMixIn causeProxy;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private int commonElementCount;
+
+    @JsonIgnore
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String localizedMessage;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String message;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @Override
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @Override
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_EXTENDED_STACK_TRACE)
+    public abstract String getExtendedStackTraceAsString();
+
+    @Override
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @Override
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_SUPPRESSED)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_SUPPRESSED_ITEM)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @Override
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @Override
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithoutStacktraceXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithoutStacktraceXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithoutStacktraceXmlMixIn.java
new file mode 100644
index 0000000..4ecffae
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyWithoutStacktraceXmlMixIn.java
@@ -0,0 +1,60 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.jackson.ThrowableProxyWithoutStacktraceMixIn;
+import org.apache.logging.log4j.jackson.XmlConstants;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+public abstract class ThrowableProxyWithoutStacktraceXmlMixIn extends 
ThrowableProxyWithoutStacktraceMixIn {
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CAUSE)
+    private ThrowableProxyWithoutStacktraceMixIn causeProxy;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private int commonElementCount;
+
+    @JsonIgnore
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String localizedMessage;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String message;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @Override
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @Override
+    @JsonIgnore
+    public abstract String getExtendedStackTraceAsString();
+
+    @Override
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @Override
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_SUPPRESSED)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_SUPPRESSED_ITEM)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @Override
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @Override
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyXmlMixIn.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyXmlMixIn.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyXmlMixIn.java
new file mode 100644
index 0000000..b52f7f6
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ThrowableProxyXmlMixIn.java
@@ -0,0 +1,78 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.jackson.ThrowableProxyMixIn;
+import org.apache.logging.log4j.jackson.XmlConstants;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import 
com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+public abstract class ThrowableProxyXmlMixIn extends ThrowableProxyMixIn {
+
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_CAUSE)
+    private ThrowableProxyMixIn causeProxy;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private int commonElementCount;
+
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_EXTENDED_STACK_TRACE)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_EXTENDED_STACK_TRACE_ITEM)
+    private ExtendedStackTraceElement[] extendedStackTrace;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String localizedMessage;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String message;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String name;
+
+    @JsonIgnore
+    private transient Throwable throwable;
+
+    @Override
+    @JsonIgnore
+    public abstract String getCauseStackTraceAsString();
+
+    @Override
+    @JsonIgnore
+    public abstract String getExtendedStackTraceAsString();
+
+    @Override
+    @JsonIgnore
+    public abstract StackTraceElement[] getStackTrace();
+
+    @Override
+    @JacksonXmlElementWrapper(namespace = XmlConstants.XML_NAMESPACE, 
localName = XmlConstants.ELT_SUPPRESSED)
+    @JacksonXmlProperty(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_SUPPRESSED_ITEM)
+    public abstract ThrowableProxy[] getSuppressedProxies();
+
+    @Override
+    @JsonIgnore
+    public abstract String getSuppressedStackTrace();
+
+    @Override
+    @JsonIgnore
+    public abstract Throwable getThrowable();
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlMapEntry.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlMapEntry.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlMapEntry.java
new file mode 100644
index 0000000..2500c11
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlMapEntry.java
@@ -0,0 +1,41 @@
+/*
+ * 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.jackson.xml;
+
+import org.apache.logging.log4j.jackson.MapEntry;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+
+@JsonPropertyOrder({ "key", "value" })
+class XmlMapEntry extends MapEntry {
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String key;
+
+    @JacksonXmlProperty(isAttribute = true)
+    private String value;
+
+    @JsonCreator
+    public XmlMapEntry(@JsonProperty("key") final String key, 
@JsonProperty("value") final String value) {
+        super(key, value);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
new file mode 100644
index 0000000..4cc5124
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/XmlSetupContextInitializer.java
@@ -0,0 +1,38 @@
+package org.apache.logging.log4j.jackson.xml;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.jackson.LevelMixIn;
+
+import com.fasterxml.jackson.databind.Module.SetupContext;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * Used to set up {@link SetupContext} from different {@link SimpleModule}s.
+ * <p>
+ * <em>Consider this class private.</em>
+ * </p>
+ */
+class XmlSetupContextInitializer {
+
+    public void setupModule(final SetupContext context, final boolean 
includeStacktrace,
+            final boolean stacktraceAsString) {
+        // JRE classes: we cannot edit those with Jackson annotations
+        context.setMixInAnnotations(StackTraceElement.class, 
StackTraceElementXmlMixIn.class);
+        // Log4j API classes: we do not want to edit those with Jackson 
annotations because the API module should not
+        // depend on Jackson.
+        context.setMixInAnnotations(Marker.class, MarkerXmlMixIn.class);
+        context.setMixInAnnotations(Level.class, LevelMixIn.class);
+        context.setMixInAnnotations(Instant.class, InstantXmlMixIn.class);
+        context.setMixInAnnotations(LogEvent.class, 
LogEventWithContextListXmlMixIn.class);
+        // Log4j Core classes: we do not want to bring in Jackson at runtime 
if we do not have to.
+        context.setMixInAnnotations(ExtendedStackTraceElement.class, 
ExtendedStackTraceElementXmlMixIn.class);
+        context.setMixInAnnotations(ThrowableProxy.class, includeStacktrace
+                ? (stacktraceAsString ? 
ThrowableProxyWithStacktraceAsStringXmlMixIn.class : 
ThrowableProxyXmlMixIn.class)
+                : ThrowableProxyWithoutStacktraceXmlMixIn.class);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
new file mode 100644
index 0000000..6956861
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/Log4jXmlPrettyPrinter.java
@@ -0,0 +1,41 @@
+package org.apache.logging.log4j.jackson.xml.layout;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.codehaus.stax2.XMLStreamWriter2;
+
+import com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter;
+
+/**
+ * When &lt;Event&gt;s are written into a XML file; the "Event" object is not 
the root element, but an element named
+ * &lt;Events&gt; created using {@link XmlLayout#getHeader()} and {@link 
XmlLayout#getFooter()} methods.
+ * <p>
+ * {@link com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter} 
is used to print the Event object into
+ * XML; hence it assumes &lt;Event&gt; tag as the root element, so it prints 
the &lt;Event&gt; tag without any
+ * indentation. To add an indentation to the &lt;Event&gt; tag; hence an 
additional indentation for any
+ * sub-elements, this class is written. As an additional task, to avoid the 
blank line printed after the ending
+ * &lt;/Event&gt; tag, the {@code #writePrologLinefeed(XMLStreamWriter2)} 
method is also overridden.
+ * </p>
+ */
+class Log4jXmlPrettyPrinter extends DefaultXmlPrettyPrinter {
+
+    private static final long serialVersionUID = 1L;
+
+    Log4jXmlPrettyPrinter(final int nesting) {
+        _nesting = nesting;
+    }
+
+    /**
+     * Sets the nesting level to 1 rather than 0, so the "Event" tag will get 
indentation of next level below root.
+     */
+    @Override
+    public DefaultXmlPrettyPrinter createInstance() {
+        return new Log4jXmlPrettyPrinter(XmlJacksonFactory.DEFAULT_INDENT);
+    }
+
+    @Override
+    public void writePrologLinefeed(final XMLStreamWriter2 sw) throws 
XMLStreamException {
+        // nothing
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
new file mode 100644
index 0000000..0cfba5b
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlJacksonFactory.java
@@ -0,0 +1,54 @@
+package org.apache.logging.log4j.jackson.xml.layout;
+
+import org.apache.logging.log4j.jackson.AbstractJacksonFactory;
+import org.apache.logging.log4j.jackson.JsonConstants;
+import org.apache.logging.log4j.jackson.XmlConstants;
+import org.apache.logging.log4j.jackson.xml.Log4jXmlObjectMapper;
+
+import com.fasterxml.jackson.core.PrettyPrinter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+class XmlJacksonFactory extends AbstractJacksonFactory {
+
+    static final int DEFAULT_INDENT = 1;
+
+    public XmlJacksonFactory(final boolean includeStacktrace, final boolean 
stacktraceAsString) {
+        super(includeStacktrace, stacktraceAsString);
+    }
+
+    @Override
+    protected String getPropertyNameForContextMap() {
+        return XmlConstants.ELT_CONTEXT_MAP;
+    }
+
+    @Override
+    protected String getPropertyNameForNanoTime() {
+        return JsonConstants.ELT_NANO_TIME;
+    }
+
+    @Override
+    protected String getPropertyNameForSource() {
+        return XmlConstants.ELT_SOURCE;
+    }
+
+    @Override
+    protected String getPropertyNameForStackTrace() {
+        return XmlConstants.ELT_EXTENDED_STACK_TRACE;
+    }
+
+    @Override
+    protected PrettyPrinter newCompactPrinter() {
+        // Yes, null is the proper answer.
+        return null;
+    }
+
+    @Override
+    protected ObjectMapper newObjectMapper() {
+        return new Log4jXmlObjectMapper(includeStacktrace, stacktraceAsString);
+    }
+
+    @Override
+    protected PrettyPrinter newPrettyPrinter() {
+        return new Log4jXmlPrettyPrinter(DEFAULT_INDENT);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0eb5212e/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
----------------------------------------------------------------------
diff --git 
a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
new file mode 100644
index 0000000..6d723b0
--- /dev/null
+++ 
b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayout.java
@@ -0,0 +1,226 @@
+/*
+ * 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.jackson.xml.layout;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
+import org.apache.logging.log4j.core.util.KeyValuePair;
+import org.apache.logging.log4j.jackson.AbstractJacksonLayout;
+import org.apache.logging.log4j.jackson.XmlConstants;
+
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+
+/**
+ * Appends a series of {@code event} elements as defined in the <a 
href="log4j.dtd">log4j.dtd</a>.
+ *
+ * <h3>Complete well-formed XML vs. fragment XML</h3>
+ * <p>
+ * If you configure {@code complete="true"}, the appender outputs a 
well-formed XML document where the default namespace
+ * is the log4j namespace {@value XmlConstants#XML_NAMESPACE}. By default, 
with {@code complete="false"}, you should
+ * include the output as an <em>external entity</em> in a separate file to 
form a well-formed XML document.
+ * </p>
+ * <p>
+ * If {@code complete="false"}, the appender does not write the XML processing 
instruction and the root element.
+ * </p>
+ * <h3>Encoding</h3>
+ * <p>
+ * Appenders using this layout should have their {@code charset} set to {@code 
UTF-8} or {@code UTF-16}, otherwise
+ * events containing non-ASCII characters could result in corrupted log files.
+ * </p>
+ * <h3>Pretty vs. compact XML</h3>
+ * <p>
+ * By default, the XML layout is not compact (compact = not "pretty") with 
{@code compact="false"}, which means the
+ * appender uses end-of-line characters and indents lines to format the XML. 
If {@code compact="true"}, then no
+ * end-of-line or indentation is used. Message content may contain, of course, 
end-of-lines.
+ * </p>
+ * <h3>Additional Fields</h3>
+ * <p>
+ * This property allows addition of custom fields into generated JSON.
+ * {@code <XmlLayout><KeyValuePair key="foo" value="bar"/></XmlLayout>} 
inserts {@code <foo>bar</foo>} directly into XML
+ * output. Supports Lookup expressions.
+ * </p>
+ */
+@Plugin(name = "XmlLayout", category = Node.CATEGORY, elementType = 
Layout.ELEMENT_TYPE, printObject = true)
+public final class XmlLayout extends AbstractJacksonLayout {
+
+    public static class Builder<B extends Builder<B>> extends 
AbstractJacksonLayout.Builder<B>
+            implements org.apache.logging.log4j.core.util.Builder<XmlLayout> {
+
+        public Builder() {
+            super();
+            setCharset(StandardCharsets.UTF_8);
+        }
+
+        @Override
+        public XmlLayout build() {
+            return new XmlLayout(getConfiguration(), isLocationInfo(), 
isProperties(), isComplete(), isCompact(),
+                    getCharset(), isIncludeStacktrace(), 
isStacktraceAsString(), isIncludeNullDelimiter(),
+                    getAdditionalFields());
+        }
+    }
+
+    @JacksonXmlRootElement(namespace = XmlConstants.XML_NAMESPACE, localName = 
XmlConstants.ELT_EVENT)
+    public static class XmlLogEventWithAdditionalFields extends 
LogEventWithAdditionalFields {
+
+        public XmlLogEventWithAdditionalFields(final Object logEvent, final 
Map<String, String> additionalFields) {
+            super(logEvent, additionalFields);
+        }
+
+    }
+
+    private static final String ROOT_TAG = "Events";
+
+    /**
+     * Creates an XML Layout using the default settings.
+     *
+     * @return an XML Layout.
+     */
+    public static XmlLayout createDefaultLayout() {
+        return new XmlLayout(null, false, false, false, false, 
StandardCharsets.UTF_8, true, false, false, null);
+    }
+
+    /**
+     * Creates an XML Layout.
+     *
+     * @param locationInfo
+     *            If "true", includes the location information in the 
generated XML.
+     * @param properties
+     *            If "true", includes the thread context map in the generated 
XML.
+     * @param complete
+     *            If "true", includes the XML header and footer, defaults to 
"false".
+     * @param compact
+     *            If "true", does not use end-of-lines and indentation, 
defaults to "false".
+     * @param charset
+     *            The character set to use, if {@code null}, uses "UTF-8".
+     * @param includeStacktrace
+     *            If "true", includes the stacktrace of any Throwable in the 
generated XML, defaults to "true".
+     * @return An XML Layout.
+     *
+     * @deprecated Use {@link #newBuilder()} instead
+     */
+    @Deprecated
+    public static XmlLayout createLayout(final boolean locationInfo, final 
boolean properties, final boolean complete,
+            final boolean compact, final Charset charset, final boolean 
includeStacktrace) {
+        return new XmlLayout(null, locationInfo, properties, complete, 
compact, charset, includeStacktrace, false,
+                false, null);
+    }
+
+    @PluginBuilderFactory
+    public static <B extends Builder<B>> B newBuilder() {
+        return new Builder<B>().asBuilder();
+    }
+
+    /**
+     * @deprecated Use {@link #newBuilder()} instead
+     */
+    @Deprecated
+    protected XmlLayout(final boolean locationInfo, final boolean properties, 
final boolean complete,
+            final boolean compact, final Charset charset, final boolean 
includeStacktrace) {
+        this(null, locationInfo, properties, complete, compact, charset, 
includeStacktrace, false, false, null);
+    }
+
+    private XmlLayout(final Configuration config, final boolean locationInfo, 
final boolean properties,
+            final boolean complete, final boolean compact, final Charset 
charset, final boolean includeStacktrace,
+            final boolean stacktraceAsString, final boolean 
includeNullDelimiter,
+            final KeyValuePair[] additionalFields) {
+        super(config,
+                new XmlJacksonFactory(includeStacktrace, 
stacktraceAsString).newWriter(locationInfo, properties,
+                        compact),
+                charset, compact, complete, false, null, null, 
includeNullDelimiter, additionalFields);
+    }
+
+    @Override
+    protected LogEventWithAdditionalFields 
createLogEventWithAdditionalFields(final LogEvent event,
+            final Map<String, String> additionalFieldsMap) {
+        return new XmlLogEventWithAdditionalFields(event, additionalFieldsMap);
+    }
+
+    /**
+     * Gets this XmlLayout's content format. Specified by:
+     * <ul>
+     * <li>Key: "dtd" Value: "log4j-events.dtd"</li>
+     * <li>Key: "version" Value: "2.0"</li>
+     * </ul>
+     *
+     * @return Map of content format keys supporting XmlLayout
+     */
+    @Override
+    public Map<String, String> getContentFormat() {
+        final Map<String, String> result = new HashMap<>();
+        // result.put("dtd", "log4j-events.dtd");
+        result.put("xsd", "log4j-events.xsd");
+        result.put("version", "2.0");
+        return result;
+    }
+
+    /**
+     * @return The content type.
+     */
+    @Override
+    public String getContentType() {
+        return "text/xml; charset=" + this.getCharset();
+    }
+
+    /**
+     * Returns appropriate XML footer.
+     *
+     * @return a byte array containing the footer, closing the XML root 
element.
+     */
+    @Override
+    public byte[] getFooter() {
+        if (!complete) {
+            return null;
+        }
+        return getBytes("</" + ROOT_TAG + '>' + this.eol);
+    }
+
+    /**
+     * Returns appropriate XML headers.
+     * <ol>
+     * <li>XML processing instruction</li>
+     * <li>XML root element</li>
+     * </ol>
+     *
+     * @return a byte array containing the header.
+     */
+    @Override
+    public byte[] getHeader() {
+        if (!complete) {
+            return null;
+        }
+        final StringBuilder buf = new StringBuilder();
+        buf.append("<?xml version=\"1.0\" encoding=\"");
+        buf.append(this.getCharset().name());
+        buf.append("\"?>");
+        buf.append(this.eol);
+        // Make the log4j namespace the default namespace, no need to use more 
space with a namespace prefix.
+        buf.append('<');
+        buf.append(ROOT_TAG);
+        buf.append(" xmlns=\"" + XmlConstants.XML_NAMESPACE + "\">");
+        buf.append(this.eol);
+        return buf.toString().getBytes(this.getCharset());
+    }
+}

Reply via email to