Browse Source

Upgrade Log4j 2 to version 2.7

This commit upgrades the Log4j 2 dependency to version 2.7 and removes
some hacks that we had in place to work around bugs in Log4j 2 version
2.6.2.

Relates #20805
Jason Tedor 9 years ago
parent
commit
535bf92280

+ 1 - 1
buildSrc/version.properties

@@ -6,7 +6,7 @@ spatial4j         = 0.6
 jts               = 1.13
 jackson           = 2.8.1
 snakeyaml         = 1.15
-log4j             = 2.6.2
+log4j             = 2.7
 slf4j             = 1.6.2
 jna               = 4.2.2
 

+ 10 - 0
core/build.gradle

@@ -158,6 +158,10 @@ thirdPartyAudit.excludes = [
   'com.fasterxml.jackson.databind.ObjectMapper',
 
   // from log4j
+  'com.beust.jcommander.IStringConverter',
+  'com.beust.jcommander.JCommander',
+  'com.conversantmedia.util.concurrent.DisruptorBlockingQueue',
+  'com.conversantmedia.util.concurrent.SpinPolicy',
   'com.fasterxml.jackson.annotation.JsonInclude$Include',
   'com.fasterxml.jackson.databind.DeserializationContext',
   'com.fasterxml.jackson.databind.JsonMappingException',
@@ -176,6 +180,10 @@ thirdPartyAudit.excludes = [
   'com.fasterxml.jackson.dataformat.xml.JacksonXmlModule',
   'com.fasterxml.jackson.dataformat.xml.XmlMapper',
   'com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter',
+  'com.fasterxml.jackson.databind.node.JsonNodeFactory',
+  'com.fasterxml.jackson.databind.node.ObjectNode',
+  'org.fusesource.jansi.Ansi',
+  'org.fusesource.jansi.AnsiRenderer$Code',
   'com.lmax.disruptor.BlockingWaitStrategy',
   'com.lmax.disruptor.BusySpinWaitStrategy',
   'com.lmax.disruptor.EventFactory',
@@ -228,6 +236,8 @@ thirdPartyAudit.excludes = [
   'org.apache.kafka.clients.producer.Producer',
   'org.apache.kafka.clients.producer.ProducerRecord',
   'org.codehaus.stax2.XMLStreamWriter2',
+  'org.jctools.queues.MessagePassingQueue$Consumer',
+  'org.jctools.queues.MpscArrayQueue',
   'org.osgi.framework.AdaptPermission',
   'org.osgi.framework.AdminPermission',
   'org.osgi.framework.Bundle',

+ 0 - 665
core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableProxy.java

@@ -1,665 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-package org.apache.logging.log4j.core.impl;
-
-import java.io.Serializable;
-import java.net.URL;
-import java.security.CodeSource;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-
-import org.apache.logging.log4j.core.util.Loader;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.ReflectionUtil;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * Wraps a Throwable to add packaging information about each stack trace element.
- *
- * <p>
- * A proxy is used to represent a throwable that may not exist in a different class loader or JVM. When an application
- * deserializes a ThrowableProxy, the throwable may not be set, but the throwable's information is preserved in other
- * fields of the proxy like the message and stack trace.
- * </p>
- *
- * <p>
- * TODO: Move this class to org.apache.logging.log4j.core because it is used from LogEvent.
- * </p>
- * <p>
- * TODO: Deserialize: Try to rebuild Throwable if the target exception is in this class loader?
- * </p>
- */
-public class ThrowableProxy implements Serializable {
-
-    private static final String CAUSED_BY_LABEL = "Caused by: ";
-    private static final String SUPPRESSED_LABEL = "Suppressed: ";
-    private static final String WRAPPED_BY_LABEL = "Wrapped by: ";
-
-    /**
-     * Cached StackTracePackageElement and ClassLoader.
-     * <p>
-     * Consider this class private.
-     * </p>
-     */
-    static class CacheEntry {
-        private final ExtendedClassInfo element;
-        private final ClassLoader loader;
-
-        public CacheEntry(final ExtendedClassInfo element, final ClassLoader loader) {
-            this.element = element;
-            this.loader = loader;
-        }
-    }
-
-    private static final ThrowableProxy[] EMPTY_THROWABLE_PROXY_ARRAY = new ThrowableProxy[0];
-
-    private static final char EOL = '\n';
-
-    private static final long serialVersionUID = -2752771578252251910L;
-
-    private final ThrowableProxy causeProxy;
-
-    private int commonElementCount;
-
-    private final ExtendedStackTraceElement[] extendedStackTrace;
-
-    private final String localizedMessage;
-
-    private final String message;
-
-    private final String name;
-
-    private final ThrowableProxy[] suppressedProxies;
-
-    private final transient Throwable throwable;
-
-    /**
-     * For JSON and XML IO via Jackson.
-     */
-    @SuppressWarnings("unused")
-    private ThrowableProxy() {
-        this.throwable = null;
-        this.name = null;
-        this.extendedStackTrace = null;
-        this.causeProxy = null;
-        this.message = null;
-        this.localizedMessage = null;
-        this.suppressedProxies = EMPTY_THROWABLE_PROXY_ARRAY;
-    }
-
-    /**
-     * Constructs the wrapper for the Throwable that includes packaging data.
-     *
-     * @param throwable
-     *        The Throwable to wrap, must not be null.
-     */
-    public ThrowableProxy(final Throwable throwable) {
-        this(throwable, null);
-    }
-
-    /**
-     * Constructs the wrapper for the Throwable that includes packaging data.
-     *
-     * @param throwable
-     *        The Throwable to wrap, must not be null.
-     * @param visited
-     *        The set of visited suppressed exceptions.
-     */
-    private ThrowableProxy(final Throwable throwable, final Set<Throwable> visited) {
-        this.throwable = throwable;
-        this.name = throwable.getClass().getName();
-        this.message = throwable.getMessage();
-        this.localizedMessage = throwable.getLocalizedMessage();
-        final Map<String, CacheEntry> map = new HashMap<>();
-        final Stack<Class<?>> stack = ReflectionUtil.getCurrentStackTrace();
-        this.extendedStackTrace = this.toExtendedStackTrace(stack, map, null, throwable.getStackTrace());
-        final Throwable throwableCause = throwable.getCause();
-        final Set<Throwable> causeVisited = new HashSet<>(1);
-        this.causeProxy = throwableCause == null ? null : new ThrowableProxy(throwable, stack, map, throwableCause, visited, causeVisited);
-        this.suppressedProxies = this.toSuppressedProxies(throwable, visited);
-    }
-
-    /**
-     * Constructs the wrapper for a Throwable that is referenced as the cause by another Throwable.
-     *
-     * @param parent
-     *        The Throwable referencing this Throwable.
-     * @param stack
-     *        The Class stack.
-     * @param map
-     *        The cache containing the packaging data.
-     * @param cause
-     *        The Throwable to wrap.
-     * @param suppressedVisited TODO
-     * @param causeVisited TODO
-     */
-    private ThrowableProxy(final Throwable parent, final Stack<Class<?>> stack, final Map<String, CacheEntry> map,
-                           final Throwable cause, final Set<Throwable> suppressedVisited, final Set<Throwable> causeVisited) {
-        causeVisited.add(cause);
-        this.throwable = cause;
-        this.name = cause.getClass().getName();
-        this.message = this.throwable.getMessage();
-        this.localizedMessage = this.throwable.getLocalizedMessage();
-        this.extendedStackTrace = this.toExtendedStackTrace(stack, map, parent.getStackTrace(), cause.getStackTrace());
-        final Throwable causeCause = cause.getCause();
-        this.causeProxy = causeCause == null || causeVisited.contains(causeCause) ? null : new ThrowableProxy(parent,
-            stack, map, causeCause, suppressedVisited, causeVisited);
-        this.suppressedProxies = this.toSuppressedProxies(cause, suppressedVisited);
-    }
-
-    @Override
-    public boolean equals(final Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (this.getClass() != obj.getClass()) {
-            return false;
-        }
-        final ThrowableProxy other = (ThrowableProxy) obj;
-        if (this.causeProxy == null) {
-            if (other.causeProxy != null) {
-                return false;
-            }
-        } else if (!this.causeProxy.equals(other.causeProxy)) {
-            return false;
-        }
-        if (this.commonElementCount != other.commonElementCount) {
-            return false;
-        }
-        if (this.name == null) {
-            if (other.name != null) {
-                return false;
-            }
-        } else if (!this.name.equals(other.name)) {
-            return false;
-        }
-        if (!Arrays.equals(this.extendedStackTrace, other.extendedStackTrace)) {
-            return false;
-        }
-        if (!Arrays.equals(this.suppressedProxies, other.suppressedProxies)) {
-            return false;
-        }
-        return true;
-    }
-
-    private void formatCause(final StringBuilder sb, final String prefix, final ThrowableProxy cause, final List<String> ignorePackages) {
-        formatThrowableProxy(sb, prefix, CAUSED_BY_LABEL, cause, ignorePackages);
-    }
-
-    private void formatThrowableProxy(final StringBuilder sb, final String prefix, final String causeLabel,
-                                      final ThrowableProxy throwableProxy, final List<String> ignorePackages) {
-        if (throwableProxy == null) {
-            return;
-        }
-        sb.append(prefix).append(causeLabel).append(throwableProxy).append(EOL);
-        this.formatElements(sb, prefix, throwableProxy.commonElementCount,
-            throwableProxy.getStackTrace(), throwableProxy.extendedStackTrace, ignorePackages);
-        this.formatSuppressed(sb, prefix + "\t", throwableProxy.suppressedProxies, ignorePackages);
-        this.formatCause(sb, prefix, throwableProxy.causeProxy, ignorePackages);
-    }
-
-    private void formatSuppressed(final StringBuilder sb, final String prefix, final ThrowableProxy[] suppressedProxies,
-                                  final List<String> ignorePackages) {
-        if (suppressedProxies == null) {
-            return;
-        }
-        for (final ThrowableProxy suppressedProxy : suppressedProxies) {
-            final ThrowableProxy cause = suppressedProxy;
-            formatThrowableProxy(sb, prefix, SUPPRESSED_LABEL, cause, ignorePackages);
-        }
-    }
-
-    private void formatElements(final StringBuilder sb, final String prefix, final int commonCount,
-                                final StackTraceElement[] causedTrace, final ExtendedStackTraceElement[] extStackTrace,
-                                final List<String> ignorePackages) {
-        if (ignorePackages == null || ignorePackages.isEmpty()) {
-            for (final ExtendedStackTraceElement element : extStackTrace) {
-                this.formatEntry(element, sb, prefix);
-            }
-        } else {
-            int count = 0;
-            for (int i = 0; i < extStackTrace.length; ++i) {
-                if (!this.ignoreElement(causedTrace[i], ignorePackages)) {
-                    if (count > 0) {
-                        appendSuppressedCount(sb, prefix, count);
-                        count = 0;
-                    }
-                    this.formatEntry(extStackTrace[i], sb, prefix);
-                } else {
-                    ++count;
-                }
-            }
-            if (count > 0) {
-                appendSuppressedCount(sb, prefix, count);
-            }
-        }
-        if (commonCount != 0) {
-            sb.append(prefix).append("\t... ").append(commonCount).append(" more").append(EOL);
-        }
-    }
-
-    private void appendSuppressedCount(final StringBuilder sb, final String prefix, final int count) {
-        sb.append(prefix);
-        if (count == 1) {
-            sb.append("\t....").append(EOL);
-        } else {
-            sb.append("\t... suppressed ").append(count).append(" lines").append(EOL);
-        }
-    }
-
-    private void formatEntry(final ExtendedStackTraceElement extStackTraceElement, final StringBuilder sb, final String prefix) {
-        sb.append(prefix);
-        sb.append("\tat ");
-        sb.append(extStackTraceElement);
-        sb.append(EOL);
-    }
-
-    /**
-     * Formats the specified Throwable.
-     *
-     * @param sb
-     *        StringBuilder to contain the formatted Throwable.
-     * @param cause
-     *        The Throwable to format.
-     */
-    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause) {
-        this.formatWrapper(sb, cause, null);
-    }
-
-    /**
-     * Formats the specified Throwable.
-     *
-     * @param sb
-     *        StringBuilder to contain the formatted Throwable.
-     * @param cause
-     *        The Throwable to format.
-     * @param packages
-     *        The List of packages to be suppressed from the trace.
-     */
-    @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-    public void formatWrapper(final StringBuilder sb, final ThrowableProxy cause, final List<String> packages) {
-        final Throwable caused = cause.getCauseProxy() != null ? cause.getCauseProxy().getThrowable() : null;
-        if (caused != null) {
-            this.formatWrapper(sb, cause.causeProxy);
-            sb.append(WRAPPED_BY_LABEL);
-        }
-        sb.append(cause).append(EOL);
-        this.formatElements(sb, "", cause.commonElementCount,
-            cause.getThrowable().getStackTrace(), cause.extendedStackTrace, packages);
-    }
-
-    public ThrowableProxy getCauseProxy() {
-        return this.causeProxy;
-    }
-
-    /**
-     * Format the Throwable that is the cause of this Throwable.
-     *
-     * @return The formatted Throwable that caused this Throwable.
-     */
-    public String getCauseStackTraceAsString() {
-        return this.getCauseStackTraceAsString(null);
-    }
-
-    /**
-     * Format the Throwable that is the cause of this Throwable.
-     *
-     * @param packages
-     *        The List of packages to be suppressed from the trace.
-     * @return The formatted Throwable that caused this Throwable.
-     */
-    public String getCauseStackTraceAsString(final List<String> packages) {
-        final StringBuilder sb = new StringBuilder();
-        if (this.causeProxy != null) {
-            this.formatWrapper(sb, this.causeProxy);
-            sb.append(WRAPPED_BY_LABEL);
-        }
-        sb.append(this.toString());
-        sb.append(EOL);
-        this.formatElements(sb, "", 0, this.throwable.getStackTrace(), this.extendedStackTrace, packages);
-        return sb.toString();
-    }
-
-    /**
-     * Return the number of elements that are being omitted because they are common with the parent Throwable's stack
-     * trace.
-     *
-     * @return The number of elements omitted from the stack trace.
-     */
-    public int getCommonElementCount() {
-        return this.commonElementCount;
-    }
-
-    /**
-     * Gets the stack trace including packaging information.
-     *
-     * @return The stack trace including packaging information.
-     */
-    public ExtendedStackTraceElement[] getExtendedStackTrace() {
-        return this.extendedStackTrace;
-    }
-
-    /**
-     * Format the stack trace including packaging information.
-     *
-     * @return The formatted stack trace including packaging information.
-     */
-    public String getExtendedStackTraceAsString() {
-        return this.getExtendedStackTraceAsString(null);
-    }
-
-    /**
-     * Format the stack trace including packaging information.
-     *
-     * @param ignorePackages
-     *        List of packages to be ignored in the trace.
-     * @return The formatted stack trace including packaging information.
-     */
-    public String getExtendedStackTraceAsString(final List<String> ignorePackages) {
-        final StringBuilder sb = new StringBuilder(this.name);
-        final String msg = this.message;
-        if (msg != null) {
-            sb.append(": ").append(msg);
-        }
-        sb.append(EOL);
-        final StackTraceElement[] causedTrace = this.throwable != null ? this.throwable.getStackTrace() : null;
-        this.formatElements(sb, "", 0, causedTrace, this.extendedStackTrace, ignorePackages);
-        this.formatSuppressed(sb, "\t", this.suppressedProxies, ignorePackages);
-        this.formatCause(sb, "", this.causeProxy, ignorePackages);
-        return sb.toString();
-    }
-
-    public String getLocalizedMessage() {
-        return this.localizedMessage;
-    }
-
-    public String getMessage() {
-        return this.message;
-    }
-
-    /**
-     * Return the FQCN of the Throwable.
-     *
-     * @return The FQCN of the Throwable.
-     */
-    public String getName() {
-        return this.name;
-    }
-
-    public StackTraceElement[] getStackTrace() {
-        return this.throwable == null ? null : this.throwable.getStackTrace();
-    }
-
-    /**
-     * Gets proxies for suppressed exceptions.
-     *
-     * @return proxies for suppressed exceptions.
-     */
-    public ThrowableProxy[] getSuppressedProxies() {
-        return this.suppressedProxies;
-    }
-
-    /**
-     * Format the suppressed Throwables.
-     *
-     * @return The formatted suppressed Throwables.
-     */
-    public String getSuppressedStackTrace() {
-        final ThrowableProxy[] suppressed = this.getSuppressedProxies();
-        if (suppressed == null || suppressed.length == 0) {
-            return Strings.EMPTY;
-        }
-        final StringBuilder sb = new StringBuilder("Suppressed Stack Trace Elements:").append(EOL);
-        for (final ThrowableProxy proxy : suppressed) {
-            sb.append(proxy.getExtendedStackTraceAsString());
-        }
-        return sb.toString();
-    }
-
-    /**
-     * The throwable or null if this object is deserialized from XML or JSON.
-     *
-     * @return The throwable or null if this object is deserialized from XML or JSON.
-     */
-    public Throwable getThrowable() {
-        return this.throwable;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + (this.causeProxy == null ? 0 : this.causeProxy.hashCode());
-        result = prime * result + this.commonElementCount;
-        result = prime * result + (this.extendedStackTrace == null ? 0 : Arrays.hashCode(this.extendedStackTrace));
-        result = prime * result + (this.suppressedProxies == null ? 0 : Arrays.hashCode(this.suppressedProxies));
-        result = prime * result + (this.name == null ? 0 : this.name.hashCode());
-        return result;
-    }
-
-    private boolean ignoreElement(final StackTraceElement element, final List<String> ignorePackages) {
-        final String className = element.getClassName();
-        for (final String pkg : ignorePackages) {
-            if (className.startsWith(pkg)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Loads classes not located via Reflection.getCallerClass.
-     *
-     * @param lastLoader
-     *        The ClassLoader that loaded the Class that called this Class.
-     * @param className
-     *        The name of the Class.
-     * @return The Class object for the Class or null if it could not be located.
-     */
-    private Class<?> loadClass(final ClassLoader lastLoader, final String className) {
-        // XXX: this is overly complicated
-        Class<?> clazz;
-        if (lastLoader != null) {
-            try {
-                clazz = Loader.initializeClass(className, lastLoader);
-                if (clazz != null) {
-                    return clazz;
-                }
-            } catch (final Throwable ignore) {
-                // Ignore exception.
-            }
-        }
-        try {
-            clazz = Loader.loadClass(className);
-        } catch (final ClassNotFoundException ignored) {
-            return initializeClass(className);
-        } catch (final NoClassDefFoundError ignored) {
-            return initializeClass(className);
-        } catch (final SecurityException ignored) {
-            return initializeClass(className);
-        }
-        return clazz;
-    }
-
-    private Class<?> initializeClass(final String className) {
-        try {
-            return Loader.initializeClass(className, this.getClass().getClassLoader());
-        } catch (final ClassNotFoundException ignore) {
-            return null;
-        } catch (final NoClassDefFoundError ignore) {
-            return null;
-        } catch (final SecurityException ignore) {
-            return null;
-        }
-    }
-
-    /**
-     * Construct the CacheEntry from the Class's information.
-     *
-     * @param stackTraceElement
-     *        The stack trace element
-     * @param callerClass
-     *        The Class.
-     * @param exact
-     *        True if the class was obtained via Reflection.getCallerClass.
-     *
-     * @return The CacheEntry.
-     */
-    private CacheEntry toCacheEntry(final StackTraceElement stackTraceElement, final Class<?> callerClass,
-                                    final boolean exact) {
-        String location = "?";
-        String version = "?";
-        ClassLoader lastLoader = null;
-        if (callerClass != null) {
-            try {
-                final CodeSource source = callerClass.getProtectionDomain().getCodeSource();
-                if (source != null) {
-                    final URL locationURL = source.getLocation();
-                    if (locationURL != null) {
-                        final String str = locationURL.toString().replace('\\', '/');
-                        int index = str.lastIndexOf("/");
-                        if (index >= 0 && index == str.length() - 1) {
-                            index = str.lastIndexOf("/", index - 1);
-                            location = str.substring(index + 1);
-                        } else {
-                            location = str.substring(index + 1);
-                        }
-                    }
-                }
-            } catch (final Exception ex) {
-                // Ignore the exception.
-            }
-            final Package pkg = callerClass.getPackage();
-            if (pkg != null) {
-                final String ver = pkg.getImplementationVersion();
-                if (ver != null) {
-                    version = ver;
-                }
-            }
-            lastLoader = callerClass.getClassLoader();
-        }
-        return new CacheEntry(new ExtendedClassInfo(exact, location, version), lastLoader);
-    }
-
-    /**
-     * Resolve all the stack entries in this stack trace that are not common with the parent.
-     *
-     * @param stack
-     *        The callers Class stack.
-     * @param map
-     *        The cache of CacheEntry objects.
-     * @param rootTrace
-     *        The first stack trace resolve or null.
-     * @param stackTrace
-     *        The stack trace being resolved.
-     * @return The StackTracePackageElement array.
-     */
-    ExtendedStackTraceElement[] toExtendedStackTrace(final Stack<Class<?>> stack, final Map<String, CacheEntry> map,
-                                                     final StackTraceElement[] rootTrace, final StackTraceElement[] stackTrace) {
-        int stackLength;
-        if (rootTrace != null) {
-            int rootIndex = rootTrace.length - 1;
-            int stackIndex = stackTrace.length - 1;
-            while (rootIndex >= 0 && stackIndex >= 0 && rootTrace[rootIndex].equals(stackTrace[stackIndex])) {
-                --rootIndex;
-                --stackIndex;
-            }
-            this.commonElementCount = stackTrace.length - 1 - stackIndex;
-            stackLength = stackIndex + 1;
-        } else {
-            this.commonElementCount = 0;
-            stackLength = stackTrace.length;
-        }
-        final ExtendedStackTraceElement[] extStackTrace = new ExtendedStackTraceElement[stackLength];
-        Class<?> clazz = stack.isEmpty() ? null : stack.peek();
-        ClassLoader lastLoader = null;
-        for (int i = stackLength - 1; i >= 0; --i) {
-            final StackTraceElement stackTraceElement = stackTrace[i];
-            final String className = stackTraceElement.getClassName();
-            // The stack returned from getCurrentStack may be missing entries for java.lang.reflect.Method.invoke()
-            // and its implementation. The Throwable might also contain stack entries that are no longer
-            // present as those methods have returned.
-            ExtendedClassInfo extClassInfo;
-            if (clazz != null && className.equals(clazz.getName())) {
-                final CacheEntry entry = this.toCacheEntry(stackTraceElement, clazz, true);
-                extClassInfo = entry.element;
-                lastLoader = entry.loader;
-                stack.pop();
-                clazz = stack.isEmpty() ? null : stack.peek();
-            } else {
-                final CacheEntry cacheEntry = map.get(className);
-                if (cacheEntry != null) {
-                    final CacheEntry entry = cacheEntry;
-                    extClassInfo = entry.element;
-                    if (entry.loader != null) {
-                        lastLoader = entry.loader;
-                    }
-                } else {
-                    final CacheEntry entry = this.toCacheEntry(stackTraceElement,
-                        this.loadClass(lastLoader, className), false);
-                    extClassInfo = entry.element;
-                    map.put(stackTraceElement.toString(), entry);
-                    if (entry.loader != null) {
-                        lastLoader = entry.loader;
-                    }
-                }
-            }
-            extStackTrace[i] = new ExtendedStackTraceElement(stackTraceElement, extClassInfo);
-        }
-        return extStackTrace;
-    }
-
-    @Override
-    public String toString() {
-        final String msg = this.message;
-        return msg != null ? this.name + ": " + msg : this.name;
-    }
-
-    private ThrowableProxy[] toSuppressedProxies(final Throwable thrown, Set<Throwable> suppressedVisited) {
-        try {
-            final Throwable[] suppressed = thrown.getSuppressed();
-            if (suppressed == null) {
-                return EMPTY_THROWABLE_PROXY_ARRAY;
-            }
-            final List<ThrowableProxy> proxies = new ArrayList<>(suppressed.length);
-            if (suppressedVisited == null) {
-                suppressedVisited = new HashSet<>(proxies.size());
-            }
-            for (int i = 0; i < suppressed.length; i++) {
-                final Throwable candidate = suppressed[i];
-                if (!suppressedVisited.contains(candidate)) {
-                    suppressedVisited.add(candidate);
-                    proxies.add(new ThrowableProxy(candidate, suppressedVisited));
-                }
-            }
-            return proxies.toArray(new ThrowableProxy[proxies.size()]);
-        } catch (final Exception e) {
-            StatusLogger.getLogger().error(e);
-        }
-        return null;
-    }
-}

+ 0 - 392
core/src/main/java/org/apache/logging/log4j/core/jmx/Server.java

@@ -1,392 +0,0 @@
-/*
- * 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.jmx;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.NotCompliantMBeanException;
-import javax.management.ObjectName;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.appender.AsyncAppender;
-import org.apache.logging.log4j.core.async.AsyncLoggerConfig;
-import org.apache.logging.log4j.core.async.AsyncLoggerContext;
-import org.apache.logging.log4j.core.async.DaemonThreadFactory;
-import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.core.impl.Log4jContextFactory;
-import org.apache.logging.log4j.core.selector.ContextSelector;
-import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.spi.LoggerContextFactory;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.elasticsearch.common.SuppressForbidden;
-
-/**
- * Creates MBeans to instrument various classes in the log4j class hierarchy.
- * <p>
- * All instrumentation for Log4j 2 classes can be disabled by setting system property {@code -Dlog4j2.disable.jmx=true}.
- * </p>
- */
-@SuppressForbidden(reason = "copied class to hack around Log4j bug")
-public final class Server {
-
-    /**
-     * The domain part, or prefix ({@value}) of the {@code ObjectName} of all MBeans that instrument Log4J2 components.
-     */
-    public static final String DOMAIN = "org.apache.logging.log4j2";
-    private static final String PROPERTY_DISABLE_JMX = "log4j2.disable.jmx";
-    private static final String PROPERTY_ASYNC_NOTIF = "log4j2.jmx.notify.async";
-    private static final String THREAD_NAME_PREFIX = "log4j2.jmx.notif";
-    private static final StatusLogger LOGGER = StatusLogger.getLogger();
-    static final Executor executor = isJmxDisabled() ? null : createExecutor();
-
-    private Server() {
-    }
-
-    /**
-     * Returns either a {@code null} Executor (causing JMX notifications to be sent from the caller thread) or a daemon
-     * background thread Executor, depending on the value of system property "log4j2.jmx.notify.async". If this
-     * property is not set, use a {@code null} Executor for web apps to avoid memory leaks and other issues when the
-     * web app is restarted.
-     * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-938">LOG4J2-938</a>
-     */
-    private static ExecutorService createExecutor() {
-        final boolean defaultAsync = !Constants.IS_WEB_APP;
-        final boolean async = PropertiesUtil.getProperties().getBooleanProperty(PROPERTY_ASYNC_NOTIF, defaultAsync);
-        return async ? Executors.newFixedThreadPool(1, new DaemonThreadFactory(THREAD_NAME_PREFIX)) : null;
-    }
-
-    /**
-     * Either returns the specified name as is, or returns a quoted value containing the specified name with the special
-     * characters (comma, equals, colon, quote, asterisk, or question mark) preceded with a backslash.
-     *
-     * @param name the name to escape so it can be used as a value in an {@link ObjectName}.
-     * @return the escaped name
-     */
-    public static String escape(final String name) {
-        final StringBuilder sb = new StringBuilder(name.length() * 2);
-        boolean needsQuotes = false;
-        for (int i = 0; i < name.length(); i++) {
-            final char c = name.charAt(i);
-            switch (c) {
-                case '\\':
-                case '*':
-                case '?':
-                case '\"':
-                    // quote, star, question & backslash must be escaped
-                    sb.append('\\');
-                    needsQuotes = true; // ... and can only appear in quoted value
-                    break;
-                case ',':
-                case '=':
-                case ':':
-                    // no need to escape these, but value must be quoted
-                    needsQuotes = true;
-                    break;
-                case '\r':
-                    // drop \r characters: \\r gives "invalid escape sequence"
-                    continue;
-                case '\n':
-                    // replace \n characters with \\n sequence
-                    sb.append("\\n");
-                    needsQuotes = true;
-                    continue;
-            }
-            sb.append(c);
-        }
-        if (needsQuotes) {
-            sb.insert(0, '\"');
-            sb.append('\"');
-        }
-        return sb.toString();
-    }
-
-    private static boolean isJmxDisabled() {
-        return PropertiesUtil.getProperties().getBooleanProperty(PROPERTY_DISABLE_JMX);
-    }
-
-    public static void reregisterMBeansAfterReconfigure() {
-        // avoid creating Platform MBean Server if JMX disabled
-        if (isJmxDisabled()) {
-            LOGGER.debug("JMX disabled for log4j2. Not registering MBeans.");
-            return;
-        }
-        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-        reregisterMBeansAfterReconfigure(mbs);
-    }
-
-    public static void reregisterMBeansAfterReconfigure(final MBeanServer mbs) {
-        if (isJmxDisabled()) {
-            LOGGER.debug("JMX disabled for log4j2. Not registering MBeans.");
-            return;
-        }
-
-        // now provide instrumentation for the newly configured
-        // LoggerConfigs and Appenders
-        try {
-            final ContextSelector selector = getContextSelector();
-            if (selector == null) {
-                LOGGER.debug("Could not register MBeans: no ContextSelector found.");
-                return;
-            }
-            LOGGER.trace("Reregistering MBeans after reconfigure. Selector={}", selector);
-            final List<LoggerContext> contexts = selector.getLoggerContexts();
-            int i = 0;
-            for (final LoggerContext ctx : contexts) {
-                LOGGER.trace("Reregistering context ({}/{}): '{}' {}", ++i, contexts.size(), ctx.getName(), ctx);
-                // first unregister the context and all nested loggers,
-                // appenders, statusLogger, contextSelector, ringbuffers...
-                unregisterLoggerContext(ctx.getName(), mbs);
-
-                final LoggerContextAdmin mbean = new LoggerContextAdmin(ctx, executor);
-                register(mbs, mbean, mbean.getObjectName());
-
-                if (ctx instanceof AsyncLoggerContext) {
-                    final RingBufferAdmin rbmbean = ((AsyncLoggerContext) ctx).createRingBufferAdmin();
-                    if (rbmbean.getBufferSize() > 0) {
-                        // don't register if Disruptor not started (DefaultConfiguration: config not found)
-                        register(mbs, rbmbean, rbmbean.getObjectName());
-                    }
-                }
-
-                // register the status logger and the context selector
-                // repeatedly
-                // for each known context: if one context is unregistered,
-                // these MBeans should still be available for the other
-                // contexts.
-                registerStatusLogger(ctx.getName(), mbs, executor);
-                registerContextSelector(ctx.getName(), selector, mbs, executor);
-
-                registerLoggerConfigs(ctx, mbs, executor);
-                registerAppenders(ctx, mbs, executor);
-            }
-        } catch (final Exception ex) {
-            LOGGER.error("Could not register mbeans", ex);
-        }
-    }
-
-    /**
-     * Unregister all log4j MBeans from the platform MBean server.
-     */
-    public static void unregisterMBeans() {
-        if (isJmxDisabled()) {
-            LOGGER.debug("JMX disabled for Log4j2. Not unregistering MBeans.");
-            return;
-        }
-        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-        unregisterMBeans(mbs);
-    }
-
-    /**
-     * Unregister all log4j MBeans from the specified MBean server.
-     *
-     * @param mbs the MBean server to unregister from.
-     */
-    public static void unregisterMBeans(final MBeanServer mbs) {
-        unregisterStatusLogger("*", mbs);
-        unregisterContextSelector("*", mbs);
-        unregisterContexts(mbs);
-        unregisterLoggerConfigs("*", mbs);
-        unregisterAsyncLoggerRingBufferAdmins("*", mbs);
-        unregisterAsyncLoggerConfigRingBufferAdmins("*", mbs);
-        unregisterAppenders("*", mbs);
-        unregisterAsyncAppenders("*", mbs);
-    }
-
-    /**
-     * Returns the {@code ContextSelector} of the current {@code Log4jContextFactory}.
-     *
-     * @return the {@code ContextSelector} of the current {@code Log4jContextFactory}
-     */
-    private static ContextSelector getContextSelector() {
-        final LoggerContextFactory factory = LogManager.getFactory();
-        if (factory instanceof Log4jContextFactory) {
-            final ContextSelector selector = ((Log4jContextFactory) factory).getSelector();
-            return selector;
-        }
-        return null;
-    }
-
-    /**
-     * Unregisters all MBeans associated with the specified logger context (including MBeans for {@code LoggerConfig}s
-     * and {@code Appender}s from the platform MBean server.
-     *
-     * @param loggerContextName name of the logger context to unregister
-     */
-    public static void unregisterLoggerContext(final String loggerContextName) {
-        if (isJmxDisabled()) {
-            LOGGER.debug("JMX disabled for Log4j2. Not unregistering MBeans.");
-            return;
-        }
-        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
-        unregisterLoggerContext(loggerContextName, mbs);
-    }
-
-    /**
-     * Unregisters all MBeans associated with the specified logger context (including MBeans for {@code LoggerConfig}s
-     * and {@code Appender}s from the platform MBean server.
-     *
-     * @param contextName name of the logger context to unregister
-     * @param mbs the MBean Server to unregister the instrumented objects from
-     */
-    public static void unregisterLoggerContext(final String contextName, final MBeanServer mbs) {
-        final String pattern = LoggerContextAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs); // unregister context mbean
-
-        // now unregister all MBeans associated with this logger context
-        unregisterStatusLogger(contextName, mbs);
-        unregisterContextSelector(contextName, mbs);
-        unregisterLoggerConfigs(contextName, mbs);
-        unregisterAppenders(contextName, mbs);
-        unregisterAsyncAppenders(contextName, mbs);
-        unregisterAsyncLoggerRingBufferAdmins(contextName, mbs);
-        unregisterAsyncLoggerConfigRingBufferAdmins(contextName, mbs);
-    }
-
-    private static void registerStatusLogger(final String contextName, final MBeanServer mbs, final Executor executor)
-            throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
-
-        final StatusLoggerAdmin mbean = new StatusLoggerAdmin(contextName, executor);
-        register(mbs, mbean, mbean.getObjectName());
-    }
-
-    private static void registerContextSelector(final String contextName, final ContextSelector selector,
-                                                final MBeanServer mbs, final Executor executor) throws InstanceAlreadyExistsException,
-            MBeanRegistrationException, NotCompliantMBeanException {
-
-        final ContextSelectorAdmin mbean = new ContextSelectorAdmin(contextName, selector);
-        register(mbs, mbean, mbean.getObjectName());
-    }
-
-    private static void unregisterStatusLogger(final String contextName, final MBeanServer mbs) {
-        final String pattern = StatusLoggerAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterContextSelector(final String contextName, final MBeanServer mbs) {
-        final String pattern = ContextSelectorAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterLoggerConfigs(final String contextName, final MBeanServer mbs) {
-        final String pattern = LoggerConfigAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterContexts(final MBeanServer mbs) {
-        final String pattern = LoggerContextAdminMBean.PATTERN;
-        final String search = String.format(pattern, "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterAppenders(final String contextName, final MBeanServer mbs) {
-        final String pattern = AppenderAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterAsyncAppenders(final String contextName, final MBeanServer mbs) {
-        final String pattern = AsyncAppenderAdminMBean.PATTERN;
-        final String search = String.format(pattern, escape(contextName), "*");
-        unregisterAllMatching(search, mbs);
-    }
-
-    private static void unregisterAsyncLoggerRingBufferAdmins(final String contextName, final MBeanServer mbs) {
-        final String pattern1 = RingBufferAdminMBean.PATTERN_ASYNC_LOGGER;
-        final String search1 = String.format(pattern1, escape(contextName));
-        unregisterAllMatching(search1, mbs);
-    }
-
-    private static void unregisterAsyncLoggerConfigRingBufferAdmins(final String contextName, final MBeanServer mbs) {
-        final String pattern2 = RingBufferAdminMBean.PATTERN_ASYNC_LOGGER_CONFIG;
-        final String search2 = String.format(pattern2, escape(contextName), "*");
-        unregisterAllMatching(search2, mbs);
-    }
-
-    private static void unregisterAllMatching(final String search, final MBeanServer mbs) {
-        try {
-            final ObjectName pattern = new ObjectName(search);
-            final Set<ObjectName> found = mbs.queryNames(pattern, null);
-            if (found.isEmpty()) {
-                LOGGER.trace("Unregistering but no MBeans found matching '{}'", search);
-            } else {
-                LOGGER.trace("Unregistering {} MBeans: {}", found.size(), found);
-            }
-            for (final ObjectName objectName : found) {
-                mbs.unregisterMBean(objectName);
-            }
-        } catch (final Exception ex) {
-            LOGGER.error("Could not unregister MBeans for " + search, ex);
-        }
-    }
-
-    private static void registerLoggerConfigs(final LoggerContext ctx, final MBeanServer mbs, final Executor executor)
-            throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
-
-        final Map<String, LoggerConfig> map = ctx.getConfiguration().getLoggers();
-        for (final String name : map.keySet()) {
-            final LoggerConfig cfg = map.get(name);
-            final LoggerConfigAdmin mbean = new LoggerConfigAdmin(ctx, cfg);
-            register(mbs, mbean, mbean.getObjectName());
-
-            if (cfg instanceof AsyncLoggerConfig) {
-                final AsyncLoggerConfig async = (AsyncLoggerConfig) cfg;
-                final RingBufferAdmin rbmbean = async.createRingBufferAdmin(ctx.getName());
-                register(mbs, rbmbean, rbmbean.getObjectName());
-            }
-        }
-    }
-
-    private static void registerAppenders(final LoggerContext ctx, final MBeanServer mbs, final Executor executor)
-            throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
-
-        final Map<String, Appender> map = ctx.getConfiguration().getAppenders();
-        for (final String name : map.keySet()) {
-            final Appender appender = map.get(name);
-
-            if (appender instanceof AsyncAppender) {
-                final AsyncAppender async = ((AsyncAppender) appender);
-                final AsyncAppenderAdmin mbean = new AsyncAppenderAdmin(ctx.getName(), async);
-                register(mbs, mbean, mbean.getObjectName());
-            } else {
-                final AppenderAdmin mbean = new AppenderAdmin(ctx.getName(), appender);
-                register(mbs, mbean, mbean.getObjectName());
-            }
-        }
-    }
-
-    private static void register(final MBeanServer mbs, final Object mbean, final ObjectName objectName)
-            throws InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
-        LOGGER.debug("Registering MBean {}", objectName);
-        mbs.registerMBean(mbean, objectName);
-    }
-}

+ 0 - 14
core/src/main/java/org/elasticsearch/bootstrap/JarHell.java

@@ -272,20 +272,6 @@ public class JarHell {
                         "class: " + clazz + System.lineSeparator() +
                         "exists multiple times in jar: " + jarpath + " !!!!!!!!!");
             } else {
-                if (clazz.startsWith("org.apache.logging.log4j.core.impl.ThrowableProxy")) {
-                    /*
-                     * deliberate to hack around a bug in Log4j
-                     * cf. https://github.com/elastic/elasticsearch/issues/20304
-                     * cf. https://issues.apache.org/jira/browse/LOG4J2-1560
-                     */
-                    return;
-                } else if (clazz.startsWith("org.apache.logging.log4j.core.jmx.Server")) {
-                    /*
-                     * deliberate to hack around a bug in Log4j
-                     * cf. https://issues.apache.org/jira/browse/LOG4J2-1506
-                     */
-                    return;
-                }
                 throw new IllegalStateException("jar hell!" + System.lineSeparator() +
                         "class: " + clazz + System.lineSeparator() +
                         "jar1: " + previous + System.lineSeparator() +

+ 1 - 1
core/src/main/java/org/elasticsearch/common/logging/LogConfigurator.java

@@ -99,7 +99,7 @@ public class LogConfigurator {
             @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                 if (file.getFileName().toString().equals("log4j2.properties")) {
-                    configurations.add((PropertiesConfiguration) factory.getConfiguration(file.toString(), file.toUri()));
+                    configurations.add((PropertiesConfiguration) factory.getConfiguration(context, file.toString(), file.toUri()));
                 }
                 return FileVisitResult.CONTINUE;
             }

+ 0 - 12
core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java

@@ -111,18 +111,6 @@ public class JarHellTests extends ESTestCase {
         }
     }
 
-    public void testLog4jThrowableProxyLeniency() throws Exception {
-        Path dir = createTempDir();
-        URL[] jars = {makeJar(dir, "foo.jar", null, "org.apache.logging.log4j.core.impl.ThrowableProxy.class"), makeJar(dir, "bar.jar", null, "org.apache.logging.log4j.core.impl.ThrowableProxy.class")};
-        JarHell.checkJarHell(jars);
-    }
-
-    public void testLog4jServerLeniency() throws Exception {
-        Path dir = createTempDir();
-        URL[] jars = {makeJar(dir, "foo.jar", null, "org.apache.logging.log4j.core.jmx.Server.class"), makeJar(dir, "bar.jar", null, "org.apache.logging.log4j.core.jmx.Server.class")};
-        JarHell.checkJarHell(jars);
-    }
-
     public void testWithinSingleJar() throws Exception {
         // the java api for zip file does not allow creating duplicate entries (good!) so
         // this bogus jar had to be constructed with ant

+ 0 - 1
distribution/licenses/log4j-1.2-api-2.6.2.jar.sha1

@@ -1 +0,0 @@
-3b4c5a8b734b6a29b2f03380535a48da6284b210

+ 1 - 0
distribution/licenses/log4j-1.2-api-2.7.jar.sha1

@@ -0,0 +1 @@
+39f4e6c2d68d4ef8fd4b0883d165682dedd5be52

+ 0 - 1
distribution/licenses/log4j-api-2.6.2.jar.sha1

@@ -1 +0,0 @@
-bd1b74a5d170686362091c7cf596bbc3adf5c09b

+ 1 - 0
distribution/licenses/log4j-api-2.7.jar.sha1

@@ -0,0 +1 @@
+8de00e382a817981b737be84cb8def687d392963

+ 0 - 1
distribution/licenses/log4j-core-2.6.2.jar.sha1

@@ -1 +0,0 @@
-00a91369f655eb1639c6aece5c5eb5108db18306

+ 1 - 0
distribution/licenses/log4j-core-2.7.jar.sha1

@@ -0,0 +1 @@
+a3f2b4e64c61a7fc1ed8f1e5ba371933404ed98a