You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/08/22 21:06:16 UTC

[logging-log4j2] branch slf4j-2.0 updated (8dcdb7c7d9 -> 7223523333)

This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a change to branch slf4j-2.0
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


    omit 8dcdb7c7d9 [LOG4J2-3370] Initial SLF4J 2.0.x support
     add fb83682941 Bump GitHub setup-java action to v3. (#816)
     add 5be42b2cfe [LOG4J2-3475] Add missing message parameterization in RegexFilter
     add ebfc8945a5 Add changelog entry for LOG4J2-3475
     add 041648a6a3 LOG4J2-3477 Add the missing context stack to JsonLayout template. (#819)
     add e865c9ad7b LOG4J2-3476 ignore JUL ApiLogger.setLevel without error
     add 060b09f7cd LOG4J2-3476 ignore JUL ApiLogger.setLevel without error
     add bfed0a38df Merge pull request #821 from remkop/LOG4J2-3476-JUL-ApiLogger-setLevel
     add 27fd2f8050 LOG4J2-3476 update changes.xml
     add 15166c8827 Fix `log4j-api` Java 9 tests
     add bfc8004c42 Fix `log4j-jul` ApiLoggerTest
     add 262828b193 [LOG4J2-3427] Replace ServiceLoader calls with ServiceLoaderUtil
     add a2f0faefa1 Add OSGI support to `ServiceLoaderUtil`
     add a3c3431cfc Add developer info in POM
     add 30e9563fdb [LOG4J2-3362] Adds a SmtpManager compatible with Jakarta EE 9
     add 7e7b1d7ef5 Fix `log4j-jakarta-smtp` POM file
     add e5576ed339 LOG4J2-3360 Add OSSF Scorecards GitHub Action.
     add 8f3f3af3e4 LOG4J2-3360 Replace GitHub Action versions with commit checksums.
     add 32e0df1ba2 LOG4J2-3369 Make build and CodeQL workflows read-only.
     add 618e6ca56d LOG4J2-3472 make disruptor WaitStrategy configurable in Log4j configuration
     add 8dd38f13c4 LOG4J2-3472 custom WaitStrategy additional tests
     add a3f054f45a LOG4J2-3472 custom WaitStrategy documentation
     add 29fdca6a1a LOG4J2-3472 files should end with newline
     add a68d3c4e67 LOG4J2-3472 make internals available with package-protected getters for testing
     add a89e33deef LOG4J2-3472 clear all modified system properties after test is done
     add 1b989b9604 LOG4J2-3472 (DOC) clarify specification
     add 86fe5452f0 LOG4J2-3472 package-protected getter
     add 425389c04a LOG4J2-3472 fix package-protected getters
     add 91222178b3 LOG4J2-3472 check that user-specified class implements AsyncWaitStrategyFactory
     add 52713b8ac3 LOG4J2-3472 code cleanup
     add b45e49c395 LOG4J2-3472 add missing license text
     add 786c011e29 Merge pull request #824 from remkop/LOG4J2-3472-WaitStrategyFactory
     add aa1cab96fd LOG4J2-3472 update changes.xml
     add b5592b7594 LOG4J2-3362 changelog
     add 6edf507ce8 Fix flaky ServiceLoaderUtilTest
     add 06b75ef230 LOG4J2-3473 add garbage-free version of TimeoutBlockingWaitStrategy and make this the default Async Loggers WaitStrategy
     add d7d60c6ed7 LOG4J2-3473 update for changes made with LOG4J2-3472
     add 97b8c1dc4f LOG4J2-3473 DOC update manual for garbage-free logging
     add e4e46f0667 LOG4J2-3473 update change log
     add 1341f1ddb0 Bump org.apache.felix.framework from 5.6.12 to 7.0.3
     add 448b057cf0 LOG4J2-3473 (DOC) fix version number
     add ad414c1ac0 LOG4J2-3495, LOG4J2-3481, LOG4J2-3482 Add MutableThreadContextMapFilter. Pass Auth provider when creating a connection.
     add 73b0513e4e Change the variable name
     add 03a0069cbc Update doc
     add 6bc69ab44f LOG4J2-2956 - Prevent ContextDataFactory error during startup
     add 455dca15dd Change config element name
     add 3277edc568 Update doc
     add a710c55b26 INFRA-23225 Publish snapshots using GitHub Actions.
     add 725bfef28f INFRA-23225 Deploy snapshots (once) if all platforms build successfully.
     add 88ce392cde INFRA-23225 Fix Maven deploy goal.
     add d86c9f6972 INFRA-23225 Add toolchains support.
     add 8f4267ba41 INFRA-23225 Fix Maven deploy goal, hopefully.
     add 07444c0d4a INFRA-23225 Try without deployAtEnd
     add e4a05ea642 INFRA-23225 Exclude failing log4j-bom from deployment
     add 7a40e60c30 INFRA-23225 Replaces - by !
     add 1a2a5946f3 INFRA-23225 Try to deploy log4j-bom, one more time.
     add 796f83150b INFRA-23225 Exclude log4j-bom, one more time.
     add cd29455a1e Improve JTL test parallelization.
     add 01465ca269 INFRA-23225 Provide deployment repository for log4j-bom.
     add 9f5cfdf780 Revert "Improve JTL test parallelization."
     add aaf13561e7 [LOG4J2-3366] Fixes order of property sources
     add 166968f266 Bump activemq-broker from 5.16.4 to 5.17.1
     add 73609fe4ff Bump de.flapdoodle.embed.mongo from 3.4.3 to 3.4.5
     add f976574cff Bump jmh.version from 1.34 to 1.35
     add 9ea52e7892 Bump elasticsearch-rest-high-level-client from 7.17.0 to 7.17.3
     add 550f60e5c4 Bump mongodb3.version from 3.12.10 to 3.12.11
     add d807c7adbe Defer fetching of the filter configuration until the first poll to prevent application startup from being blocked
     add 26efbc801b LOG4J2-3493 - ClassArbiter mistakenly used SystemPropertyArbiter.Builder
     add 25fff83746 LOG4J2-3506 - Support Spring 2.6.x
     add 918bb8472d LOG4J2-3506 - Support Spring 2.6.x
     add 1f227cd394 [LOG4J2-1376] Define eid as String instead of int to allow for Oid according to RFC5424 (#836)
     add 05a714c4b0 LOG4J2-3509 Fix minor doc typos.
     add a4d562b036 LOG4J2-3509 Of course I forgot the comma.
     add 26c7c42e83 LOG4J2-3491 - Correctly default to not include location info for AsyncLoggers
     add 22382a42bb Update mongodb dependencies in docs (#827)
     add ecd2d77830 Increase to 50 dependabot proposals
     add 460706b3c8 Dependabot support only a single Maven configuration
     add 30a5f51acc Bump jackson2Version from 2.13.2 to 2.13.3
     add 06511c6e46 Bump maven-clean-plugin from 3.1.0 to 3.2.0
     add 0b2ad4b71f Bump docker-maven-plugin from 0.39.0 to 0.39.1
     add c7dbe45be3 Bump maven-resources-plugin from 3.0.2 to 3.2.0
     add fb5ee513fb Bump de.flapdoodle.embed.mongo from 3.4.5 to 3.4.6
     add 022802aa3c Bump kubernetes-client from 5.12.1 to 5.12.2
     add 5673c2ffa0 Bump jacoco-maven-plugin from 0.8.7 to 0.8.8
     add 498bba4490 Bump log4j2-ecs-layout from 1.3.2 to 1.4.0 (#857)
     add a3ce1413aa Bump jctools-core from 1.2.1 to 3.3.0 (#862)
     add bd1ad8ae21 LOG4J2-3432 - SizeBasedTriggeringPolicy would fail to rename files properly when integer pattern contained a leading zero.
     add 272a614b7f LOG4J2-3516 - Move perf tests to log4j-core-its
     add fab90e06cf LOG4J2-3516 - Add changes.xml entry
     add 8bb477ada5 Bump elasticsearch-rest-high-level-client from 7.17.3 to 7.17.4 (#892)
     add 8e0ae5d66b Bump h2 from 1.4.200 to 2.1.212
     add 803c3e2384 Switch to PostgreSQL compatibility mode
     add 4c98fc20ef Bump org.apache.felix.framework from 7.0.3 to 7.0.4
     add 1e90f9aeb1 [LOG4J2-3483] Adds support for Apache Extras RollingFileAppender
     add 68097f8e29 LOG4J2-3520 Update outdated Maven Toolchains instructions. (#894)
     add 7348b6c892 LOG4J2-3520 More build instructions clean up.
     add ee30b5cdfb INFRA-23225 Remove redundant warning.
     add e71bb01cbf LOG4J2-3512, LOG4J2-3522 - Disable flaky tests
     add e4982c8be1 Bump plexus-utils from 3.4.1 to 3.4.2
     add 03c859cdfe Merge pull request #869 from apache/dependabot/maven/org.codehaus.plexus-plexus-utils-3.4.2
     add f7ff37b35e Bump spotbugs-maven-plugin from 4.0.4 to 4.7.0.0
     add c37a49c775 Bump maven-antrun-plugin from 3.0.0 to 3.1.0
     add 387340bff5 Merge pull request #871 from apache/dependabot/maven/org.apache.maven.plugins-maven-antrun-plugin-3.1.0
     add 6860f94214 Bump maven-compiler-plugin from 3.9.0 to 3.10.1
     add f1a0ce26bf Merge pull request #858 from apache/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.10.1
     add 8d310f7978 Bump springVersion from 5.3.19 to 5.3.20
     add 1007cf0964 Merge pull request #852 from apache/dependabot/maven/springVersion-5.3.20
     add e234784dc2 Use correct annotation to disable flaky test
     add 04ea25b986 Update CodeQL workflow to init@v2 and update permissions
     add 843dec10ea Bump findsecbugs-plugin from 1.10.1 to 1.12.0
     add 47d334d425 Merge pull request #888 from apache/dependabot/maven/com.h3xstream.findsecbugs-findsecbugs-plugin-1.12.0
     add ad9d25898d Narrow test disabling to Windows
     add 06c33a131b Bump maven-failsafe-plugin from 3.0.0-M5 to 3.0.0-M6
     add 6d15e411f2 Merge pull request #863 from apache/dependabot/maven/org.apache.maven.plugins-maven-failsafe-plugin-3.0.0-M6
     add affcbde0f0 Bump jeromq from 0.4.3 to 0.5.2
     add cecaaa4562 Merge pull request #843 from apache/dependabot/maven/org.zeromq-jeromq-0.5.2
     add 80b894fb26 Bump spring-ws-core from 3.1.2 to 3.1.3
     add fd4429d3e3 Merge pull request #876 from apache/dependabot/maven/org.springframework.ws-spring-ws-core-3.1.3
     add 3ef4e3e024 Update CI link in pom
     add 501f07ce23 Enable github action dependabot nagging
     add dfabcfa34b Bump cassandra-driver-core from 3.1.4 to 3.11.2
     add 623360f5a9 Merge pull request #856 from apache/dependabot/maven/com.datastax.cassandra-cassandra-driver-core-3.11.2
     add d26d48da3e Bump org.osgi.core from 4.3.1 to 6.0.0
     add 69c8944dcc Merge pull request #859 from apache/dependabot/maven/org.osgi-org.osgi.core-6.0.0
     add c4cce1ea82 Bump maven-jxr-plugin from 3.1.1 to 3.2.0
     add e532daeb9a Merge pull request #877 from apache/dependabot/maven/org.apache.maven.plugins-maven-jxr-plugin-3.2.0
     add 50a9ce8e76 Bump tomcat-juli from 10.0.16 to 10.0.21
     add 352cda1c7c Merge pull request #861 from apache/dependabot/maven/org.apache.tomcat-tomcat-juli-10.0.21
     add c979eba9a5 Bump maven-dependency-plugin from 3.2.0 to 3.3.0
     add 31c60200fd Merge pull request #875 from apache/dependabot/maven/org.apache.maven.plugins-maven-dependency-plugin-3.3.0
     add 3709750696 Bump icu4j from 4.6.1 to 71.1
     add 9b62fd2f8a Merge pull request #874 from apache/dependabot/maven/com.ibm.icu-icu4j-71.1
     add eba0fb2d7e Narrow permissions required for codeql
     add 464940d81a Bump ossf/scorecard-action from 1.0.4 to 1.1.0
     add 02d99c3e3f Merge pull request #897 from apache/dependabot/github_actions/ossf/scorecard-action-1.1.0
     add 7e58c0b298 Bump actions/setup-java from 3.1.1 to 3.3.0
     add 859ace8952 Merge pull request #898 from apache/dependabot/github_actions/actions/setup-java-3.3.0
     add dc67a20772 Bump actions/checkout from 3.0.1 to 3.0.2
     add 7ba5d0435b Merge pull request #899 from apache/dependabot/github_actions/actions/checkout-3.0.2
     add 78b3fa4f37 Bump actions/upload-artifact from 3.0.0 to 3.1.0
     add b34f8ca6ca Merge pull request #900 from apache/dependabot/github_actions/actions/upload-artifact-3.1.0
     add 02274f11dd Move permissions required for codeql
     add decd2cf837 Bump jetty-util from 8.2.0.v20160908 to 11.0.9
     add 6d50df8731 Change the version to 9.4
     add ed8185da9b Remove managed dependency
     add f53da962a8 Bump surefire.plugin.version from 3.0.0-M5 to 3.0.0-M6
     add cde5b4a5a3 Keep `log4j-jpl` at Surefire version 2.13
     add f7beb65e11 Bump lightcouch from 0.0.6 to 0.2.0
     add 3045d91d11 Revert h2 version upgrade
     add 84232a6bd6 Retry copying if the file is in use
     add 8456c2ece9 Remove disabled annotation
     add a5532c6759 Fix cleanup procedure after H2 tests
     add fc7ed4fa6d Upgrade H2 to version 2.1.212
     add 9f25c4f568 Bump docker-maven-plugin from 0.39.1 to 0.40.0 (#901)
     add 1ab0788f61 LOG4J2-3490 - The DirectWriteRolloverStrategy was not detecting the correct index to use during startup
     add 448fbcd78e Bump cassandra-all from 2.2.8 to 4.0.4
     add 8febdb0667 Downgrade Cassandra to 3.11.13 and fix test
     add c75a46d515 Bump JNA to version 4.5.2
     add 5d9a36dd4b LOG4J2-3527 - Don't use Paths.get()
     add eabff363c5 LOG4J2-3527 - Don't use Paths.get()
     add 662603bb0e Bump org.apache.felix.framework from 7.0.4 to 7.0.5
     add 4d20b040b3 Bump assertj-core from 3.22.0 to 3.23.1 (#908)
     add a3e8e217d6 [LOG4J2-3531] Parser configuration workaround for old Xerces
     add e0d01e05ac [LOG4J2-3531] Check if XInclude is supported
     add 6fe1109610 Changelog for LOG4J2-3531
     add 5635fa3c03 LOG4J2-3528 Fix typo in docs.
     add a84787555e Bump ossf/scorecard-action from 1.1.0 to 1.1.1 (#914)
     add 1e3c6f5d4d Bump actions/setup-python from 3.1.2 to 4 (#923)
     add c2d049d947 [LOG4J2-3534] Fix LevelRangeFilterBuilder to align with log4j1's behavior (#924)
     add df5a68541b Update to Flume 1.10.0
     add ab1528ba7a LOG4J2-3536 - Upgrade the Flume Appender to Flume 1.10.0
     add a8b40ca25b Bump jna from 4.5.2 to 5.11.0
     add 35e3525d6d Bump h2 from 2.1.212 to 2.1.214
     add f70802305a LOG4J2-3538 Added support for 24 colors in highlighting (#933)
     add 38ba5a46cf LOG4J2-3537 Fixes problem with wrong ANSI escape code for bright colors (#935)
     add 358a346e99 Bump docker-maven-plugin from 0.40.0 to 0.40.1 (#925)
     add 8a1bfd5628 Bump jetty-util from 9.4.46.v20220331 to 9.4.47.v20220610
     add 8a18112a27 Bump jetty-util from 9.4.47.v20220610 to 9.4.48.v20220622
     add 161c07664c LOG4J2-3339 - DirectWriteRolloverStrategy should use the current time when creating files
     add 604341fdda Revert pdf plugin verison back to 1.2
     add 6997f93af7 Updates dependencies to Java EE 8
     add 902e15c063 Fix heading
     add b4f10b5d32 Resolve issues in changes.xml
     add 920bba0291 Prepare for release
     add a3613864c8 [maven-release-plugin] prepare release log4j-2.18.0-rc1
     add cccc77c8f0 [maven-release-plugin] prepare for next development iteration
     add 6dc0f07eb8 [LOG4J2-3545] Add Service Loader Mediator support to `log4j-jcl`
     add d891597cc4 Quoting problem
     add f5b5d0b922 [LOG4J2-3546] Switch from `osgi.serviceloader` to `Activator`
     add 45cfad3c55 Bump ossf/scorecard-action from 1.1.1 to 1.1.2 (#944)
     add c1d2e6c5a2 Bump elasticsearch-rest-high-level-client from 7.17.4 to 7.17.5 (#945)
     add 6b4fb8f0d4 fix SystemPropertyArbiter (#955)
     add 55bbf91127 LOG4J2-3550 - SystemPropertyAribiter was assigning the value as the name
     add bcf34fe5ed Fix GitHub Actions dependency version comments (#971)
     add 36f71eaf7e Update CodeQL to 2.10.1.
     add d01ddbd85a Bump actions/setup-python from 4.0.0 to 4.1.0 (#958)
     add 1024b7069e Bump actions/setup-java from 3.3.0 to 3.4.1 (#957)
     add 05c1c55697 Update CodeQL to 2.1.16, the earlier fix was wrong.
     add bfd4069378 Add missing modules to BOM
     add f167c5198c LOG4J2-3560: Logger$PrivateConfig.filter(Level, Marker, String) varargs does not allocate (#974)
     add be8af7f32b [LOG4J2-2557] Remove recursion between Logger and LoggerRepository
     add 7fde259912 [LOG4J2-3561] Support both whitespace and commas in %style
     add 3df5ce9b1a [LOG4J2-3564] Fix NPE when root logger level is null
     add f40c66b6ba Bump github/codeql-action from 2.1.16 to 2.1.17 (#985)
     add 8662c06dda Bump docker-maven-plugin from 0.40.1 to 0.40.2 (#991)
     add 28efddbcd5 [LOG4J2-3565] Fix RollingRandomAccessFileAppender with DirectWriteRolloverStrategy can't create the first log file of different directory.
     add 40214e87c4 Fix version typos in security page.
     add e08ef96329 Vanity commit
     add e1caac6af8 Bump actions/setup-python from 4.1.0 to 4.2.0 (#992)
     add 4ed4d281ff Bump github/codeql-action from 2.1.17 to 2.1.18 (#993)
     add 4d1d780d0b LOG4J2-3573 Removed build page in favor of a single build instructions file.
     add f0526bce4e LOG4J2-3573 Remove mention of unsupported parallel build.
     add 80aae21796 [LOG4J2-3577] Use classloader provided by servlet context
     add 092f64370e Revert commit 80aae21
     add 767e03020b LOG4J2-3556 Make JsonTemplateLayout stack trace truncation operate for each label block. (#1002)
     add 1e25c58dd2 LOG4J2-3578 - Generate new SSL certs for unit testing
     new 7223523333 [LOG4J2-3370] Initial SLF4J 2.0.x support

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (8dcdb7c7d9)
            \
             N -- N -- N   refs/heads/slf4j-2.0 (7223523333)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/dependabot.yml                             |   8 +-
 .github/workflows/benchmark.yml                    |  18 +-
 .github/workflows/build.yml                        |  62 +-
 .github/workflows/codeql-analysis.yml              |  84 +--
 .../workflows/maven-settings.xml                   |  46 +-
 .github/workflows/scorecards-analysis.yml          |  67 +++
 BUILDING.md                                        |  58 +-
 NOTICE.txt                                         |   3 +
 README.md                                          |  27 +-
 RELEASE-NOTES.md                                   | 267 +++------
 log4j-1.2-api/pom.xml                              |   9 +-
 .../src/main/java/org/apache/log4j/Category.java   |  12 +-
 .../src/main/java/org/apache/log4j/Hierarchy.java  | 103 +---
 .../org/apache/log4j/builders/AbstractBuilder.java |  27 +
 .../org/apache/log4j/builders/BuilderManager.java  |   7 +
 .../EnhancedRollingFileAppenderBuilder.java        | 241 ++++++++
 .../builders/filter/LevelRangeFilterBuilder.java   |  21 +-
 .../rolling/CompositeTriggeringPolicyBuilder.java  |  74 +++
 .../rolling/SizeBasedTriggeringPolicyBuilder.java  |  75 +++
 .../rolling/TimeBasedRollingPolicyBuilder.java     |  56 ++
 .../builders/rolling/TriggeringPolicyBuilder.java  |  12 +-
 .../log4j/config/PropertiesConfiguration.java      |   9 +
 .../org/apache/log4j/xml/XmlConfiguration.java     |   7 +
 .../test/java/org/apache/log4j/CategoryTest.java   |   1 +
 .../filter/LevelRangeFilterBuilderTest.java        | 211 +++++++
 .../config/AbstractLog4j1ConfigurationTest.java    | 102 ++++
 .../log4j/config/PropertiesConfigurationTest.java  |  52 +-
 .../apache/log4j/config/XmlConfigurationTest.java  |  31 +-
 .../src/test/resources/LOG4J2-3326.properties      |  49 +-
 .../log4j-EnhancedRollingFileAppender.properties   |  66 +++
 .../log4j-EnhancedRollingFileAppender.xml          |  94 +++
 .../log4j-LevelRangeFilter.properties}             |  46 +-
 .../config-1.2/log4j-LevelRangeFilter.xml          |  32 +
 log4j-api-java9/pom.xml                            |  67 +--
 log4j-api-java9/src/assembly/java9.xml             |   4 +
 log4j-api-java9/src/main/java/module-info.java     |   8 +
 .../StatusLogger.java}                             |  22 +-
 .../EnvironmentPropertySource.java}                |   2 +-
 .../PropertySource.java => util/LoaderUtil.java}   |   6 +-
 .../log4j/{log4j => }/util/PropertySource.java     |  12 +-
 .../logging/log4j/util/ServiceLoaderUtil.java      | 111 ++++
 .../SystemPropertiesPropertySource.java}           |   2 +-
 .../{ProcessIdUtilTest.java => ModuleTest.java}    |  20 +-
 .../log4j/util/java9/ProcessIdUtilTest.java        |   4 +-
 .../log4j/util/java9/ServiceLoaderUtilTest.java    |  53 ++
 .../logging/log4j/util/java9/StackLocatorTest.java |  11 +-
 .../log4j/util/java9/test/BetterService.java}      |  11 +-
 .../logging/log4j/util/java9/test/Service.java}    |  11 +-
 .../logging/log4j/util/java9/test/Service1.java}   |  11 +-
 .../logging/log4j/util/java9/test/Service2.java}   |  11 +-
 .../src/test/{java => java9}/module-info.java      |  13 +
 .../logging/log4j/util/java9/ModuleUtil.java}      |  15 +-
 log4j-api/pom.xml                                  |  68 ++-
 .../logging/log4j/message/StructuredDataId.java    |  69 ++-
 .../logging/log4j/message/ThreadDumpMessage.java   |  26 +-
 .../log4j/util/EnvironmentPropertySource.java      |  45 +-
 .../org/apache/logging/log4j/util/LoaderUtil.java  |  37 +-
 .../logging/log4j/util/OsgiServiceLocator.java     |  67 +++
 .../log4j/util/PropertiesPropertySource.java       |  27 +-
 .../apache/logging/log4j/util/PropertiesUtil.java  | 123 ++--
 .../log4j/util/PropertyFilePropertySource.java     |  15 +-
 .../apache/logging/log4j/util/PropertySource.java  |  13 +-
 .../logging/log4j/util/ProviderActivator.java      |  55 ++
 .../apache/logging/log4j/util/ProviderUtil.java    |  35 +-
 .../logging/log4j/util/ServiceLoaderUtil.java      | 176 +++---
 .../log4j/util/SystemPropertiesPropertySource.java |  26 +-
 .../log4j/message/StructuredDataMessageTest.java   |   8 +
 .../logging/log4j/util/OsgiServiceLocatorTest.java |  25 +-
 .../log4j/util/PropertiesUtilOrderTest.java        | 204 +++++++
 .../logging/log4j/util/ServiceLoaderUtilTest.java  |  58 +-
 .../resources/PropertiesUtilOrderTest.properties   |  43 ++
 log4j-appserver/pom.xml                            |   5 +-
 log4j-bom/pom.xml                                  |  30 +-
 log4j-cassandra/pom.xml                            |  10 +-
 .../logging/log4j/cassandra/CassandraRule.java     |  29 +-
 log4j-core-its/pom.xml                             |  13 +-
 .../core/async/perftest/AbstractRunQueue.java      |   0
 .../log4j/core/async/perftest/Histogram.java       |   0
 .../log4j/core/async/perftest/IPerfTestRunner.java |   0
 .../log4j/core/async/perftest/IdleStrategy.java    |   0
 .../core/async/perftest/MultiThreadPerfTest.java   |   0
 .../core/async/perftest/NoOpIdleStrategy.java      |   0
 .../log4j/core/async/perftest/PerfTest.java        |   0
 .../log4j/core/async/perftest/PerfTestDriver.java  |   0
 .../async/perftest/PerfTestResultFormatter.java    |   0
 .../core/async/perftest/ResponseTimeTest.java      |   0
 .../log4j/core/async/perftest/RunConversant.java   |   0
 .../log4j/core/async/perftest/RunJCTools.java      |   0
 .../log4j/core/async/perftest/RunLog4j1.java       |   0
 .../log4j/core/async/perftest/RunLog4j2.java       |   0
 .../log4j/core/async/perftest/RunLogback.java      |   0
 .../log4j/core/async/perftest/SimplePerfTest.java  |   0
 .../core/async/perftest/YieldIdleStrategy.java     |   0
 log4j-core-java9/pom.xml                           |  11 +-
 log4j-core/pom.xml                                 |  32 +-
 .../java/org/apache/logging/log4j/core/Filter.java |  13 +
 .../java/org/apache/logging/log4j/core/Logger.java |   3 +-
 .../logging/log4j/core/appender/SmtpAppender.java  |  68 ++-
 .../log4j/core/appender/SyslogAppender.java        |  38 +-
 .../appender/rolling/AbstractRolloverStrategy.java |   2 +-
 .../appender/rolling/DefaultRolloverStrategy.java  |   3 +-
 .../rolling/DirectWriteRolloverStrategy.java       |   5 +-
 .../core/appender/rolling/PatternProcessor.java    |   8 +
 .../core/appender/rolling/RollingFileManager.java  |   2 +
 .../rolling/RollingRandomAccessFileManager.java    |  10 +-
 .../logging/log4j/core/async/AsyncLogger.java      |   5 +
 .../log4j/core/async/AsyncLoggerConfig.java        |  10 +-
 .../core/async/AsyncLoggerConfigDisruptor.java     |  13 +-
 .../log4j/core/async/AsyncLoggerContext.java       |   8 +-
 .../log4j/core/async/AsyncLoggerDisruptor.java     |  15 +-
 .../core/async/AsyncWaitStrategyFactory.java}      |  27 +-
 .../core/async/AsyncWaitStrategyFactoryConfig.java | 106 ++++
 .../async/DefaultAsyncWaitStrategyFactory.java     |  94 +++
 .../logging/log4j/core/async/DisruptorUtil.java    |  59 +-
 .../core/async/TimeoutBlockingWaitStrategy.java    | 135 +++++
 .../log4j/core/config/AbstractConfiguration.java   |  15 +-
 .../logging/log4j/core/config/Configuration.java   |  11 +
 .../logging/log4j/core/config/HttpWatcher.java     | 104 ++--
 .../logging/log4j/core/config/LoggerConfig.java    |   2 -
 .../log4j/core/config/arbiters/ClassArbiter.java   |   4 +-
 .../config/arbiters/SystemPropertyArbiter.java     |   4 +-
 .../log4j/core/config/xml/XmlConfiguration.java    |  39 +-
 .../log4j/core/filter/DynamicThresholdFilter.java  |   7 +
 .../log4j/core/filter/LevelRangeFilter.java        |   4 +
 .../core/filter/MutableThreadContextMapFilter.java | 407 +++++++++++++
 .../logging/log4j/core/filter/RegexFilter.java     |   6 +-
 .../log4j/core/filter/ThreadContextMapFilter.java  |   9 +-
 .../core/filter/mutable/KeyValuePairConfig.java}   |  33 +-
 .../log4j/core/impl/ThreadContextDataInjector.java |  17 +-
 .../logging/log4j/core/layout/LoggerFields.java    |   4 +-
 .../logging/log4j/core/layout/Rfc5424Layout.java   | 163 ++++-
 .../apache/logging/log4j/core/net/MailManager.java | 211 +++++++
 .../log4j/core/net/MailManagerFactory.java}        |  18 +-
 .../apache/logging/log4j/core/net/SmtpManager.java | 165 ++----
 .../log4j/core/net/UrlConnectionFactory.java       |  80 +--
 .../apache/logging/log4j/core/osgi/Activator.java  |  23 +-
 .../logging/log4j/core/pattern/AnsiEscape.java     | 168 +++++-
 .../logging/log4j/core/pattern/StyleConverter.java |   2 +-
 .../apache/logging/log4j/core/util/Patterns.java   |   5 +
 .../org/apache/logging/log4j/core/util/Source.java |  14 +-
 .../logging/log4j/core/util/WatchManager.java      |  25 +-
 .../core/util/internal/HttpInputStreamUtil.java    | 135 +++++
 .../core/util/internal/LastModifiedSource.java}    |  40 +-
 .../logging/log4j/core/util/internal/Status.java   |   9 +-
 .../logging/log4j/core/GcFreeLoggingTestUtil.java  |  95 ++-
 .../log4j/core/appender/SmtpAppenderTest.java      |  15 +-
 .../core/appender/db/jdbc/AbstractH2Test.java      |   8 -
 .../jdbc/JdbcAppenderColumnMappingLiteralTest.java |   6 -
 .../core/appender/db/jdbc/JdbcH2TestHelper.java    |   4 +-
 .../core/appender/mom/kafka/KafkaAppenderTest.java |   8 +-
 .../appender/rolling/RollingAppenderCountTest.java |   2 +
 .../rolling/RollingAppenderDirectCronTest.java     | 119 ++++
 .../rolling/RollingAppenderSizeMaxWidthTest.java   | 159 +++++
 .../rolling/RollingDirectSize3490Test.java         | 100 ++++
 ...omAppenderDirectWriteAndSwitchDirectorTest.java |  48 ++
 .../core/async/AsyncLoggerDefaultLocationTest.java |  71 +++
 ...WaitStrategyFactoryConfigGlobalLoggersTest.java |  69 +++
 .../async/AsyncWaitStrategyFactoryConfigTest.java  |  82 +++
 ...egyFactoryIncorrectConfigGlobalLoggersTest.java |  65 ++
 .../core/config/arbiters/BasicArbiterTest.java     |  11 +
 .../filter/HttpThreadContextMapFilterTest.java     | 198 +++++++
 .../filter/MutableThreadContextMapFilterTest.java  | 108 ++++
 .../logging/log4j/core/filter/RegexFilterTest.java |  20 +
 .../log4j/core/layout/Rfc5424LayoutTest.java       |  64 +-
 .../logging/log4j/core/net/SmtpManagerTest.java    |  33 +-
 .../log4j/core/net/UrlConnectionFactoryTest.java   |  25 +-
 .../log4j/core/pattern/HighlightConverterTest.java |  31 +-
 .../log4j/core/pattern/StyleConverterTest.java     |  26 +
 .../resources/AsyncLoggerDefaultLocationTest.xml   |  20 +
 ...ncWaitStrategyFactoryConfigGlobalLoggerTest.xml |  17 +
 .../AsyncWaitStrategyFactoryConfigTest.xml         |  17 +
 ...ategyIncorrectFactoryConfigGlobalLoggerTest.xml |  16 +
 ...AsyncWaitStrategyIncorrectFactoryConfigTest.xml |  16 +
 log4j-core/src/test/resources/emptyConfig.json     |   4 +
 log4j-core/src/test/resources/filterConfig.json    |   6 +
 .../src/test/resources/log4j-rolling-3490.xml      |  19 +
 ...-arbiters.xml => log4j-rolling-direct-cron.xml} |  37 +-
 ...log4j-rolling-random-direct-switch-director.xml |  49 ++
 ...ters.xml => log4j-rolling-size-max-width-1.xml} |  38 +-
 ...ters.xml => log4j-rolling-size-max-width-2.xml} |  38 +-
 ...ters.xml => log4j-rolling-size-max-width-3.xml} |  38 +-
 .../resources/log4j-rolling-size-max-width-4.xml   |  53 ++
 log4j-core/src/test/resources/log4j2-arbiters.xml  |   8 +
 ...og4j2-arbiters.xml => log4j2-mutableFilter.xml} |  26 +-
 .../logging/log4j/core/net/ssl/build/gencerts.sh   |  28 +
 .../logging/log4j/core/net/ssl/build/rootca.conf   |   9 +
 .../logging/log4j/core/net/ssl/build/server.conf   |   9 +
 .../log4j/core/net/ssl/client.log4j2-crt.pem       |  32 -
 .../log4j/core/net/ssl/client.log4j2-keystore.jks  | Bin 6829 -> 3520 bytes
 .../logging/log4j/core/net/ssl/log4j2-cacert.pem   |  32 -
 .../log4j/core/net/ssl/server.log4j2-crt.pem       |  45 +-
 .../log4j/core/net/ssl/server.log4j2-key.pem       |  51 --
 .../logging/log4j/core/net/ssl/server.log4j2.pem   |  23 +
 .../log4j/core/net/ssl/syslog-ng-sample.conf       |  33 --
 .../logging/log4j/core/net/ssl/truststore.jks      | Bin 1487 -> 776 bytes
 log4j-couchdb/pom.xml                              |   2 +-
 log4j-distribution/pom.xml                         |   6 +-
 log4j-docker/pom.xml                               |   2 +-
 log4j-flume-ng/pom.xml                             |  15 +-
 .../log4j/flume/appender/FlumeAppender.java        |  18 +-
 .../flume/appender/FlumeEmbeddedAgentTest.java     |  34 +-
 .../flume/appender/FlumeEmbeddedAppenderTest.java  |  35 +-
 .../appender/FlumePersistentAppenderTest.java      |  33 +-
 .../log4j/flume/appender/FlumePersistentPerf.java  |  34 +-
 log4j-iostreams/pom.xml                            |   2 +-
 {log4j-mongodb3 => log4j-jakarta-smtp}/pom.xml     |  80 ++-
 .../logging/log4j/smtp/MimeMessageBuilder.java     |  93 +++
 .../apache/logging/log4j/smtp}/SmtpManager.java    | 202 ++-----
 ...pache.logging.log4j.core.net.MailManagerFactory |   1 +
 .../logging/log4j/smtp/SmtpAppenderAsyncTest.java  |  98 +++
 .../logging/log4j/smtp}/SmtpAppenderTest.java      |  24 +-
 .../logging/log4j/smtp}/SmtpManagerTest.java       |  44 +-
 .../src/test/resources/SmtpAppenderAsyncTest.xml   |   0
 log4j-jakarta-web/pom.xml                          |   2 +-
 log4j-jcl/pom.xml                                  |   4 +-
 log4j-jdbc-dbcp2/pom.xml                           |   2 +-
 log4j-jmx-gui/pom.xml                              |   2 +-
 log4j-jpa/pom.xml                                  |   7 +-
 .../src/test/resources/META-INF/persistence.xml    |   7 +-
 log4j-jpl/pom.xml                                  |   4 +-
 log4j-jul/pom.xml                                  |   2 +-
 .../org/apache/logging/log4j/jul/ApiLogger.java    |   4 +-
 .../apache/logging/log4j/jul/ApiLoggerTest.java    |  11 +-
 log4j-kubernetes/pom.xml                           |   2 +-
 log4j-layout-template-json/pom.xml                 |   2 +-
 .../template/json/resolver/ExceptionResolver.java  |   9 +-
 .../json/resolver/StackTraceStringResolver.java    | 248 +++++++-
 .../template/json/util/CharSequencePointer.java    | 106 ++++
 .../json/util/TruncatingBufferedPrintWriter.java   |  17 +-
 .../json/util/TruncatingBufferedWriter.java        |  50 +-
 .../src/main/resources/JsonLayout.json             |   4 +
 .../log4j/layout/template/json/JsonLayoutTest.java |  12 +-
 .../template/json/JsonTemplateLayoutTest.java      | 276 +--------
 .../resolver/StackTraceStringResolverTest.java     | 657 +++++++++++++++++++++
 .../json/util/CharSequencePointerTest.java         | 121 ++++
 .../json/util/TruncatingBufferedWriterTest.java    |  63 +-
 log4j-liquibase/pom.xml                            |   2 +-
 log4j-mongodb3/pom.xml                             |   2 +-
 log4j-mongodb3/src/site/markdown/index.md.vm       |   2 +-
 log4j-mongodb4/pom.xml                             |   2 +-
 log4j-mongodb4/src/site/markdown/index.md.vm       |   2 +-
 log4j-osgi/pom.xml                                 | 108 +++-
 .../log4j/osgi/tests/AbstractLoadBundleTest.java   |  69 +--
 .../logging/log4j/osgi/tests/JULProviderTest.java  |  72 +++
 .../log4j/osgi/tests/SLF4JProviderTest.java        |  71 +++
 .../log4j/osgi/tests/junit/BundleTestInfo.java     |  71 ---
 log4j-perf/pom.xml                                 |   8 +-
 log4j-samples/log4j-samples-configuration/pom.xml  |   2 +-
 log4j-samples/log4j-samples-flume-common/pom.xml   |   2 +-
 log4j-samples/log4j-samples-flume-embedded/pom.xml |   2 +-
 log4j-samples/log4j-samples-flume-remote/pom.xml   |   2 +-
 .../log4j-samples-loggerProperties/pom.xml         |   2 +-
 log4j-samples/pom.xml                              |   4 +-
 log4j-slf4j-impl/pom.xml                           |   2 +-
 log4j-slf4j18-impl/pom.xml                         |   2 +-
 log4j-spring-boot/pom.xml                          |   2 +-
 .../boot/Log4j2CloudConfigLoggingSystem.java       |  83 ++-
 .../log4j/spring/boot/SpringPropertySource.java    |   4 +-
 .../log4j-spring-cloud-config-client/pom.xml       |   2 +-
 .../pom.xml                                        |   4 +-
 .../pom.xml                                        |   6 +-
 .../log4j-spring-cloud-config-samples/pom.xml      |   4 +-
 log4j-spring-cloud-config/pom.xml                  |   2 +-
 log4j-taglib/pom.xml                               |   6 +-
 log4j-to-jul/pom.xml                               |  13 +-
 .../org/apache/logging/log4j/tojul/Activator.java  |  14 +-
 .../org/apache/logging/log4j/tojul/JULLogger.java  |   3 +-
 .../apache/logging/log4j/tojul/JULLoggerTest.java  |  66 ++-
 log4j-to-slf4j/pom.xml                             |  13 +-
 .../java/org/apache/logging/slf4j/Activator.java   |  16 +-
 log4j-web/pom.xml                                  |  10 +-
 pom.xml                                            | 229 +++++--
 src/changes/announcement.vm                        |  13 +-
 src/changes/changes.xml                            | 123 +++-
 .../asciidoc/manual/json-template-layout.adoc.vm   |  10 +-
 src/site/custom/project-info-report.properties     |   6 +-
 src/site/markdown/build.md                         |  69 ---
 src/site/markdown/index.md.vm                      |   1 +
 src/site/markdown/security.md                      |   4 +-
 src/site/site.xml                                  |   2 +-
 src/site/xdoc/manual/async.xml                     |  56 ++
 src/site/xdoc/manual/configuration.xml.vm          |  51 +-
 src/site/xdoc/manual/filters.xml                   |  82 +++
 src/site/xdoc/manual/garbagefree.xml               |  11 +-
 src/site/xdoc/manual/layouts.xml.vm                |  23 +-
 toolchains-sample-linux.xml                        |  52 --
 toolchains-sample-mac.xml                          |  52 --
 287 files changed, 8927 insertions(+), 2867 deletions(-)
 rename toolchains-sample-win.xml => .github/workflows/maven-settings.xml (52%)
 create mode 100644 .github/workflows/scorecards-analysis.yml
 create mode 100644 log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/EnhancedRollingFileAppenderBuilder.java
 create mode 100644 log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/CompositeTriggeringPolicyBuilder.java
 create mode 100644 log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/SizeBasedTriggeringPolicyBuilder.java
 create mode 100644 log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TimeBasedRollingPolicyBuilder.java
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => log4j-1.2-api/src/main/java/org/apache/log4j/builders/rolling/TriggeringPolicyBuilder.java (76%)
 create mode 100644 log4j-1.2-api/src/test/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilderTest.java
 create mode 100644 log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.properties
 create mode 100644 log4j-1.2-api/src/test/resources/config-1.2/log4j-EnhancedRollingFileAppender.xml
 copy log4j-1.2-api/src/test/resources/{LOG4J2-3326.properties => config-1.2/log4j-LevelRangeFilter.properties} (73%)
 create mode 100644 log4j-1.2-api/src/test/resources/config-1.2/log4j-LevelRangeFilter.xml
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/{log4j/util/PropertySource.java => status/StatusLogger.java} (64%)
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/{log4j/util/PropertySource.java => util/EnvironmentPropertySource.java} (93%)
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/{log4j/util/PropertySource.java => util/LoaderUtil.java} (86%)
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/{log4j => }/util/PropertySource.java (72%)
 create mode 100644 log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/{log4j/util/PropertySource.java => util/SystemPropertiesPropertySource.java} (93%)
 copy log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/{ProcessIdUtilTest.java => ModuleTest.java} (60%)
 create mode 100644 log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/ServiceLoaderUtilTest.java
 copy log4j-api-java9/src/{main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => test/java/org/apache/logging/log4j/util/java9/test/BetterService.java} (79%)
 copy log4j-api-java9/src/{main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => test/java/org/apache/logging/log4j/util/java9/test/Service.java} (79%)
 copy log4j-api-java9/src/{main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => test/java/org/apache/logging/log4j/util/java9/test/Service1.java} (79%)
 copy log4j-api-java9/src/{main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => test/java/org/apache/logging/log4j/util/java9/test/Service2.java} (79%)
 copy log4j-api-java9/src/test/{java => java9}/module-info.java (71%)
 copy log4j-api-java9/src/{main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => test/java9/org/apache/logging/log4j/util/java9/ModuleUtil.java} (76%)
 create mode 100644 log4j-api/src/main/java/org/apache/logging/log4j/util/OsgiServiceLocator.java
 create mode 100644 log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderActivator.java
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => log4j-api/src/test/java/org/apache/logging/log4j/util/OsgiServiceLocatorTest.java (58%)
 create mode 100644 log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilOrderTest.java
 create mode 100644 log4j-api/src/test/resources/PropertiesUtilOrderTest.properties
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/AbstractRunQueue.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/Histogram.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/IPerfTestRunner.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/IdleStrategy.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/MultiThreadPerfTest.java (100%)
 copy {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/NoOpIdleStrategy.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTest.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTestDriver.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/PerfTestResultFormatter.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/ResponseTimeTest.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/RunConversant.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/RunJCTools.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLog4j1.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLog4j2.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/RunLogback.java (100%)
 rename {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/SimplePerfTest.java (100%)
 copy {log4j-core => log4j-core-its}/src/test/java/org/apache/logging/log4j/core/async/perftest/YieldIdleStrategy.java (100%)
 copy log4j-core/src/{test/java/org/apache/logging/log4j/core/async/perftest/NoOpIdleStrategy.java => main/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactory.java} (58%)
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfig.java
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/async/DefaultAsyncWaitStrategyFactory.java
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/async/TimeoutBlockingWaitStrategy.java
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilter.java
 rename log4j-core/src/{test/java/org/apache/logging/log4j/core/async/perftest/NoOpIdleStrategy.java => main/java/org/apache/logging/log4j/core/filter/mutable/KeyValuePairConfig.java} (56%)
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/net/MailManager.java
 rename log4j-core/src/{test/java/org/apache/logging/log4j/core/async/perftest/YieldIdleStrategy.java => main/java/org/apache/logging/log4j/core/net/MailManagerFactory.java} (71%)
 create mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/util/internal/HttpInputStreamUtil.java
 copy log4j-core/src/{test/java/org/apache/logging/log4j/core/appender/db/jdbc/AbstractH2Test.java => main/java/org/apache/logging/log4j/core/util/internal/LastModifiedSource.java} (52%)
 copy log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => log4j-core/src/main/java/org/apache/logging/log4j/core/util/internal/Status.java (77%)
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectCronTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeMaxWidthTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectSize3490Test.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteAndSwitchDirectorTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerDefaultLocationTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigGlobalLoggersTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryConfigTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactoryIncorrectConfigGlobalLoggersTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/filter/HttpThreadContextMapFilterTest.java
 create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilterTest.java
 create mode 100644 log4j-core/src/test/resources/AsyncLoggerDefaultLocationTest.xml
 create mode 100644 log4j-core/src/test/resources/AsyncWaitStrategyFactoryConfigGlobalLoggerTest.xml
 create mode 100644 log4j-core/src/test/resources/AsyncWaitStrategyFactoryConfigTest.xml
 create mode 100644 log4j-core/src/test/resources/AsyncWaitStrategyIncorrectFactoryConfigGlobalLoggerTest.xml
 create mode 100644 log4j-core/src/test/resources/AsyncWaitStrategyIncorrectFactoryConfigTest.xml
 create mode 100644 log4j-core/src/test/resources/emptyConfig.json
 create mode 100644 log4j-core/src/test/resources/filterConfig.json
 create mode 100644 log4j-core/src/test/resources/log4j-rolling-3490.xml
 copy log4j-core/src/test/resources/{log4j2-arbiters.xml => log4j-rolling-direct-cron.xml} (55%)
 create mode 100644 log4j-core/src/test/resources/log4j-rolling-random-direct-switch-director.xml
 copy log4j-core/src/test/resources/{log4j2-arbiters.xml => log4j-rolling-size-max-width-1.xml} (53%)
 copy log4j-core/src/test/resources/{log4j2-arbiters.xml => log4j-rolling-size-max-width-2.xml} (53%)
 copy log4j-core/src/test/resources/{log4j2-arbiters.xml => log4j-rolling-size-max-width-3.xml} (53%)
 create mode 100644 log4j-core/src/test/resources/log4j-rolling-size-max-width-4.xml
 copy log4j-core/src/test/resources/{log4j2-arbiters.xml => log4j2-mutableFilter.xml} (63%)
 create mode 100755 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/build/gencerts.sh
 create mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/build/rootca.conf
 create mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/build/server.conf
 delete mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/client.log4j2-crt.pem
 delete mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/log4j2-cacert.pem
 delete mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/server.log4j2-key.pem
 create mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/server.log4j2.pem
 delete mode 100644 log4j-core/src/test/resources/org/apache/logging/log4j/core/net/ssl/syslog-ng-sample.conf
 copy {log4j-mongodb3 => log4j-jakarta-smtp}/pom.xml (78%)
 create mode 100644 log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/MimeMessageBuilder.java
 copy {log4j-core/src/main/java/org/apache/logging/log4j/core/net => log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp}/SmtpManager.java (58%)
 create mode 100644 log4j-jakarta-smtp/src/main/resources/META-INF/services/org.apache.logging.log4j.core.net.MailManagerFactory
 create mode 100644 log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp/SmtpAppenderAsyncTest.java
 copy {log4j-core/src/test/java/org/apache/logging/log4j/core/appender => log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp}/SmtpAppenderTest.java (91%)
 copy {log4j-core/src/test/java/org/apache/logging/log4j/core/net => log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp}/SmtpManagerTest.java (70%)
 copy {log4j-core => log4j-jakarta-smtp}/src/test/resources/SmtpAppenderAsyncTest.xml (100%)
 create mode 100644 log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/CharSequencePointer.java
 create mode 100644 log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/StackTraceStringResolverTest.java
 create mode 100644 log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/util/CharSequencePointerTest.java
 create mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/JULProviderTest.java
 create mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/SLF4JProviderTest.java
 delete mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
 rename log4j-api-java9/src/test/java/module-info.java => log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/Activator.java (77%)
 copy log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/ProcessIdUtilTest.java => log4j-to-jul/src/test/java/org/apache/logging/log4j/tojul/JULLoggerTest.java (58%)
 rename log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java => log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/Activator.java (79%)
 delete mode 100644 src/site/markdown/build.md
 delete mode 100644 toolchains-sample-linux.xml
 delete mode 100644 toolchains-sample-mac.xml


[logging-log4j2] 01/01: [LOG4J2-3370] Initial SLF4J 2.0.x support

Posted by pk...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch slf4j-2.0
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 72235233331a50046398befab26a03b716385450
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Mon Apr 11 23:59:26 2022 +0200

    [LOG4J2-3370] Initial SLF4J 2.0.x support
---
 log4j-slf4j20-impl/pom.xml                         | 255 +++++++++++++
 .../java/org/apache/logging/slf4j/Log4jLogger.java | 420 +++++++++++++++++++++
 .../apache/logging/slf4j/Log4jLoggerFactory.java   |  75 ++++
 .../org/apache/logging/slf4j/Log4jMDCAdapter.java  |  60 +++
 .../java/org/apache/logging/slf4j/Log4jMarker.java | 126 +++++++
 .../apache/logging/slf4j/Log4jMarkerFactory.java   | 138 +++++++
 .../logging/slf4j/SLF4JLoggingException.java       |  41 ++
 .../apache/logging/slf4j/SLF4JServiceProvider.java |  59 +++
 .../org/apache/logging/slf4j/package-info.java     |  22 ++
 .../services/org.slf4j.spi.SLF4JServiceProvider    |   1 +
 log4j-slf4j20-impl/src/site/markdown/index.md      |  40 ++
 log4j-slf4j20-impl/src/site/site.xml               |  52 +++
 .../logging/other/pkg/LoggerContextAnchorTest.java |  91 +++++
 .../logging/slf4j/CallerInformationTest.java       |  67 ++++
 .../org/apache/logging/slf4j/CustomFlatMarker.java |  76 ++++
 .../org/apache/logging/slf4j/Log4j1222Test.java    |  57 +++
 .../logging/slf4j/Log4j2_1482_Slf4jTest.java       |  41 ++
 .../org/apache/logging/slf4j/Log4jMarkerTest.java  |  47 +++
 .../apache/logging/slf4j/LoggerContextTest.java    |  44 +++
 .../java/org/apache/logging/slf4j/LoggerTest.java  | 161 ++++++++
 .../java/org/apache/logging/slf4j/MarkerTest.java  | 186 +++++++++
 .../org/apache/logging/slf4j/OverflowTest.java     |  43 +++
 .../org/apache/logging/slf4j/SerializeTest.java    |  46 +++
 .../src/test/resources/log4j-test1.xml             |  33 ++
 .../src/test/resources/log4j2-1482.xml             |  27 ++
 pom.xml                                            |   1 +
 26 files changed, 2209 insertions(+)

diff --git a/log4j-slf4j20-impl/pom.xml b/log4j-slf4j20-impl/pom.xml
new file mode 100644
index 0000000000..8d516fdc1b
--- /dev/null
+++ b/log4j-slf4j20-impl/pom.xml
@@ -0,0 +1,255 @@
+<?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">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>2.17.3-SNAPSHOT</version>
+  </parent>
+  <artifactId>log4j-slf4j20-impl</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache Log4j SLF4J 2.0+ Binding</name>
+  <description>The Apache Log4j SLF4J 2.0 API binding to Log4j 2 Core</description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>SLF4J Documentation</docLabel>
+    <projectDir>/slf4j18</projectDir>
+    <slf4j.version>2.0.0-alpha5</slf4j.version>
+    <module.name>org.apache.logging.log4j.slf4j</module.name>
+    <maven.doap.skip>true</maven.doap.skip>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-ext</artifactId>
+      <version>${slf4j.version}</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-csv</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-core</artifactId>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-to-slf4j</artifactId>
+      <scope>test</scope>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.vintage</groupId>
+      <artifactId>junit-vintage-engine</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <!-- Include the standard NOTICE and LICENSE -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <configuration>
+              <skip>false</skip>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>loop-test</id>
+            <phase>test</phase>
+            <goals>
+              <goal>test</goal>
+            </goals>
+            <configuration>
+              <includes>
+                <include>**/OverflowTest.java</include>
+              </includes>
+            </configuration>
+          </execution>
+          <execution>
+            <id>default-test</id>
+            <phase>test</phase>
+            <goals>
+              <goal>test</goal>
+            </goals>
+            <configuration>
+              <includes>
+                <include>**/*Test.java</include>
+              </includes>
+              <excludes>
+                <exclude>**/OverflowTest.java</exclude>
+              </excludes>
+              <classpathDependencyExcludes>
+                <classpathDependencyExcludes>org.apache.logging.log4j:log4j-to-slf4j</classpathDependencyExcludes>
+              </classpathDependencyExcludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.apache.logging.slf4j,
+              org.slf4j.impl
+            </Export-Package>
+            <Require-Capability>
+              osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
+            </Require-Capability>
+            <Provide-Capability>
+              osgi.serviceloader;osgi.serviceloader=org.slf4j.spi.SLF4JServiceProvider
+            </Provide-Capability>
+          </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>com.github.spotbugs</groupId>
+        <artifactId>spotbugs-maven-plugin</artifactId>
+      </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>
+
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java
new file mode 100644
index 0000000000..10ad49ca7e
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLogger.java
@@ -0,0 +1,420 @@
+/*
+ * 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.slf4j;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.slf4j.Marker;
+import org.slf4j.spi.LocationAwareLogger;
+
+/**
+ * SLF4J logger implementation that uses Log4j.
+ */
+public class Log4jLogger implements LocationAwareLogger, Serializable {
+
+    public static final String FQCN = Log4jLogger.class.getName();
+
+    private static final long serialVersionUID = 7869000638091304316L;
+    private transient ExtendedLogger logger;
+    private final String name;
+    private transient Log4jMarkerFactory markerFactory;
+
+    public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) {
+        this.markerFactory = markerFactory;
+        this.logger = logger;
+        this.name = name;
+    }
+
+    @Override
+    public void trace(final String format) {
+        logger.logIfEnabled(FQCN, Level.TRACE, null, format);
+    }
+
+    @Override
+    public void trace(final String format, final Object o) {
+        logger.logIfEnabled(FQCN, Level.TRACE, null, format, o);
+    }
+
+    @Override
+    public void trace(final String format, final Object arg1, final Object arg2) {
+        logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2);
+    }
+
+    @Override
+    public void trace(final String format, final Object... args) {
+        logger.logIfEnabled(FQCN, Level.TRACE, null, format, args);
+    }
+
+    @Override
+    public void trace(final String format, final Throwable t) {
+        logger.logIfEnabled(FQCN, Level.TRACE, null, format, t);
+    }
+
+    @Override
+    public boolean isTraceEnabled() {
+        return logger.isEnabled(Level.TRACE, null, null);
+    }
+
+    @Override
+    public boolean isTraceEnabled(final Marker marker) {
+        return logger.isEnabled(Level.TRACE, getMarker(marker), null);
+    }
+
+    @Override
+    public void trace(final Marker marker, final String s) {
+        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s);
+    }
+
+    @Override
+    public void trace(final Marker marker, final String s, final Object o) {
+        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o);
+    }
+
+    @Override
+    public void trace(final Marker marker, final String s, final Object o, final Object o1) {
+        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1);
+    }
+
+    @Override
+    public void trace(final Marker marker, final String s, final Object... objects) {
+        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects);
+    }
+
+    @Override
+    public void trace(final Marker marker, final String s, final Throwable throwable) {
+        logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable);
+    }
+
+    @Override
+    public void debug(final String format) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, format);
+    }
+
+    @Override
+    public void debug(final String format, final Object o) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o);
+    }
+
+    @Override
+    public void debug(final String format, final Object arg1, final Object arg2) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2);
+    }
+
+    @Override
+    public void debug(final String format, final Object... args) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args);
+    }
+
+    @Override
+    public void debug(final String format, final Throwable t) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t);
+    }
+
+    @Override
+    public boolean isDebugEnabled() {
+        return logger.isEnabled(Level.DEBUG, null, null);
+    }
+
+    @Override
+    public boolean isDebugEnabled(final Marker marker) {
+        return logger.isEnabled(Level.DEBUG, getMarker(marker), null);
+    }
+
+    @Override
+    public void debug(final Marker marker, final String s) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s);
+    }
+
+    @Override
+    public void debug(final Marker marker, final String s, final Object o) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o);
+    }
+
+    @Override
+    public void debug(final Marker marker, final String s, final Object o, final Object o1) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1);
+    }
+
+    @Override
+    public void debug(final Marker marker, final String s, final Object... objects) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects);
+    }
+
+    @Override
+    public void debug(final Marker marker, final String s, final Throwable throwable) {
+        logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable);
+    }
+
+    @Override
+    public void info(final String format) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, format);
+    }
+
+    @Override
+    public void info(final String format, final Object o) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, format, o);
+    }
+
+    @Override
+    public void info(final String format, final Object arg1, final Object arg2) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2);
+    }
+
+    @Override
+    public void info(final String format, final Object... args) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, format, args);
+    }
+
+    @Override
+    public void info(final String format, final Throwable t) {
+        logger.logIfEnabled(FQCN, Level.INFO, null, format, t);
+    }
+
+    @Override
+    public boolean isInfoEnabled() {
+        return logger.isEnabled(Level.INFO, null, null);
+    }
+
+    @Override
+    public boolean isInfoEnabled(final Marker marker) {
+        return logger.isEnabled(Level.INFO, getMarker(marker), null);
+    }
+
+    @Override
+    public void info(final Marker marker, final String s) {
+        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s);
+    }
+
+    @Override
+    public void info(final Marker marker, final String s, final Object o) {
+        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o);
+    }
+
+    @Override
+    public void info(final Marker marker, final String s, final Object o, final Object o1) {
+        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
+    }
+
+    @Override
+    public void info(final Marker marker, final String s, final Object... objects) {
+        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects);
+    }
+
+    @Override
+    public void info(final Marker marker, final String s, final Throwable throwable) {
+        logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable);
+    }
+
+    @Override
+    public void warn(final String format) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, format);
+    }
+
+    @Override
+    public void warn(final String format, final Object o) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, format, o);
+    }
+
+    @Override
+    public void warn(final String format, final Object arg1, final Object arg2) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2);
+    }
+
+    @Override
+    public void warn(final String format, final Object... args) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, format, args);
+    }
+
+    @Override
+    public void warn(final String format, final Throwable t) {
+        logger.logIfEnabled(FQCN, Level.WARN, null, format, t);
+    }
+
+    @Override
+    public boolean isWarnEnabled() {
+        return logger.isEnabled(Level.WARN, null, null);
+    }
+
+    @Override
+    public boolean isWarnEnabled(final Marker marker) {
+        return logger.isEnabled(Level.WARN, getMarker(marker), null);
+    }
+
+    @Override
+    public void warn(final Marker marker, final String s) {
+        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s);
+    }
+
+    @Override
+    public void warn(final Marker marker, final String s, final Object o) {
+        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o);
+    }
+
+    @Override
+    public void warn(final Marker marker, final String s, final Object o, final Object o1) {
+        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1);
+    }
+
+    @Override
+    public void warn(final Marker marker, final String s, final Object... objects) {
+        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects);
+    }
+
+    @Override
+    public void warn(final Marker marker, final String s, final Throwable throwable) {
+        logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable);
+    }
+
+    @Override
+    public void error(final String format) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, format);
+    }
+
+    @Override
+    public void error(final String format, final Object o) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, format, o);
+    }
+
+    @Override
+    public void error(final String format, final Object arg1, final Object arg2) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2);
+    }
+
+    @Override
+    public void error(final String format, final Object... args) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, format, args);
+    }
+
+    @Override
+    public void error(final String format, final Throwable t) {
+        logger.logIfEnabled(FQCN, Level.ERROR, null, format, t);
+    }
+
+    @Override
+    public boolean isErrorEnabled() {
+        return logger.isEnabled(Level.ERROR, null, null);
+    }
+
+    @Override
+    public boolean isErrorEnabled(final Marker marker) {
+        return logger.isEnabled(Level.ERROR, getMarker(marker), null);
+    }
+
+    @Override
+    public void error(final Marker marker, final String s) {
+        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s);
+    }
+
+    @Override
+    public void error(final Marker marker, final String s, final Object o) {
+        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o);
+    }
+
+    @Override
+    public void error(final Marker marker, final String s, final Object o, final Object o1) {
+        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1);
+    }
+
+    @Override
+    public void error(final Marker marker, final String s, final Object... objects) {
+        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects);
+    }
+
+    @Override
+    public void error(final Marker marker, final String s, final Throwable throwable) {
+        logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable);
+    }
+
+    @Override
+    public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) {
+        final Level log4jLevel = getLevel(level);
+        final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker);
+
+        if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) {
+            return;
+        }
+        final Message msg;
+        if (params == null) {
+            msg = new SimpleMessage(message);
+        } else {
+            msg = new ParameterizedMessage(message, params, throwable);
+            if (throwable != null) {
+                throwable = msg.getThrowable();
+            }
+        }
+        logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable);
+    }
+
+    private org.apache.logging.log4j.Marker getMarker(final Marker marker) {
+        if (marker == null) {
+            return null;
+        } else if (marker instanceof Log4jMarker) {
+            return ((Log4jMarker) marker).getLog4jMarker();
+        } else {
+            return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Always treat de-serialization as a full-blown constructor, by validating the final state of
+     * the de-serialized object.
+     */
+    private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException {
+        // always perform the default de-serialization first
+        aInputStream.defaultReadObject();
+        logger = LogManager.getContext().getLogger(name);
+        markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
+    }
+
+    /**
+     * This is the default implementation of writeObject. Customise if necessary.
+     */
+    private void writeObject(final ObjectOutputStream aOutputStream) throws IOException {
+        // perform the default serialization for all non-transient, non-static fields
+        aOutputStream.defaultWriteObject();
+    }
+
+    private static Level getLevel(final int i) {
+        switch (i) {
+        case TRACE_INT:
+            return Level.TRACE;
+        case DEBUG_INT:
+            return Level.DEBUG;
+        case INFO_INT:
+            return Level.INFO;
+        case WARN_INT:
+            return Level.WARN;
+        case ERROR_INT:
+            return Level.ERROR;
+        }
+        return Level.ERROR;
+    }
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java
new file mode 100644
index 0000000000..99e6817a1a
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jLoggerFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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.slf4j;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.LoggingException;
+import org.apache.logging.log4j.spi.AbstractLoggerAdapter;
+import org.apache.logging.log4j.spi.LoggerContext;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.StackLocatorUtil;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+
+import java.util.function.Predicate;
+
+/**
+ * Log4j implementation of SLF4J ILoggerFactory interface.
+ */
+public class Log4jLoggerFactory extends AbstractLoggerAdapter<Logger> implements ILoggerFactory {
+
+    private static final StatusLogger LOGGER = StatusLogger.getLogger();
+    private static final String SLF4J_PACKAGE = "org.slf4j";
+    private static final Predicate<Class<?>> CALLER_PREDICATE = clazz ->
+            !AbstractLoggerAdapter.class.equals(clazz) && !clazz.getName().startsWith(SLF4J_PACKAGE);
+    private static final String TO_SLF4J_CONTEXT = "org.apache.logging.slf4j.SLF4JLoggerContext";
+
+    private final Log4jMarkerFactory markerFactory;
+
+    public Log4jLoggerFactory(final Log4jMarkerFactory markerFactory) {
+        this.markerFactory = markerFactory;
+    }
+
+
+    @Override
+    protected Logger newLogger(final String name, final LoggerContext context) {
+        final String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
+        return new Log4jLogger(markerFactory, validateContext(context).getLogger(key), name);
+    }
+
+    @Override
+    protected LoggerContext getContext() {
+        final Class<?> anchor = LogManager.getFactory().isClassLoaderDependent()
+                ? StackLocatorUtil.getCallerClass(Log4jLoggerFactory.class, CALLER_PREDICATE)
+                : null;
+        LOGGER.trace("Log4jLoggerFactory.getContext() found anchor {}", anchor);
+        return anchor == null
+                ? LogManager.getContext(false)
+                : getContext(anchor);
+    }
+
+    Log4jMarkerFactory getMarkerFactory() {
+        return markerFactory;
+    }
+
+    private LoggerContext validateContext(final LoggerContext context) {
+        if (TO_SLF4J_CONTEXT.equals(context.getClass().getName())) {
+            throw new LoggingException("log4j-slf4j-impl cannot be present with log4j-to-slf4j");
+        }
+        return context;
+    }
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java
new file mode 100644
index 0000000000..b12c297ac3
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMDCAdapter.java
@@ -0,0 +1,60 @@
+/*
+ * 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.slf4j;
+
+import java.util.Map;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.slf4j.spi.MDCAdapter;
+
+/**
+ *
+ */
+public class Log4jMDCAdapter implements MDCAdapter {
+
+    @Override
+    public void put(final String key, final String val) {
+        ThreadContext.put(key, val);
+    }
+
+    @Override
+    public String get(final String key) {
+        return ThreadContext.get(key);
+    }
+
+    @Override
+    public void remove(final String key) {
+        ThreadContext.remove(key);
+    }
+
+    @Override
+    public void clear() {
+        ThreadContext.clearMap();
+    }
+
+    @Override
+    public Map<String, String> getCopyOfContextMap() {
+        return ThreadContext.getContext();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API
+    public void setContextMap(@SuppressWarnings("rawtypes") final Map map) {
+        ThreadContext.clearMap();
+        ThreadContext.putAll(map);
+    }
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java
new file mode 100644
index 0000000000..fb21659103
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarker.java
@@ -0,0 +1,126 @@
+/*
+ * 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.slf4j;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.logging.log4j.MarkerManager;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.Marker;
+
+/**
+ * Log4j/SLF4J {@link Marker} type bridge.
+ */
+class Log4jMarker implements Marker {
+
+    public static final long serialVersionUID = 1590472L;
+
+    private final IMarkerFactory factory;
+
+    private final org.apache.logging.log4j.Marker marker;
+
+    /**
+     * Constructs a Log4jMarker using an existing Log4j {@link org.apache.logging.log4j.Marker}.
+     * @param marker The Log4j Marker upon which to base this Marker.
+     */
+    public Log4jMarker(final IMarkerFactory markerFactory, final org.apache.logging.log4j.Marker marker) {
+        this.factory = markerFactory;
+        this.marker = marker;
+    }
+
+    @Override
+    public void add(final Marker marker) {
+		if (marker == null) {
+			throw new IllegalArgumentException();
+		}
+        final Marker m = factory.getMarker(marker.getName());
+        this.marker.addParents(((Log4jMarker)m).getLog4jMarker());
+    }
+
+    @Override
+	public boolean contains(final Marker marker) {
+		if (marker == null) {
+			throw new IllegalArgumentException();
+		}
+		return this.marker.isInstanceOf(marker.getName());
+	}
+
+    @Override
+	public boolean contains(final String s) {
+		return s != null ? this.marker.isInstanceOf(s) : false;
+	}
+
+    @Override
+	public boolean equals(final Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (!(obj instanceof Log4jMarker)) {
+			return false;
+		}
+		final Log4jMarker other = (Log4jMarker) obj;
+		if (!Objects.equals(marker, other.marker)) {
+			return false;
+		}
+		return true;
+	}
+
+    public org.apache.logging.log4j.Marker getLog4jMarker() {
+        return marker;
+    }
+
+    @Override
+    public String getName() {
+        return marker.getName();
+    }
+
+    @Override
+    public boolean hasChildren() {
+        return marker.hasParents();
+    }
+
+    @Override
+	public int hashCode() {
+		return 31 + Objects.hashCode(marker);
+	}
+
+    @Override
+    public boolean hasReferences() {
+        return marker.hasParents();
+    }
+
+	@Override
+    public Iterator<Marker> iterator() {
+        final org.apache.logging.log4j.Marker[] log4jParents = this.marker.getParents();
+        final List<Marker> parents = new ArrayList<>(log4jParents.length);
+		for (final org.apache.logging.log4j.Marker m : log4jParents) {
+            parents.add(factory.getMarker(m.getName()));
+        }
+        return parents.iterator();
+    }
+
+	@Override
+	public boolean remove(final Marker marker) {
+		return marker != null ? this.marker.remove(MarkerManager.getMarker(marker.getName())) : false;
+	}
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java
new file mode 100644
index 0000000000..69ea94b33c
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/Log4jMarkerFactory.java
@@ -0,0 +1,138 @@
+/*
+ * 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.slf4j;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.Marker;
+
+/**
+ * Log4j/SLF4J bridge to create SLF4J Markers based on name or based on existing SLF4J Markers.
+ */
+public class Log4jMarkerFactory implements IMarkerFactory {
+
+    private static final Logger LOGGER = StatusLogger.getLogger();
+
+    private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<>();
+
+    /**
+     * Returns a Log4j Marker that is compatible with SLF4J.
+     * @param name The name of the Marker.
+     * @return A Marker.
+     */
+    @Override
+    public Marker getMarker(final String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Marker name must not be null");
+        }
+        final Marker marker = markerMap.get(name);
+        if (marker != null) {
+            return marker;
+        }
+        final org.apache.logging.log4j.Marker log4jMarker = MarkerManager.getMarker(name);
+        return addMarkerIfAbsent(name, log4jMarker);
+    }
+
+    private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) {
+        final Marker marker = new Log4jMarker(this, log4jMarker);
+        final Marker existing = markerMap.putIfAbsent(name, marker);
+        return existing == null ? marker : existing;
+    }
+
+    /**
+     * Returns a Log4j Marker converted from an existing custom SLF4J Marker.
+     * @param marker The SLF4J Marker to convert.
+     * @return A converted Log4j/SLF4J Marker.
+     * @since 2.1
+     */
+    public Marker getMarker(final Marker marker) {
+        if (marker == null) {
+            throw new IllegalArgumentException("Marker must not be null");
+        }
+        final Marker m = markerMap.get(marker.getName());
+        if (m != null) {
+            return m;
+        }
+        return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
+    }
+
+    private static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
+        if (original == null) {
+            throw new IllegalArgumentException("Marker must not be null");
+        }
+        return convertMarker(original, new ArrayList<Marker>());
+    }
+
+    private static org.apache.logging.log4j.Marker convertMarker(final Marker original,
+                                                                 final Collection<Marker> visited) {
+        final org.apache.logging.log4j.Marker marker = MarkerManager.getMarker(original.getName());
+        if (original.hasReferences()) {
+            final Iterator<Marker> it = original.iterator();
+            while (it.hasNext()) {
+                final Marker next = it.next();
+                if (visited.contains(next)) {
+                    LOGGER.warn("Found a cycle in Marker [{}]. Cycle will be broken.", next.getName());
+                } else {
+                    visited.add(next);
+                    marker.addParents(convertMarker(next, visited));
+                }
+            }
+        }
+        return marker;
+    }
+
+    /**
+     * Returns true if the Marker exists.
+     * @param name The Marker name.
+     * @return {@code true} if the Marker exists, {@code false} otherwise.
+     */
+    @Override
+    public boolean exists(final String name) {
+        return markerMap.containsKey(name);
+    }
+
+    /**
+     * Log4j does not support detached Markers. This method always returns false.
+     * @param name The Marker name.
+     * @return {@code false}
+     */
+    @Override
+    public boolean detachMarker(final String name) {
+        return false;
+    }
+
+    /**
+     * Log4j does not support detached Markers for performance reasons. The returned Marker is attached.
+     * @param name The Marker name.
+     * @return The named Marker (unmodified).
+     */
+    @Override
+    public Marker getDetachedMarker(final String name) {
+        LOGGER.warn("Log4j does not support detached Markers. Returned Marker [{}] will be unchanged.", name);
+        return getMarker(name);
+    }
+
+
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.java
new file mode 100644
index 0000000000..0a41215383
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JLoggingException.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.slf4j;
+
+/**
+ * Exception thrown when the SLF4J adapter encounters a problem.
+ *
+ */
+public class SLF4JLoggingException extends RuntimeException {
+
+    /**
+     * Generated serial version ID.
+     */
+    private static final long serialVersionUID = -1618650972455089998L;
+
+    public SLF4JLoggingException(final String msg) {
+        super(msg);
+    }
+
+    public SLF4JLoggingException(final String msg, final Exception ex) {
+        super(msg, ex);
+    }
+
+    public SLF4JLoggingException(final Exception ex) {
+        super(ex);
+    }
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java
new file mode 100644
index 0000000000..b711941a91
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/SLF4JServiceProvider.java
@@ -0,0 +1,59 @@
+/*
+ * 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.slf4j;
+
+import org.slf4j.ILoggerFactory;
+import org.slf4j.IMarkerFactory;
+import org.slf4j.spi.MDCAdapter;
+
+public class SLF4JServiceProvider implements org.slf4j.spi.SLF4JServiceProvider {
+
+    public static final String REQUESTED_API_VERSION = "2.0.99";
+
+    private ILoggerFactory loggerFactory;
+    private Log4jMarkerFactory markerFactory;
+    private MDCAdapter mdcAdapter;
+
+    @Override
+    public ILoggerFactory getLoggerFactory() {
+        return loggerFactory;
+    }
+
+    @Override
+    public IMarkerFactory getMarkerFactory() {
+        return markerFactory;
+    }
+
+    @Override
+    public MDCAdapter getMDCAdapter() {
+        return mdcAdapter;
+    }
+
+    @Override
+    public String getRequestedApiVersion() {
+        return REQUESTED_API_VERSION;
+    }
+
+    @Override
+    public void initialize() {
+        markerFactory = new Log4jMarkerFactory();
+        loggerFactory = new Log4jLoggerFactory(markerFactory);
+        mdcAdapter = new Log4jMDCAdapter();
+    }
+
+
+}
diff --git a/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/package-info.java b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/package-info.java
new file mode 100644
index 0000000000..ec0f031c37
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/java/org/apache/logging/slf4j/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * SLF4J support. Note that this does indeed share the same package namespace as the one found in log4j-to-slf4j;
+ * this is intentional. The two JARs should <em>not</em> be used at the same time! Thus, in an OSGi environment
+ * where split packages are not allowed, this error is prevented due to both JARs sharing an exported package name.
+ */
+package org.apache.logging.slf4j;
diff --git a/log4j-slf4j20-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/log4j-slf4j20-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
new file mode 100644
index 0000000000..1577f12daf
--- /dev/null
+++ b/log4j-slf4j20-impl/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider
@@ -0,0 +1 @@
+org.apache.logging.slf4j.SLF4JServiceProvider
\ No newline at end of file
diff --git a/log4j-slf4j20-impl/src/site/markdown/index.md b/log4j-slf4j20-impl/src/site/markdown/index.md
new file mode 100644
index 0000000000..6e3f3f69d1
--- /dev/null
+++ b/log4j-slf4j20-impl/src/site/markdown/index.md
@@ -0,0 +1,40 @@
+<!-- vim: set syn=markdown : -->
+<!--
+    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.
+-->
+
+# Log4j 2 SLF4J Binding
+
+The Log4j 2 SLF4J Binding allows applications coded to the SLF4J API to use
+Log4j 2 as the implementation.
+
+## Requirements
+
+The Log4j 2 SLF4J Binding has a dependency on the Log4j 2 API as well as the SLF4J API.
+For more information, see [Runtime Dependencies](../runtime-dependencies.html).
+
+## Usage
+
+The SLF4J binding provided in this component cause all the SLF4J APIs to be routed to Log4j 2. Simply
+include the Log4j 2 SLF4J Binding jar along with the Log4j 2 jars and SLF4J API jar to cause all SLF4J
+logging to be handled by Log4j 2.
+
+<div class="alert alert-danger">
+Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with 
+the SLF4J adapter (log4j-to-slf4j-2.0.jar) should 
+never be attempted, as it will cause events to endlessly be routed between
+SLF4J and Log4j 2.
+</div>
diff --git a/log4j-slf4j20-impl/src/site/site.xml b/log4j-slf4j20-impl/src/site/site.xml
new file mode 100644
index 0000000000..a1f9106932
--- /dev/null
+++ b/log4j-slf4j20-impl/src/site/site.xml
@@ -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.
+
+-->
+<project name="SLF4J Binding Using Log4j"
+         xmlns="http://maven.apache.org/DECORATION/1.4.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
+  <body>
+    <links>
+      <item name="Apache" href="http://www.apache.org/" />
+      <item name="Logging Services" href="http://logging.apache.org/"/>
+      <item name="Log4j" href="../index.html"/>
+    </links>
+
+    <!-- Component-specific reports -->
+    <menu ref="reports"/>
+
+	<!-- Overall Project Info -->
+    <menu name="Log4j Project Information" img="icon-info-sign">
+      <item name="Dependencies" href="../dependencies.html" />
+      <item name="Dependency Convergence" href="../dependency-convergence.html" />
+      <item name="Dependency Management" href="../dependency-management.html" />
+      <item name="Project Team" href="../team-list.html" />
+      <item name="Mailing Lists" href="../mail-lists.html" />
+      <item name="Issue Tracking" href="../issue-tracking.html" />
+      <item name="Project License" href="../license.html" />
+      <item name="Source Repository" href="../source-repository.html" />
+      <item name="Project Summary" href="../project-summary.html" />
+    </menu>
+
+    <menu name="Log4j Project Reports" img="icon-cog">
+      <item name="Changes Report" href="../changes-report.html" />
+      <item name="JIRA Report" href="../jira-report.html" />
+      <item name="Surefire Report" href="../surefire-report.html" />
+      <item name="RAT Report" href="../rat-report.html" />
+    </menu>
+  </body>
+</project>
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/other/pkg/LoggerContextAnchorTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/other/pkg/LoggerContextAnchorTest.java
new file mode 100644
index 0000000000..2b0fe91c20
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/other/pkg/LoggerContextAnchorTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.other.pkg;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.status.StatusData;
+import org.apache.logging.log4j.status.StatusListener;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test LoggerContext lookups by verifying the anchor class representing calling code.
+ */
+public class LoggerContextAnchorTest {
+    private static final String PREFIX = "Log4jLoggerFactory.getContext() found anchor class ";
+
+    @Test
+    public void testLoggerFactoryLookupClass() {
+        String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger(LoggerContextAnchorTest.class));
+        assertEquals(getClass().getName(), fqcn);
+    }
+
+    @Test
+    public void testLoggerFactoryLookupString() {
+        String fqcn = getAnchorFqcn(() -> LoggerFactory.getLogger("custom.logger"));
+        assertEquals(getClass().getName(), fqcn);
+    }
+
+    @Test
+    public void testLoggerFactoryGetILoggerFactoryLookup() {
+        String fqcn = getAnchorFqcn(() -> LoggerFactory.getILoggerFactory().getLogger("custom.logger"));
+        assertEquals(getClass().getName(), fqcn);
+    }
+
+    private static String getAnchorFqcn(Runnable runnable) {
+        List<String> results = new CopyOnWriteArrayList<>();
+        StatusListener listener = new StatusListener() {
+            @Override
+            public void log(StatusData data) {
+                String formattedMessage = data.getMessage().getFormattedMessage();
+                if (formattedMessage.startsWith(PREFIX)) {
+                    results.add(formattedMessage.substring(PREFIX.length()));
+                }
+            }
+
+            @Override
+            public Level getStatusLevel() {
+                return Level.TRACE;
+            }
+
+            @Override
+            public void close() {
+                // nop
+            }
+        };
+        StatusLogger statusLogger = StatusLogger.getLogger();
+        statusLogger.registerListener(listener);
+        try {
+            runnable.run();
+            if (results.isEmpty()) {
+                throw new AssertionError("Failed to locate an anchor lookup status message");
+            }
+            if (results.size() > 1) {
+                throw new AssertionError("Found multiple anchor lines: " + results);
+            }
+            return results.get(0);
+        } finally {
+            statusLogger.removeListener(listener);
+        }
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
new file mode 100644
index 0000000000..7efc0e5090
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.slf4j;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CallerInformationTest {
+
+    // config from log4j-core test-jar
+    private static final String CONFIG = "log4j2-calling-class.xml";
+
+    @ClassRule
+    public static final LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+
+    @Test
+    public void testClassLogger() throws Exception {
+        final ListAppender app = ctx.getListAppender("Class").clear();
+        final Logger logger = LoggerFactory.getLogger("ClassLogger");
+        logger.info("Ignored message contents.");
+        logger.warn("Verifying the caller class is still correct.");
+        logger.error("Hopefully nobody breaks me!");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 3, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller class name.", this.getClass().getName(), message);
+        }
+    }
+
+    @Test
+    public void testMethodLogger() throws Exception {
+        final ListAppender app = ctx.getListAppender("Method").clear();
+        final Logger logger = LoggerFactory.getLogger("MethodLogger");
+        logger.info("More messages.");
+        logger.warn("CATASTROPHE INCOMING!");
+        logger.error("ZOMBIES!!!");
+        logger.warn("brains~~~");
+        logger.info("Itchy. Tasty.");
+        final List<String> messages = app.getMessages();
+        assertEquals("Incorrect number of messages.", 5, messages.size());
+        for (final String message : messages) {
+            assertEquals("Incorrect caller method name.", "testMethodLogger", message);
+        }
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java
new file mode 100644
index 0000000000..0138cead6e
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/CustomFlatMarker.java
@@ -0,0 +1,76 @@
+/*
+ * 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.slf4j;
+
+import java.util.Iterator;
+
+import org.slf4j.Marker;
+
+/**
+ * Test Marker that may contain no reference/parent Markers.
+ * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
+ */
+public class CustomFlatMarker implements Marker {
+    private static final long serialVersionUID = -4115520883240247266L;
+
+    private final String name;
+
+    public CustomFlatMarker(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void add(final Marker reference) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean remove(final Marker reference) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasChildren() {
+        return hasReferences();
+    }
+
+    @Override
+    public boolean hasReferences() {
+        return false;
+    }
+
+    @Override
+    public Iterator<Marker> iterator() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean contains(final Marker other) {
+        return false;
+    }
+
+    @Override
+    public boolean contains(final String name) {
+        return false;
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java
new file mode 100644
index 0000000000..59f69e0d2d
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j1222Test.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.slf4j;
+
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests logging during shutdown.
+ */
+public class Log4j1222Test
+{
+
+	@Test
+	public void homepageRendersSuccessfully()
+	{
+        System.setProperty("log4j.configurationFile", "log4j2-console.xml");
+		Runtime.getRuntime().addShutdownHook(new ShutdownHook());
+	}
+
+	private static class ShutdownHook extends Thread {
+
+		private static class Holder {
+			private static final Logger LOGGER = LoggerFactory.getLogger(Log4j1222Test.class);
+		}
+
+		@Override
+		public void run()
+		{
+			super.run();
+			trigger();
+		}
+
+		private void trigger() {
+			Holder.LOGGER.info("Attempt to trigger");
+			assertTrue("Logger is of type " + Holder.LOGGER.getClass().getName(), Holder.LOGGER instanceof Log4jLogger);
+
+		}
+	}
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.java
new file mode 100644
index 0000000000..8934f29a77
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4j2_1482_Slf4jTest.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.slf4j;
+
+import org.apache.logging.log4j.core.layout.Log4j2_1482_Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests https://issues.apache.org/jira/browse/LOG4J2-1482
+ */
+public class Log4j2_1482_Slf4jTest extends Log4j2_1482_Test {
+
+	@Override
+	protected void log(final int runNumber) {
+		if (runNumber == 2) {
+			// System.out.println("Set a breakpoint here.");
+		}
+		final Logger logger = LoggerFactory.getLogger("auditcsvfile");
+		final int val1 = 9, val2 = 11, val3 = 12;
+		logger.info("Info Message!", val1, val2, val3);
+		logger.info("Info Message!", val1, val2, val3);
+		logger.info("Info Message!", val1, val2, val3);
+	}
+
+}
\ No newline at end of file
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java
new file mode 100644
index 0000000000..ac6ad22b39
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/Log4jMarkerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.slf4j;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class Log4jMarkerTest {
+
+    private static Log4jMarkerFactory markerFactory;
+
+    @BeforeClass
+    public static void startup() {
+        markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
+
+    }
+
+	@Test
+	public void testEquals() {
+		final Marker markerA = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-A");
+		final Marker markerB = MarkerManager.getMarker(Log4jMarkerTest.class.getName() + "-B");
+		final Log4jMarker marker1 = new Log4jMarker(markerFactory, markerA);
+		final Log4jMarker marker2 = new Log4jMarker(markerFactory, markerA);
+		final Log4jMarker marker3 = new Log4jMarker(markerFactory, markerB);
+		Assert.assertEquals(marker1, marker2);
+		Assert.assertNotEquals(marker1, null);
+		Assert.assertNotEquals(null, marker1);
+		Assert.assertNotEquals(marker1, marker3);
+	}
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerContextTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerContextTest.java
new file mode 100644
index 0000000000..de37a3614f
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerContextTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.slf4j;
+
+import org.apache.logging.log4j.core.LifeCycle;
+import org.apache.logging.log4j.spi.LoggerContext;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests cleanup of the LoggerContexts.
+ */
+public class LoggerContextTest {
+
+    @Test
+    public void testCleanup() throws Exception {
+        Log4jLoggerFactory factory = (Log4jLoggerFactory) LoggerFactory.getILoggerFactory();
+        factory.getLogger("test");
+        Set<LoggerContext> set = factory.getLoggerContexts();
+        LoggerContext ctx1 = set.toArray(LoggerContext.EMPTY_ARRAY)[0];
+        assertTrue("LoggerContext is not enabled for shutdown", ctx1 instanceof LifeCycle);
+        ((LifeCycle) ctx1).stop();
+        set = factory.getLoggerContexts();
+        assertTrue("Expected no LoggerContexts", set.isEmpty());
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
new file mode 100644
index 0000000000..7c8e71379f
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.slf4j;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.apache.logging.log4j.util.Strings;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.slf4j.Marker;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+import org.slf4j.spi.LocationAwareLogger;
+
+/**
+ *
+ */
+public class LoggerTest {
+
+    private static final String CONFIG = "log4j-test1.xml";
+
+    @ClassRule
+    public static LoggerContextRule ctx = new LoggerContextRule(CONFIG);
+
+    Logger logger = LoggerFactory.getLogger("LoggerTest");
+    XLogger xlogger = XLoggerFactory.getXLogger("LoggerTest");
+
+    @Test
+    public void basicFlow() {
+        xlogger.entry();
+        verify("List", "o.a.l.s.LoggerTest entry MDC{}" + Strings.LINE_SEPARATOR);
+        xlogger.exit();
+        verify("List", "o.a.l.s.LoggerTest exit MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void simpleFlow() {
+        xlogger.entry(CONFIG);
+        verify("List", "o.a.l.s.LoggerTest entry with (log4j-test1.xml) MDC{}" + Strings.LINE_SEPARATOR);
+        xlogger.exit(0);
+        verify("List", "o.a.l.s.LoggerTest exit with (0) MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void throwing() {
+        xlogger.throwing(new IllegalArgumentException("Test Exception"));
+        verify("List", "o.a.l.s.LoggerTest throwing MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void catching() {
+        try {
+            throw new NullPointerException();
+        } catch (final Exception e) {
+            xlogger.catching(e);
+            verify("List", "o.a.l.s.LoggerTest catching MDC{}" + Strings.LINE_SEPARATOR);
+        }
+    }
+
+    @Test
+    public void debug() {
+        logger.debug("Debug message");
+        verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void debugNoParms() {
+        logger.debug("Debug message {}");
+        verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
+        logger.debug("Debug message {}", (Object[]) null);
+        verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
+        ((LocationAwareLogger)logger).log(null, Log4jLogger.class.getName(), LocationAwareLogger.DEBUG_INT,
+            "Debug message {}", null, null);
+        verify("List", "o.a.l.s.LoggerTest Debug message {} MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+
+    @Test
+    public void debugWithParms() {
+        logger.debug("Hello, {}", "World");
+        verify("List", "o.a.l.s.LoggerTest Hello, World MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void mdc() {
+
+        MDC.put("TestYear", "2010");
+        logger.debug("Debug message");
+        verify("List", "o.a.l.s.LoggerTest Debug message MDC{TestYear=2010}" + Strings.LINE_SEPARATOR);
+        MDC.clear();
+        logger.debug("Debug message");
+        verify("List", "o.a.l.s.LoggerTest Debug message MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    /**
+     * @see <a href="https://issues.apache.org/jira/browse/LOG4J2-793">LOG4J2-793</a>
+     */
+    @Test
+    public void supportsCustomSLF4JMarkers() {
+        final Marker marker = new CustomFlatMarker("TEST");
+        logger.debug(marker, "Test");
+        verify("List", "o.a.l.s.LoggerTest Test MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    @Test
+    public void testRootLogger() {
+        final Logger l = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+        assertNotNull("No Root Logger", l);
+        assertEquals(Logger.ROOT_LOGGER_NAME, l.getName());
+    }
+
+    @Test
+    public void doubleSubst() {
+        logger.debug("Hello, {}", "Log4j {}");
+        verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
+        xlogger.debug("Hello, {}", "Log4j {}");
+        verify("List", "o.a.l.s.LoggerTest Hello, Log4j {} MDC{}" + Strings.LINE_SEPARATOR);
+    }
+
+    private void verify(final String name, final String expected) {
+        final ListAppender listApp = ctx.getListAppender(name);
+        assertNotNull("Missing Appender", listApp);
+        final List<String> events = listApp.getMessages();
+        assertTrue("Incorrect number of messages. Expected 1 Actual " + events.size(), events.size()== 1);
+        final String actual = events.get(0);
+        assertEquals("Incorrect message. Expected " + expected + ". Actual " + actual, expected, actual);
+        listApp.clear();
+    }
+
+    @Before
+    @After
+    public void cleanup() {
+        MDC.clear();
+        ctx.getListAppender("List").clear();
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/MarkerTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/MarkerTest.java
new file mode 100644
index 0000000000..c078fe03fe
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/MarkerTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.slf4j;
+
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.MarkerManager;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class MarkerTest {
+
+	private static final String CHILD_MAKER_NAME = MarkerTest.class.getSimpleName() + "-TEST";
+	private static final String PARENT_MARKER_NAME = MarkerTest.class.getSimpleName() + "-PARENT";
+	private static Log4jMarkerFactory markerFactory;
+
+	@BeforeClass
+    public static void startup() {
+	    markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory();
+
+    }
+
+    @Before
+	@After
+	public void clearMarkers() {
+		MarkerManager.clear();
+	}
+
+	@Test
+	public void testAddMarker() {
+		final String childMakerName = CHILD_MAKER_NAME + "-AM";
+		final String parentMarkerName = PARENT_MARKER_NAME + "-AM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMarkerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMarkerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
+
+		assertTrue("Incorrect Marker class", slf4jMarker instanceof Log4jMarker);
+		assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
+				childMakerName, parentMarkerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
+		assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
+				childMakerName, parentMarkerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
+	}
+
+	@Test
+	public void testAddNullMarker() {
+		final String childMarkerName = CHILD_MAKER_NAME + "-ANM";
+		final String parentMakerName = PARENT_MARKER_NAME + "-ANM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
+		final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
+		final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
+		final org.slf4j.Marker nullMarker = null;
+		try {
+			log4jSlf4jParent.add(nullMarker);
+			fail("Expected " + IllegalArgumentException.class.getName());
+		} catch (final IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			log4jSlf4jMarker.add(nullMarker);
+			fail("Expected " + IllegalArgumentException.class.getName());
+		} catch (final IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testAddSameMarker() {
+		final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
+		final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
+		assertTrue(String.format("%s (log4jMarker=%s) is not an instance of %s (log4jParent=%s) in Log4j",
+				childMarkerName, parentMakerName, log4jMarker, log4jParent), log4jMarker.isInstanceOf(log4jParent));
+		assertTrue(String.format("%s (slf4jMarker=%s) is not an instance of %s (log4jParent=%s) in SLF4J",
+				childMarkerName, parentMakerName, slf4jMarker, slf4jParent), slf4jMarker.contains(slf4jParent));
+	}
+
+	@Test
+	public void testEquals() {
+		final String childMarkerName = CHILD_MAKER_NAME + "-ASM";
+		final String parentMakerName = PARENT_MARKER_NAME + "-ASM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jMarker2 = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
+		final Marker log4jMarker2 = MarkerManager.getMarker(childMarkerName);
+		assertEquals(log4jParent, log4jParent);
+		assertEquals(log4jMarker, log4jMarker);
+		assertEquals(log4jMarker, log4jMarker2);
+		assertEquals(slf4jMarker, slf4jMarker2);
+		assertNotEquals(log4jParent, log4jMarker);
+		assertNotEquals(log4jMarker, log4jParent);
+	}
+
+	@Test
+	public void testContainsNullMarker() {
+		final String childMarkerName = CHILD_MAKER_NAME + "-CM";
+		final String parentMakerName = PARENT_MARKER_NAME + "-CM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
+		final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
+		final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
+		final org.slf4j.Marker nullMarker = null;
+		try {
+			Assert.assertFalse(log4jSlf4jParent.contains(nullMarker));
+			fail("Expected " + IllegalArgumentException.class.getName());
+		} catch (final IllegalArgumentException e) {
+			// expected
+		}
+		try {
+			Assert.assertFalse(log4jSlf4jMarker.contains(nullMarker));
+			fail("Expected " + IllegalArgumentException.class.getName());
+		} catch (final IllegalArgumentException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testContainsNullString() {
+		final String childMarkerName = CHILD_MAKER_NAME + "-CS";
+		final String parentMakerName = PARENT_MARKER_NAME + "-CS";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMarkerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMarkerName);
+		final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
+		final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
+		final String nullStr = null;
+		Assert.assertFalse(log4jSlf4jParent.contains(nullStr));
+		Assert.assertFalse(log4jSlf4jMarker.contains(nullStr));
+	}
+
+	@Test
+	public void testRemoveNullMarker() {
+		final String childMakerName = CHILD_MAKER_NAME + "-CM";
+		final String parentMakerName = PARENT_MARKER_NAME + "-CM";
+		final org.slf4j.Marker slf4jMarker = org.slf4j.MarkerFactory.getMarker(childMakerName);
+		final org.slf4j.Marker slf4jParent = org.slf4j.MarkerFactory.getMarker(parentMakerName);
+		slf4jMarker.add(slf4jParent);
+		final Marker log4jParent = MarkerManager.getMarker(parentMakerName);
+		final Marker log4jMarker = MarkerManager.getMarker(childMakerName);
+		final Log4jMarker log4jSlf4jParent = new Log4jMarker(markerFactory, log4jParent);
+		final Log4jMarker log4jSlf4jMarker = new Log4jMarker(markerFactory, log4jMarker);
+		final org.slf4j.Marker nullMarker = null;
+		Assert.assertFalse(log4jSlf4jParent.remove(nullMarker));
+		Assert.assertFalse(log4jSlf4jMarker.remove(nullMarker));
+	}
+
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/OverflowTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/OverflowTest.java
new file mode 100644
index 0000000000..bcb9d0b669
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/OverflowTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.slf4j;
+
+import org.apache.logging.log4j.LoggingException;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Tests StackOverflow when slf4j-impl and to-slf4j are both present.
+ */
+public class OverflowTest {
+
+    @Test
+    public void log() {
+        try {
+            final Logger logger = LoggerFactory.getLogger(OverflowTest.class);
+            fail("Failed to detect inclusion of log4j-to-slf4j");
+        } catch (LoggingException ex) {
+            // Expected exception.
+        } catch (StackOverflowError error) {
+            fail("Failed to detect inclusion of log4j-to-slf4j, caught StackOverflowError");
+        }
+    }
+
+}
diff --git a/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
new file mode 100644
index 0000000000..d3d3db6c03
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.slf4j;
+
+import java.io.Serializable;
+
+import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
+import static org.junit.Assert.*;
+
+/**
+ *
+ */
+public class SerializeTest {
+
+    private static final String CONFIG = "log4j-test1.xml";
+
+    @ClassRule
+    public static final LoggerContextRule CTX = new LoggerContextRule(CONFIG);
+
+    Logger logger = LoggerFactory.getLogger("LoggerTest");
+
+    @Test
+    public void testLogger() throws Exception {
+        assertThat((Serializable) logger, serializesRoundTrip());
+    }
+}
diff --git a/log4j-slf4j20-impl/src/test/resources/log4j-test1.xml b/log4j-slf4j20-impl/src/test/resources/log4j-test1.xml
new file mode 100644
index 0000000000..07a2be6316
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/resources/log4j-test1.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration status="error" name="LoggerTest">
+  <properties>
+    <property name="filename">target/test.log</property>
+  </properties>
+  <ThresholdFilter level="trace"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%C{1.} %m MDC%X%n"/>
+    </Console>
+    <File name="File" fileName="${filename}">
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+    </File>
+    <List name="List">
+      <PatternLayout pattern="%C{1.} %m MDC%X%n%ex{0}"/>
+    </List>
+    <SLF4J name="SLF4J"/>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
+      <AppenderRef ref="File"/>
+    </Logger>
+
+    <Root level="trace">
+      <AppenderRef ref="List"/>
+    </Root>
+  </Loggers>
+
+</configuration>
diff --git a/log4j-slf4j20-impl/src/test/resources/log4j2-1482.xml b/log4j-slf4j20-impl/src/test/resources/log4j2-1482.xml
new file mode 100644
index 0000000000..e17953ca93
--- /dev/null
+++ b/log4j-slf4j20-impl/src/test/resources/log4j2-1482.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <Properties>
+    <Property name="audit-path">target/log4j2-1482</Property>
+    <Property name="file-name">audit</Property>
+    <Property name="file-header">param1,param2,param3${sys:line.separator}
+    </Property>
+  </Properties>
+
+  <Appenders>
+    <RollingFile name="auditfile" fileName="${audit-path}/${file-name}.tmp"
+      filePattern="${audit-path}/${file-name}-%d{yyyy-MM-dd}-%i.csv">
+      <CsvParameterLayout delimiter="," header="${file-header}">
+      </CsvParameterLayout>
+      <Policies>
+        <SizeBasedTriggeringPolicy size="80 B" />
+      </Policies>
+      <DefaultRolloverStrategy max="2" />
+    </RollingFile>
+  </Appenders>
+
+  <Loggers>
+    <Root level="info">
+      <AppenderRef ref="auditfile" />
+    </Root>
+  </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ab737f7a56..5fe11b79d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1726,6 +1726,7 @@
     <module>log4j-1.2-api</module>
     <module>log4j-slf4j-impl</module>
     <module>log4j-slf4j18-impl</module>
+    <module>log4j-slf4j20-impl</module>
     <module>log4j-to-slf4j</module>
     <module>log4j-to-jul</module>
     <module>log4j-jcl</module>