Merge pull request #480 from apache/master-java11

Master java11
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c276e87..fdc4f0a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -31,13 +31,6 @@
           java-package: jdk
           architecture: x64
 
-      - name: Setup JDK 8
-        uses: actions/setup-java@v1
-        with:
-          java-version: 8
-          java-package: jdk
-          architecture: x64
-
       - name: Inspect environment (Linux)
         if: runner.os == 'Linux'
         run: env | grep '^JAVA'
@@ -45,25 +38,27 @@
       - name: Build with Maven (Linux)
         if: runner.os == 'Linux'
         continue-on-error: true
-        run: ./mvnw -V -B --no-transfer-progress -e -DtrimStackTrace=false -Dmaven.test.failure.ignore=true -Dsurefire.rerunFailingTestsCount=1 --global-toolchains .github/workflows/maven-toolchains.xml verify
+        run: ./mvnw -V -B --no-transfer-progress -e -DtrimStackTrace=false -Dmaven.test.failure.ignore=true -Dsurefire.rerunFailingTestsCount=1  verify
 
       - name: Inspect environment (Windows)
         if: runner.os == 'Windows'
         run: set java
 
       - name: Build with Maven (Windows)
+        timeout-minutes: 60
         if: runner.os == 'Windows'
         continue-on-error: true
-        run: ./mvnw -V -B --no-transfer-progress -e "-DtrimStackTrace=false" "-Dmaven.test.failure.ignore=true" "-Dsurefire.rerunFailingTestsCount=1" "-Dlog4j2.junit.fileCleanerSleepPeriodMillis=1000" --global-toolchains ".github\workflows\maven-toolchains.xml" verify
+        run: ./mvnw -V -B --no-transfer-progress -e "-DtrimStackTrace=false" "-Dmaven.test.failure.ignore=true" "-Dsurefire.rerunFailingTestsCount=1" "-Dlog4j2.junit.fileCleanerSleepPeriodMillis=1000" verify
 
       - name: Inspect environment (MacOS)
         if: runner.os == 'macOS'
         run: env | grep '^JAVA'
 
       - name: Build with Maven (MacOS)
+        timeout-minutes: 60
         if: runner.os == 'macOS'
         continue-on-error: true
-        run: ./mvnw -V -B --no-transfer-progress -e -DtrimStackTrace=false -Dmaven.test.failure.ignore=true -Dsurefire.rerunFailingTestsCount=1 --global-toolchains .github/workflows/maven-toolchains.xml verify
+        run: ./mvnw -V -B --no-transfer-progress -e -DtrimStackTrace=false -Dmaven.test.failure.ignore=true -Dsurefire.rerunFailingTestsCount=1 verify
 
       - name: Publish Test Results
         uses: scacap/action-surefire-report@v1
diff --git a/log4j-1.2-api/pom.xml b/log4j-1.2-api/pom.xml
index 2daad49..23eacd8 100644
--- a/log4j-1.2-api/pom.xml
+++ b/log4j-1.2-api/pom.xml
@@ -43,6 +43,11 @@
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
     <!-- Place Felix before Equinox because Felix is signed. -->
     <dependency>
       <groupId>org.apache.felix</groupId>
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
index a5b3090..3ae5c34 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/CallerInformationTest.java
@@ -20,7 +20,7 @@
 

 import java.util.List;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.ClassRule;

 import org.junit.Test;

diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithMDCTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithMDCTest.java
index 997d745..624c806 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithMDCTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithMDCTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.log4j;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithRouteTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithRouteTest.java
index 606e87b..8b647fa 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithRouteTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LogWithRouteTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.log4j;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
index a30dd88..d8623c8 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggingTest.java
@@ -16,7 +16,7 @@
  */

 package org.apache.log4j;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.junit.ClassRule;

 import org.junit.Test;

 

diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/layout/Log4j1XmlLayoutTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/layout/Log4j1XmlLayoutTest.java
index 28579fe..1c2cf71 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/layout/Log4j1XmlLayoutTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/layout/Log4j1XmlLayoutTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.impl.ContextDataFactory;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.ThreadContextRule;
+import org.apache.logging.log4j.test.junit.ThreadContextRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.util.StringMap;
 import org.junit.Rule;
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/pattern/Log4j1NdcPatternConverterTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/pattern/Log4j1NdcPatternConverterTest.java
index 2f0b80f..208bc28 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/pattern/Log4j1NdcPatternConverterTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/pattern/Log4j1NdcPatternConverterTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.ThreadContextStackRule;
+import org.apache.logging.log4j.test.junit.ThreadContextStackRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
index 0576463..919f344 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/util/SerializationTestHelper.java
@@ -50,6 +50,7 @@
      * @throws IOException            on IO error.
      * @throws ClassNotFoundException if class not found.
      */
+    @SuppressWarnings("BanSerializableRead")
     public static Object serializeClone(final Object obj)
         throws IOException, ClassNotFoundException {
         final ByteArrayOutputStream memOut = new ByteArrayOutputStream();
@@ -70,6 +71,7 @@
      * @return deserialized object.
      * @throws Exception thrown on IO or deserialization exception.
      */
+    @SuppressWarnings("BanSerializableRead")
     public static Object deserializeStream(final String witness) throws Exception {
         try (final ObjectInputStream objIs = new ObjectInputStream(new FileInputStream(witness))) {
             return objIs.readObject();
diff --git a/log4j-api-java9/pom.xml b/log4j-api-java9/pom.xml
deleted file mode 100644
index 231ade8..0000000
--- a/log4j-api-java9/pom.xml
+++ /dev/null
@@ -1,168 +0,0 @@
-<?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/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-  <artifactId>log4j-api-java9</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Log4j API Java 9 support</name>
-  <description>The Apache Log4j API (Java 9)</description>
-  <properties>
-    <log4jParentDir>${basedir}/..</log4jParentDir>
-    <docLabel>API Documentation</docLabel>
-    <projectDir>/api</projectDir>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-engine</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[11, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <phase>compile</phase>
-            <goals>
-              <goal>compile</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>default-test-compile</id>
-            <phase>test-compile</phase>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <source>9</source>
-          <target>9</target>
-          <release>9</release>
-          <proc>none</proc>
-          <!-- disable errorprone -->
-          <compilerId>javac</compilerId>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <!-- Do not upgrade until https://issues.apache.org/jira/browse/SUREFIRE-720 is fixed -->
-        <version>2.13</version>
-        <executions>
-          <execution>
-            <id>test</id>
-            <phase>test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <systemPropertyVariables>
-            <java.awt.headless>true</java.awt.headless>
-          </systemPropertyVariables>
-          <includes>
-            <include>**/Test*.java</include>
-            <include>**/*Test.java</include>
-          </includes>
-          <excludes>
-            <exclude>**/*FuncTest.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>zip</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-            <configuration>
-              <finalName>log4j-api-java9-${project.version}</finalName>
-              <appendAssemblyId>false</appendAssemblyId>
-              <descriptors>
-                <descriptor>src/assembly/java9.xml</descriptor>
-              </descriptors>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <version>${deploy.plugin.version}</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-          <skipDeploy>true</skipDeploy>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-doap-plugin</artifactId>
-        <version>1.2</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
-
diff --git a/log4j-api-java9/src/assembly/java9.xml b/log4j-api-java9/src/assembly/java9.xml
deleted file mode 100644
index 58c6387..0000000
--- a/log4j-api-java9/src/assembly/java9.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?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.
--->
-
-<assembly>
-  <id>src</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <baseDirectory>/</baseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${project.build.outputDirectory}</directory>
-      <outputDirectory>/classes/META-INF/versions/9</outputDirectory>
-      <includes>
-        <include>**/*.class</include>
-      </includes>
-      <excludes>
-        <exclude>**/Dummy.class</exclude>
-        <exclude>**/spi/Provider.class</exclude>
-        <exclude>**/util/PropertySource.class</exclude>
-        <exclude>**/util/PrivateSecurityManagerStackTraceUtil.class</exclude>
-        <exclude>**/message/ThreadDumpMessage.class</exclude>
-        <exclude>**/message/ThreadDumpMessage$ThreadInfoFactory.class</exclude>
-      </excludes>
-    </fileSet>
-  </fileSets>
-</assembly>
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java
deleted file mode 100644
index f94d10a..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/log4j/util/PropertySource.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class PropertySource {
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/Dummy.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/Dummy.java
deleted file mode 100644
index 082e36e..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.message;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java
deleted file mode 100644
index 8b1af5d..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/message/ThreadDumpMessage.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.message;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class ThreadDumpMessage {
-    public static interface ThreadInfoFactory {
-
-    }
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/simple/Dummy.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/simple/Dummy.java
deleted file mode 100644
index c3a24e2..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/simple/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.simple;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/spi/Provider.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/spi/Provider.java
deleted file mode 100644
index 65b8638..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/spi/Provider.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.spi;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Provider {
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/PrivateSecurityManagerStackTraceUtil.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/PrivateSecurityManagerStackTraceUtil.java
deleted file mode 100644
index e334bc8..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/PrivateSecurityManagerStackTraceUtil.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util;
-
-import java.util.Stack;
-
-/**
- * This is a dummy class and is only here to allow this module to compile. It will not
- * be copied into the log4j-api module.
- */
-final class PrivateSecurityManagerStackTraceUtil {
-
-    static boolean isEnabled() {
-        return false;
-    }
-
-    static Stack<Class<?>> getCurrentStackTrace() {
-        return null;
-    }
-}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java
deleted file mode 100644
index 6a5c895..0000000
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/StackLocator.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.Stack;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * <em>Consider this class private.</em> Determines the caller's class.
- */
-public class StackLocator {
-
-    private final static StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
-
-    private final static StackWalker stackWalker = StackWalker.getInstance();
-
-    private final static StackLocator INSTANCE = new StackLocator();
-
-    public static StackLocator getInstance() {
-        return INSTANCE;
-    }
-
-    private StackLocator() {
-    }
-
-    public Class<?> getCallerClass(final String fqcn) {
-        return getCallerClass(fqcn, "");
-    }
-
-    public Class<?> getCallerClass(final String fqcn, final String pkg) {
-        return getCallerClass(fqcn, pkg, 0);
-    }
-
-    public Class<?> getCallerClass(final String fqcn, final String pkg, final int skipDepth) {
-        return walker.walk(s -> s
-                .dropWhile(f -> !f.getClassName().equals(fqcn))
-                .dropWhile(f -> f.getClassName().equals(fqcn))
-                .dropWhile(f -> !f.getClassName().startsWith(pkg))
-                .skip(skipDepth)
-                .findFirst())
-                .map(StackWalker.StackFrame::getDeclaringClass)
-                .orElse(null);
-    }
-
-    public Class<?> getCallerClass(final Class<?> anchor) {
-        return walker.walk(s -> s.dropWhile(f -> !f.getDeclaringClass().equals(anchor)).
-                dropWhile(f -> f.getDeclaringClass().equals(anchor)).findFirst()).
-                map(StackWalker.StackFrame::getDeclaringClass).orElse(null);
-    }
-
-    public Class<?> getCallerClass(final int depth) {
-        return walker.walk(s -> s.skip(depth).findFirst()).map(StackWalker.StackFrame::getDeclaringClass).orElse(null);
-    }
-
-    public Stack<Class<?>> getCurrentStackTrace() {
-        // benchmarks show that using the SecurityManager is much faster than looping through getCallerClass(int)
-        if (PrivateSecurityManagerStackTraceUtil.isEnabled()) {
-            return PrivateSecurityManagerStackTraceUtil.getCurrentStackTrace();
-        }
-        Stack<Class<?>> stack = new Stack<Class<?>>();
-        List<Class<?>> classes = walker.walk(s -> s.map(f -> f.getDeclaringClass()).collect(Collectors.toList()));
-        stack.addAll(classes);
-        return stack;
-    }
-
-    public StackTraceElement calcLocation(final String fqcnOfLogger) {
-        return stackWalker.walk(
-                s -> s.dropWhile(f -> !f.getClassName().equals(fqcnOfLogger)) // drop the top frames until we reach the logger
-                        .dropWhile(f -> f.getClassName().equals(fqcnOfLogger)) // drop the logger frames
-                        .findFirst()).map(StackWalker.StackFrame::toStackTraceElement).orElse(null);
-    }
-
-    public StackTraceElement getStackTraceElement(final int depth) {
-        return stackWalker.walk(s -> s.skip(depth).findFirst())
-                .map(StackWalker.StackFrame::toStackTraceElement).orElse(null);
-    }
-}
diff --git a/log4j-api-java9/src/test/java/module-info.java b/log4j-api-java9/src/test/java/module-info.java
deleted file mode 100644
index 8121d75..0000000
--- a/log4j-api-java9/src/test/java/module-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-open module org.apache.logging.log4j.java9test {
-    exports org.apache.logging.log4j.util.java9;
-    requires org.apache.logging.log4j;
-    requires transitive org.junit.jupiter.engine;
-    requires transitive org.junit.jupiter.api;
-}
diff --git a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/ProcessIdUtilTest.java b/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/ProcessIdUtilTest.java
deleted file mode 100644
index c0f22f0..0000000
--- a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/ProcessIdUtilTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util.java9;
-
-import org.apache.logging.log4j.util.ProcessIdUtil;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-
-public class ProcessIdUtilTest {
-
-    @Test
-    public void processIdTest() {
-        String processId = ProcessIdUtil.getProcessId();
-        assertNotEquals(processId, ProcessIdUtil.DEFAULT_PROCESSID, "ProcessId is default");
-    }
-}
diff --git a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/StackLocatorTest.java b/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/StackLocatorTest.java
deleted file mode 100644
index 7cd8c5c..0000000
--- a/log4j-api-java9/src/test/java/org/apache/logging/log4j/util/java9/StackLocatorTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.util.java9;
-
-import org.apache.logging.log4j.util.StackLocator;
-import org.junit.jupiter.api.Test;
-
-import java.util.Stack;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-public class StackLocatorTest {
-
-    @Test
-    public void testGetCallerClass() {
-        final Class<?> expected = StackLocatorTest.class;
-        final StackLocator stackLocator = StackLocator.getInstance();
-        final Class<?> actual = stackLocator.getCallerClass(1);
-        assertSame(expected, actual);
-    }
-
-    @Test
-    public void testGetCallerClassNameViaStackTrace() throws Exception {
-        final Class<?> expected = StackLocatorTest.class;
-        final Class<?> actual = Class.forName(new Throwable().getStackTrace()[0].getClassName());
-        assertSame(expected, actual);
-    }
-
-    @Test
-    public void testGetCurrentStackTrace() {
-        final StackLocator stackLocator = StackLocator.getInstance();
-        final Stack<Class<?>> classes = stackLocator.getCurrentStackTrace();
-        final Stack<Class<?>> reversed = new Stack<>();
-        reversed.ensureCapacity(classes.size());
-        while (!classes.empty()) {
-            reversed.push(classes.pop());
-        }
-        while (reversed.peek() != StackLocator.class) {
-            reversed.pop();
-        }
-        reversed.pop(); // ReflectionUtil
-        assertSame(StackLocatorTest.class, reversed.pop());
-    }
-
-    @Test
-    public void testGetCallerClassViaName() {
-        Inner.assertCallerClassViaName();
-    }
-
-    @Test
-    public void testGetCallerClassViaAnchorClass() {
-        Inner.assertCallerClassViaAnchorClass();
-    }
-
-    private static class Inner {
-        private static void assertCallerClassViaName() {
-            final Class<?> expected = StackLocatorTest.class;
-            final StackLocator stackLocator = StackLocator.getInstance();
-            final Class<?> actual = stackLocator.getCallerClass(Inner.class.getName());
-            assertSame(expected, actual);
-        }
-
-        private static void assertCallerClassViaAnchorClass() {
-            final Class<?> expected = StackLocatorTest.class;
-            final StackLocator stackLocator = StackLocator.getInstance();
-            final Class<?> actual = stackLocator.getCallerClass(Inner.class);
-            assertSame(expected, actual);
-        }
-    }
-
-    @Test
-    public void testLocateClass() {
-        ClassLocator locator = new ClassLocator();
-        Class<?> clazz = locator.locateClass();
-        assertNotNull(clazz, "Could not locate class");
-        assertEquals(this.getClass(), clazz, "Incorrect class");
-    }
-
-    private final class Foo {
-
-        private StackTraceElement foo() {
-            return new Bar().bar(); // <--- testCalcLocation() line
-        }
-
-    }
-
-    private final class Bar {
-
-        private StackTraceElement bar() {
-            return baz();
-        }
-
-        private StackTraceElement baz() {
-            return quux();
-        }
-
-    }
-
-    private StackTraceElement quux() {
-        final StackLocator stackLocator = StackLocator.getInstance();
-        return stackLocator.calcLocation("org.apache.logging.log4j.util.java9.StackLocatorTest$Bar");
-    }
-
-    @Test
-    public void testCalcLocation() {
-        /*
-         * We are setting up a stack trace that looks like:
-         *  - org.apache.logging.log4j.util.test.StackLocatorTest#quux(line:118)
-         *  - org.apache.logging.log4j.util.test.StackLocatorTest$Bar#baz(line:112)
-         *  - org.apache.logging.log4j.util.test.StackLocatorTest$Bar#bar(line:108)
-         *  - org.apache.logging.log4j.util.test.StackLocatorTest$Foo(line:100)
-         *
-         * We are pretending that org.apache.logging.log4j.util.test.StackLocatorTest$Bar is the logging class, and
-         * org.apache.logging.log4j.util.test.StackLocatorTest$Foo is where the log line emanated.
-         */
-        final StackTraceElement element = new Foo().foo();
-        assertEquals("org.apache.logging.log4j.util.java9.StackLocatorTest$Foo", element.getClassName());
-        assertEquals(96, element.getLineNumber());
-    }
-
-    @Test
-    public void testCalcLocationWhenNotInTheStack() {
-        final StackLocator stackLocator = StackLocator.getInstance();
-        final StackTraceElement stackTraceElement = stackLocator.calcLocation("java.util.Logger");
-        assertNull(stackTraceElement);
-    }
-
-    static class ClassLocator {
-
-        public Class<?> locateClass() {
-            final StackLocator stackLocator = StackLocator.getInstance();
-            return stackLocator.getCallerClass(ClassLocator.class);
-        }
-    }
-
-}
diff --git a/log4j-api-test/pom.xml b/log4j-api-test/pom.xml
new file mode 100644
index 0000000..7f23e59
--- /dev/null
+++ b/log4j-api-test/pom.xml
@@ -0,0 +1,124 @@
+<?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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.logging.log4j</groupId>
+    <artifactId>log4j</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+    <relativePath>../</relativePath>
+  </parent>
+  <artifactId>log4j-api-test</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache Log4j API Test Utilities</name>
+  <description>Apache Log4j API Test Utilities</description>
+  <properties>
+    <log4jParentDir>${basedir}/..</log4jParentDir>
+    <docLabel>API Documentation</docLabel>
+    <projectDir>/api</projectDir>
+    <revapi.skip>true</revapi.skip>
+    <maven.doap.skip>true</maven.doap.skip>
+    <module.name>org.apache.logging.log4j.test</module.name>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.junit.vintage</groupId>
+      <artifactId>junit-vintage-engine</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-migrationsupport</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-params</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.hamcrest</groupId>
+          <artifactId>hamcrest-core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>default-jar</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+            <configuration combine.self="override">
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- 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-deploy-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>com.github.spotbugs</groupId>
+        <artifactId>spotbugs-maven-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
+
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
index f5d4d62..c144b35 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
index ce57b80..38fe293 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java
similarity index 94%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java
copy to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java
index 65458ba..43aafd6 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java
@@ -14,13 +14,15 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 
+import org.apache.logging.log4j.test.junit.AbstractExternalFileCleaner;
+
 /**
  * A JUnit test rule to automatically delete files after a test is run.
  * <p>
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java
similarity index 96%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java
copy to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java
index 19fe195..9264d7d 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
@@ -25,6 +25,8 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 
+import org.apache.logging.log4j.test.junit.AbstractExternalFileCleaner;
+
 /**
  * A JUnit test rule to automatically delete folders recursively before
  * (optional) and after (optional) a test is run.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
similarity index 97%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java
copy to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
index 151bb85..619d6f2 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpFiles.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpFiles.java
index e00ca42..c1a9b9a 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanUpFiles.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
similarity index 97%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java
copy to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
index 26f5518..9ac7e84 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtensionContext;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/FileCleaner.java
similarity index 97%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java
copy to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/FileCleaner.java
index 1858666..c76ce21 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/FileCleaner.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtensionContext;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Mutable.java
similarity index 95%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Mutable.java
index b81a12b..2e89bd1 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/Mutable.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 /**
  * Helper class for JUnit tests.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
index 57ac55d..57a9f71 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SerialUtil.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SerialUtil.java
index 211eca6..52ca0e2 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/SerialUtil.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java
rename to log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
index 2d68b58..287b591 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.lang.reflect.Field;
 import java.net.URL;
diff --git a/log4j-api/pom.xml b/log4j-api/pom.xml
index e02efe2..af595e0 100644
--- a/log4j-api/pom.xml
+++ b/log4j-api/pom.xml
@@ -35,18 +35,6 @@
   </properties>
   <dependencies>
     <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api-java9</artifactId>
-      <scope>provided</scope>
-      <type>zip</type>
-    </dependency>
-    <!-- Place Felix before Equinox because Felix is signed. / also place it before org.osgi.core so that its versions of the OSGi classes are used -->
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.framework</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.core</artifactId>
       <scope>provided</scope>
@@ -72,13 +60,8 @@
       <artifactId>assertj-core</artifactId>
     </dependency>
     <dependency>
-      <groupId>org.eclipse.tycho</groupId>
-      <artifactId>org.eclipse.osgi</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -102,31 +85,106 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <version>3.0.2</version>
+        <artifactId>maven-compiler-plugin</artifactId>
         <executions>
           <execution>
-            <id>unpack-classes</id>
-            <phase>prepare-package</phase>
+            <!-- compile first without module-info -->
+            <id>base-compile</id>
             <goals>
-              <goal>unpack</goal>
+              <goal>compile</goal>
             </goals>
+            <phase>generate-sources</phase>
             <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.logging.log4j</groupId>
-                  <artifactId>log4j-api-java9</artifactId>
-                  <version>${project.version}</version>
-                  <type>zip</type>
-                  <overWrite>false</overWrite>
-                </artifactItem>
-              </artifactItems>
-              <includes>**/*.class</includes>
-              <excludes>**/*.java</excludes>
-              <outputDirectory>${project.build.directory}</outputDirectory>
-              <overWriteReleases>false</overWriteReleases>
-              <overWriteSnapshots>true</overWriteSnapshots>
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+            </configuration>
+          </execution>
+          <execution>
+            <!-- compile only the classes used by other modules. -->
+            <id>compile-test-utils</id>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+            <phase>generate-sources</phase>
+            <configuration>
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <compileSourceRoots>
+                <compileSourceRoot>${project.basedir}/src/test/java-test</compileSourceRoot>
+              </compileSourceRoots>
+            </configuration>
+          </execution>
+          <execution>
+            <!-- compile the source -->
+            <id>default-compile</id>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <release>${maven.compiler.release}</release>
+              <showDeprecation>true</showDeprecation>
+              <showWarnings>true</showWarnings>
+              <encoding>UTF-8</encoding>
+              <fork>true</fork>
+              <meminitial>256</meminitial>
+              <maxmem>1024</maxmem>
+              <compilerArgs>
+                <arg>-XDcompilePolicy=simple</arg>
+                <arg>-Xplugin:ErrorProne</arg>
+              </compilerArgs>
+              <compilerArguments>
+                <Xmaxwarns>10000</Xmaxwarns>
+                <Xlint />
+              </compilerArguments>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>com.google.errorprone</groupId>
+                  <artifactId>error_prone_core</artifactId>
+                  <version>${errorprone.version}</version>
+                </path>
+              </annotationProcessorPaths>
+              <forceJavacCompilerUse>true</forceJavacCompilerUse>
+              <parameters>true</parameters>
+              <compileSourceRoots>
+                <compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
+              </compileSourceRoots>
+            </configuration>
+          </execution>
+          <execution>
+            <!-- compile the test source -->
+            <id>default-testCompile</id>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <release>${maven.compiler.release}</release>
+              <showDeprecation>true</showDeprecation>
+              <showWarnings>true</showWarnings>
+              <encoding>UTF-8</encoding>
+              <fork>true</fork>
+              <meminitial>256</meminitial>
+              <maxmem>1024</maxmem>
+              <compilerArgs>
+                <arg>-XDcompilePolicy=simple</arg>
+                <arg>-Xplugin:ErrorProne</arg>
+              </compilerArgs>
+              <compilerArguments>
+                <Xmaxwarns>10000</Xmaxwarns>
+                <Xlint />
+              </compilerArguments>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>com.google.errorprone</groupId>
+                  <artifactId>error_prone_core</artifactId>
+                  <version>${errorprone.version}</version>
+                </path>
+              </annotationProcessorPaths>
+              <forceJavacCompilerUse>true</forceJavacCompilerUse>
+              <parameters>true</parameters>
             </configuration>
           </execution>
         </executions>
@@ -134,17 +192,16 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
-        <version>1.7</version>
+        <version>3.2.0</version>
         <executions>
           <execution>
-            <id>add-source</id>
-            <phase>generate-sources</phase>
+            <phase>process-sources</phase>
             <goals>
               <goal>add-source</goal>
             </goals>
             <configuration>
               <sources>
-                <source>${project.build.directory}/log4j-api-java9</source>
+                <source>src/main/java9</source>
               </sources>
             </configuration>
           </execution>
@@ -152,20 +209,6 @@
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <!-- recompile everything for target VM except the module-info.java -->
-            <configuration>
-              <source>1.8</source>
-              <target>1.8</target>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
           <properties>
@@ -203,7 +246,6 @@
                   <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
                   <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
                   <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
-                  <Multi-Release>true</Multi-Release>
                 </manifestEntries>
               </archive>
             </configuration>
@@ -213,6 +255,7 @@
             <goals>
               <goal>test-jar</goal>
             </goals>
+            <phase>process-resources</phase>
             <configuration>
               <archive>
                 <manifestFile>${manifestfile}</manifestFile>
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/internal/DefaultObjectInputFilter.java b/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultObjectInputFilter.java
similarity index 98%
rename from log4j-api-java9/src/main/java/org/apache/logging/log4j/util/internal/DefaultObjectInputFilter.java
rename to log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultObjectInputFilter.java
index 6e7cee5..2245c1d 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/internal/DefaultObjectInputFilter.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/internal/DefaultObjectInputFilter.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.util.internal;
+package org.apache.logging.log4j.internal;
 
 import java.io.ObjectInputFilter;
 import java.util.Arrays;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
index c0f5884..33fe81a 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ReusableParameterizedMessage.java
@@ -147,26 +147,26 @@
         }
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object... arguments) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object... arguments) {
         init(messagePattern, arguments == null ? 0 : arguments.length, arguments);
         varargs = arguments;
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0) {
         params[0] = p0;
         init(messagePattern, 1, params);
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1) {
         params[0] = p0;
         params[1] = p1;
         init(messagePattern, 2, params);
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2) {
         params[0] = p0;
         params[1] = p1;
         params[2] = p2;
@@ -174,7 +174,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3) {
         params[0] = p0;
         params[1] = p1;
         params[2] = p2;
@@ -183,7 +183,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4) {
         params[0] = p0;
         params[1] = p1;
         params[2] = p2;
@@ -193,7 +193,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5) {
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5) {
         params[0] = p0;
         params[1] = p1;
         params[2] = p2;
@@ -204,7 +204,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
             final Object p6) {
         params[0] = p0;
         params[1] = p1;
@@ -217,7 +217,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
             final Object p6, final Object p7) {
         params[0] = p0;
         params[1] = p1;
@@ -231,7 +231,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
             final Object p6, final Object p7, final Object p8) {
         params[0] = p0;
         params[1] = p1;
@@ -246,7 +246,7 @@
         return this;
     }
 
-    ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
+    protected ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1, final Object p2, final Object p3, final Object p4, final Object p5,
             final Object p6, final Object p7, final Object p8, final Object p9) {
         params[0] = p0;
         params[1] = p1;
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/FilteredObjectInputStream.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/FilteredObjectInputStream.java
index df97fd2..f556f92 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/FilteredObjectInputStream.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/FilteredObjectInputStream.java
@@ -75,6 +75,7 @@
         return allowedClasses;
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Override
     protected Class<?> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException {
         String name = desc.getName();
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index 12b60db..9c37943 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -23,7 +23,9 @@
 import java.security.PrivilegedAction;
 import java.util.Collection;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
+import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -152,15 +154,36 @@
         if (tcl != null) {
             classLoaders.add(tcl);
         }
-	if (!isForceTccl()) {
-            accumulateClassLoaders(LoaderUtil.class.getClassLoader(), classLoaders);
-            accumulateClassLoaders(tcl == null ? null : tcl.getParent(), classLoaders);
-            final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
-            if (systemClassLoader != null) {
-                classLoaders.add(systemClassLoader);
+        ModuleLayer layer = LoaderUtil.class.getModule().getLayer();
+        if (layer == null) {
+            if (!isForceTccl()) {
+                accumulateClassLoaders(LoaderUtil.class.getClassLoader(), classLoaders);
+                accumulateClassLoaders(tcl == null ? null : tcl.getParent(), classLoaders);
+                final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+                if (systemClassLoader != null) {
+                    classLoaders.add(systemClassLoader);
+                }
+            }
+        } else {
+            accumulateLayerClassLoaders(layer, classLoaders);
+            if (layer != ModuleLayer.boot()) {
+                for (Module module : ModuleLayer.boot().modules()) {
+                    accumulateClassLoaders(module.getClassLoader(), classLoaders);
+                }
             }
         }
-        return classLoaders.toArray(new ClassLoader[classLoaders.size()]);
+        return classLoaders.toArray(new ClassLoader[0]);
+    }
+
+    private static void accumulateLayerClassLoaders(ModuleLayer layer, Collection<ClassLoader> classLoaders) {
+        for (Module module : layer.modules()) {
+            accumulateClassLoaders(module.getClassLoader(), classLoaders);
+        }
+        if (layer.parents().size() > 0) {
+            for (ModuleLayer parent : layer.parents()) {
+                accumulateLayerClassLoaders(parent, classLoaders);
+            }
+        }
     }
 
     /**
@@ -346,6 +369,13 @@
         return resources;
     }
 
+    /**
+     * This method will only find resources that follow the JPMS rules for encapsulation. Resources
+     * on the class path should be found as normal along with resources with no package name in all
+     * modules. Resources within packages in modules must declare those resources open to org.apache.logging.log4j.
+     * @param resource The resource to locate.
+     * @return The located resources.
+     */
     static Collection<UrlResource> findUrlResources(final String resource) {
         // @formatter:off
         final ClassLoader[] candidates = {
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ProcessIdUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/ProcessIdUtil.java
similarity index 100%
rename from log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ProcessIdUtil.java
rename to log4j-api/src/main/java/org/apache/logging/log4j/util/ProcessIdUtil.java
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
index 2404ac0..db5bcca 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
@@ -106,7 +106,7 @@
         Method newMethod = null;
         try {
             if (setMethod != null) {
-                Class<?> clazz = Class.forName("org.apache.logging.log4j.util.internal.DefaultObjectInputFilter");
+                Class<?> clazz = Class.forName("org.apache.logging.log4j.internal.DefaultObjectInputFilter");
                 methods = clazz.getMethods();
                 for (Method method : methods) {
                     if (method.getName().equals("newInstance") && Modifier.isStatic(method.getModifiers())) {
@@ -552,6 +552,7 @@
         }
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private static Object unmarshall(final byte[] data, ObjectInputStream inputStream)
             throws IOException, ClassNotFoundException {
         final ByteArrayInputStream bin = new ByteArrayInputStream(data);
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/StackLocator.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/StackLocator.java
index c064080..80299a1 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/StackLocator.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/StackLocator.java
@@ -16,75 +16,23 @@
  */
 package org.apache.logging.log4j.util;
 
-import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
 import java.util.Stack;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
- * <em>Consider this class private.</em> Provides various methods to determine the caller class. <h3>Background</h3>
- * <p>
- * This method, available only in the Oracle/Sun/OpenJDK implementations of the Java Virtual Machine, is a much more
- * efficient mechanism for determining the {@link Class} of the caller of a particular method. When it is not available,
- * a {@link SecurityManager} is the second-best option. When this is also not possible, the {@code StackTraceElement[]}
- * returned by {@link Throwable#getStackTrace()} must be used, and its {@code String} class name converted to a
- * {@code Class} using the slow {@link Class#forName} (which can add an extra microsecond or more for each invocation
- * depending on the runtime ClassLoader hierarchy).
- * </p>
- * <p>
- * During Java 8 development, the {@code sun.reflect.Reflection.getCallerClass(int)} was removed from OpenJDK, and this
- * change was back-ported to Java 7 in version 1.7.0_25 which changed the behavior of the call and caused it to be off
- * by one stack frame. This turned out to be beneficial for the survival of this API as the change broke hundreds of
- * libraries and frameworks relying on the API which brought much more attention to the intended API removal.
- * </p>
- * <p>
- * After much community backlash, the JDK team agreed to restore {@code getCallerClass(int)} and keep its existing
- * behavior for the rest of Java 7. However, the method is deprecated in Java 8, and current Java 9 development has not
- * addressed this API. Therefore, the functionality of this class cannot be relied upon for all future versions of Java.
- * It does, however, work just fine in Sun JDK 1.6, OpenJDK 1.6, Oracle/OpenJDK 1.7, and Oracle/OpenJDK 1.8. Other Java
- * environments may fall back to using {@link Throwable#getStackTrace()} which is significantly slower due to
- * examination of every virtual frame of execution.
- * </p>
+ * <em>Consider this class private.</em> Determines the caller's class.
  */
 public final class StackLocator {
 
-    // Checkstyle Suppress: the lower-case 'u' ticks off CheckStyle...
-    // CHECKSTYLE:OFF
-    static final int JDK_7u25_OFFSET;
-    // CHECKSTYLE:OFF
+    private final static StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
 
-    private static final Method GET_CALLER_CLASS;
+    private final static StackWalker stackWalker = StackWalker.getInstance();
 
-    private static final StackLocator INSTANCE;
-
-    static {
-        Method getCallerClass;
-        int java7u25CompensationOffset = 0;
-        try {
-            final Class<?> sunReflectionClass = LoaderUtil.loadClass("sun.reflect.Reflection");
-            getCallerClass = sunReflectionClass.getDeclaredMethod("getCallerClass", int.class);
-            Object o = getCallerClass.invoke(null, 0);
-            getCallerClass.invoke(null, 0);
-            if (o == null || o != sunReflectionClass) {
-                getCallerClass = null;
-                java7u25CompensationOffset = -1;
-            } else {
-                o = getCallerClass.invoke(null, 1);
-                if (o == sunReflectionClass) {
-                    System.out.println("WARNING: Java 1.7.0_25 is in use which has a broken implementation of Reflection.getCallerClass(). " +
-                        " Please consider upgrading to Java 1.7.0_40 or later.");
-                    java7u25CompensationOffset = 1;
-                }
-            }
-        } catch (final Exception | LinkageError e) {
-            System.out.println("WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.");
-            getCallerClass = null;
-            java7u25CompensationOffset = -1;
-        }
-
-        GET_CALLER_CLASS = getCallerClass;
-        JDK_7u25_OFFSET = java7u25CompensationOffset;
-
-        INSTANCE = new StackLocator();
-    }
+    private final static StackLocator INSTANCE = new StackLocator();
 
     public static StackLocator getInstance() {
         return INSTANCE;
@@ -93,30 +41,11 @@
     private StackLocator() {
     }
 
-    // TODO: return Object.class instead of null (though it will have a null ClassLoader)
-    // (MS) I believe this would work without any modifications elsewhere, but I could be wrong
-
-    // migrated from ReflectiveCallerClassUtility
     @PerformanceSensitive
-    public Class<?> getCallerClass(final int depth) {
-        if (depth < 0) {
-            throw new IndexOutOfBoundsException(Integer.toString(depth));
-        }
-        if (GET_CALLER_CLASS == null) {
-            return null;
-        }
-        // note that we need to add 1 to the depth value to compensate for this method, but not for the Method.invoke
-        // since Reflection.getCallerClass ignores the call to Method.invoke()
-        try {
-            return (Class<?>) GET_CALLER_CLASS.invoke(null, depth + 1 + JDK_7u25_OFFSET);
-        } catch (final Exception e) {
-            // theoretically this could happen if the caller class were native code
-            // TODO: return Object.class
-            return null;
-        }
+    public Class<?> getCallerClass(final String fqcn) {
+        return getCallerClass(fqcn, "");
     }
 
-    // migrated from Log4jLoggerFactory
     @PerformanceSensitive
     public Class<?> getCallerClass(final String fqcn, final String pkg) {
         return getCallerClass(fqcn, pkg, 0);
@@ -124,127 +53,49 @@
 
     @PerformanceSensitive
     public Class<?> getCallerClass(final String fqcn, final String pkg, final int skipDepth) {
-        if (skipDepth < 0) {
-            throw new IllegalArgumentException("skipDepth cannot be negative");
-        }
-        boolean next = false;
-        Class<?> clazz;
-        for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
-            if (fqcn.equals(clazz.getName())) {
-                next = true;
-                continue;
-            }
-            if (next && clazz.getName().startsWith(pkg)) {
-                return skipDepth == 0
-                        ? clazz
-                        : getCallerClass(i + skipDepth);
-            }
-        }
-        // TODO: return Object.class
-        return null;
+        return walker.walk(s -> s
+                .dropWhile(f -> !f.getClassName().equals(fqcn))
+                .dropWhile(f -> f.getClassName().equals(fqcn))
+                .dropWhile(f -> !f.getClassName().startsWith(pkg))
+                .skip(skipDepth)
+                .findFirst())
+                .map(StackWalker.StackFrame::getDeclaringClass)
+                .orElse(null);
     }
 
-    // added for use in LoggerAdapter implementations mainly
     @PerformanceSensitive
     public Class<?> getCallerClass(final Class<?> anchor) {
-        boolean next = false;
-        Class<?> clazz;
-        for (int i = 2; null != (clazz = getCallerClass(i)); i++) {
-            if (anchor.equals(clazz)) {
-                next = true;
-                continue;
-            }
-            if (next) {
-                return clazz;
-            }
-        }
-        return Object.class;
+        return walker.walk(s -> s.dropWhile(f -> !f.getDeclaringClass().equals(anchor)).
+                dropWhile(f -> f.getDeclaringClass().equals(anchor)).findFirst()).
+                map(StackWalker.StackFrame::getDeclaringClass).orElse(null);
     }
 
-    // migrated from ThrowableProxy
+    @PerformanceSensitive
+    public Class<?> getCallerClass(final int depth) {
+        return walker.walk(s -> s.skip(depth).findFirst()).map(StackWalker.StackFrame::getDeclaringClass).orElse(null);
+    }
+
     @PerformanceSensitive
     public Stack<Class<?>> getCurrentStackTrace() {
         // benchmarks show that using the SecurityManager is much faster than looping through getCallerClass(int)
         if (PrivateSecurityManagerStackTraceUtil.isEnabled()) {
             return PrivateSecurityManagerStackTraceUtil.getCurrentStackTrace();
         }
-        // slower version using getCallerClass where we cannot use a SecurityManager
-        final Stack<Class<?>> classes = new Stack<>();
-        Class<?> clazz;
-        for (int i = 1; null != (clazz = getCallerClass(i)); i++) {
-            classes.push(clazz);
-        }
-        return classes;
+        Stack<Class<?>> stack = new Stack<Class<?>>();
+        List<Class<?>> classes = walker.walk(s -> s.map(f -> f.getDeclaringClass()).collect(Collectors.toList()));
+        stack.addAll(classes);
+        return stack;
     }
 
     public StackTraceElement calcLocation(final String fqcnOfLogger) {
-        if (fqcnOfLogger == null) {
-            return null;
-        }
-        // LOG4J2-1029 new Throwable().getStackTrace is faster than Thread.currentThread().getStackTrace().
-        final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
-        boolean found = false;
-        for (int i = 0; i < stackTrace.length; i++) {
-            final String className = stackTrace[i].getClassName();
-            if (fqcnOfLogger.equals(className)) {
-
-                found = true;
-                continue;
-            }
-            if (found  && !fqcnOfLogger.equals(className)) {
-                return stackTrace[i];
-            }
-        }
-        return null;
+        return stackWalker.walk(
+                s -> s.dropWhile(f -> !f.getClassName().equals(fqcnOfLogger)) // drop the top frames until we reach the logger
+                        .dropWhile(f -> f.getClassName().equals(fqcnOfLogger)) // drop the logger frames
+                        .findFirst()).map(StackWalker.StackFrame::toStackTraceElement).orElse(null);
     }
 
     public StackTraceElement getStackTraceElement(final int depth) {
-        // (MS) I tested the difference between using Throwable.getStackTrace() and Thread.getStackTrace(), and
-        // the version using Throwable was surprisingly faster! at least on Java 1.8. See ReflectionBenchmark.
-        final StackTraceElement[] elements = new Throwable().getStackTrace();
-        int i = 0;
-        for (final StackTraceElement element : elements) {
-            if (isValid(element)) {
-                if (i == depth) {
-                    return element;
-                }
-                ++i;
-            }
-        }
-        throw new IndexOutOfBoundsException(Integer.toString(depth));
-    }
-
-    private boolean isValid(final StackTraceElement element) {
-        // ignore native methods (oftentimes are repeated frames)
-        if (element.isNativeMethod()) {
-            return false;
-        }
-        final String cn = element.getClassName();
-        // ignore OpenJDK internal classes involved with reflective invocation
-        if (cn.startsWith("sun.reflect.")) {
-            return false;
-        }
-        final String mn = element.getMethodName();
-        // ignore use of reflection including:
-        // Method.invoke
-        // InvocationHandler.invoke
-        // Constructor.newInstance
-        if (cn.startsWith("java.lang.reflect.") && (mn.equals("invoke") || mn.equals("newInstance"))) {
-            return false;
-        }
-        // ignore use of Java 1.9+ reflection classes
-        if (cn.startsWith("jdk.internal.reflect.")) {
-            return false;
-        }
-        // ignore Class.newInstance
-        if (cn.equals("java.lang.Class") && mn.equals("newInstance")) {
-            return false;
-        }
-        // ignore use of Java 1.7+ MethodHandle.invokeFoo() methods
-        if (cn.equals("java.lang.invoke.MethodHandle") && mn.startsWith("invoke")) {
-            return false;
-        }
-        // any others?
-        return true;
+        return stackWalker.walk(s -> s.skip(depth).findFirst())
+                .map(StackWalker.StackFrame::toStackTraceElement).orElse(null);
     }
 }
diff --git a/log4j-api-java9/src/main/java/module-info.java b/log4j-api/src/main/java9/module-info.java
similarity index 86%
rename from log4j-api-java9/src/main/java/module-info.java
rename to log4j-api/src/main/java9/module-info.java
index 3cb22e0..45d0de3 100644
--- a/log4j-api-java9/src/main/java/module-info.java
+++ b/log4j-api/src/main/java9/module-info.java
@@ -25,4 +25,6 @@
     uses org.apache.logging.log4j.spi.Provider;
     uses org.apache.logging.log4j.util.PropertySource;
     uses org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory;
+    provides org.apache.logging.log4j.util.PropertySource with org.apache.logging.log4j.util.EnvironmentPropertySource,
+        org.apache.logging.log4j.util.SystemPropertiesPropertySource;
 }
diff --git a/log4j-api/src/main/resources/META-INF/MANIFEST.MF b/log4j-api/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/log4j-api/src/main/resources/META-INF/MANIFEST.MF
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractSerializationTest.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/AbstractSerializationTest.java
similarity index 92%
rename from log4j-api/src/test/java/org/apache/logging/log4j/AbstractSerializationTest.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/AbstractSerializationTest.java
index 6ea7540..efe499e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractSerializationTest.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/AbstractSerializationTest.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.io.Serializable;
 
@@ -22,7 +22,7 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import static org.apache.logging.log4j.SerializableMatchers.serializesRoundTrip;
+import static org.apache.logging.log4j.test.SerializableMatchers.serializesRoundTrip;
 import static org.hamcrest.MatcherAssert.assertThat;
 
 /**
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/SerializableMatchers.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/SerializableMatchers.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/SerializableMatchers.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/SerializableMatchers.java
index 7545b96..d98359d 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/SerializableMatchers.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/SerializableMatchers.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.io.Serializable;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLogger.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLogger.java
index b7a820c..5b9c5b6 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/TestLogger.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLogger.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
@@ -22,6 +22,9 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContext.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContext.java
similarity index 95%
rename from log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContext.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContext.java
index 7ca2fd6..c20e4c0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContext.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContext.java
@@ -14,12 +14,13 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.test.TestLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContextFactory.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContextFactory.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContextFactory.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContextFactory.java
index 04ad4a3..0818552 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/TestLoggerContextFactory.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/TestLoggerContextFactory.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.net.URI;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextHolder.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextHolder.java
similarity index 96%
rename from log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextHolder.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextHolder.java
index 4c85bde..35182a4 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextHolder.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextHolder.java
@@ -15,10 +15,11 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
 import java.util.Map;
 
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
 
 /**
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextTest.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextTest.java
similarity index 91%
rename from log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextTest.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextTest.java
index 3b6fb3a..75bb691 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextTest.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextTest.java
@@ -14,13 +14,16 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
+import java.lang.Class;
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
@@ -29,7 +32,14 @@
 @UsingAnyThreadContext
 public class ThreadContextTest {
     public static void reinitThreadContext() {
-        ThreadContext.init();
+        try {
+            Class<ThreadContext> clazz = ThreadContext.class;
+            Method method = clazz.getDeclaredMethod("init");
+            method.setAccessible(true);
+            method.invoke(null);
+        } catch (Exception ex) {
+            fail("Unable to reinitialize ThreadContext");
+        }
     }
 
     @Test
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextUtilityClass.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextUtilityClass.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextUtilityClass.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextUtilityClass.java
index 00d1786..6db64a0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextUtilityClass.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/ThreadContextUtilityClass.java
@@ -14,8 +14,9 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
+package org.apache.logging.log4j.test;
 
+import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.util.Timer;
 
 import java.util.Map;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
similarity index 98%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
index f5d4d62..c144b35 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractExternalFileCleaner.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
similarity index 98%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
index ce57b80..2369ed0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/AbstractFileCleaner.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/AbstractFileCleaner.java
@@ -15,11 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.BeforeEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
@@ -31,6 +27,10 @@
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
 import static org.junit.jupiter.api.Assertions.fail;
 
 abstract class AbstractFileCleaner implements BeforeEachCallback, AfterEachCallback {
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ClassMatchers.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ClassMatchers.java
similarity index 96%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/ClassMatchers.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ClassMatchers.java
index 74f6f7e..0d814f6 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ClassMatchers.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ClassMatchers.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.util.LoaderUtil;
 import org.hamcrest.CustomTypeSafeMatcher;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFiles.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFiles.java
index 65458ba..1782fa0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFiles.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFolders.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFolders.java
index 19fe195..4099eec 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanFolders.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanFolders.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.File;
 import java.io.IOException;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
index 151bb85..bdc185e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpDirectories.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpDirectories.java
@@ -15,9 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.ExtendWith;
+package org.apache.logging.log4j.test.junit;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -26,6 +24,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.junit.jupiter.api.extension.ExtendWith;
+
 /**
  * JUnit extension to automatically clean up a list of directories and their contents before and after test execution.
  * This will automatically retry deletion up to 10 times per file while pausing for 200ms each time.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpFiles.java
similarity index 97%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpFiles.java
index e00ca42..1ad6bca 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/CleanUpFiles.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/CleanUpFiles.java
@@ -15,9 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.ExtendWith;
+package org.apache.logging.log4j.test.junit;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -26,6 +24,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.junit.jupiter.api.extension.ExtendWith;
+
 /**
  * JUnit extension to automatically clean up a list of files before and after test execution.
  * This will automatically retry deletion up to 10 times per file while pausing for 200ms each time.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
similarity index 98%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
index 26f5518..a0f8e02 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/DirectoryCleaner.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/DirectoryCleaner.java
@@ -15,9 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.ExtensionContext;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.IOException;
 import java.nio.file.FileVisitResult;
@@ -29,6 +27,8 @@
 import java.util.Collection;
 import java.util.HashSet;
 
+import org.junit.jupiter.api.extension.ExtensionContext;
+
 class DirectoryCleaner extends AbstractFileCleaner {
     @Override
     Collection<Path> getPathsForTest(final ExtensionContext context) {
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/FileCleaner.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/FileCleaner.java
index 1858666..3ca16ac 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/FileCleaner.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/FileCleaner.java
@@ -15,9 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.ExtensionContext;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.IOException;
 import java.nio.file.Files;
@@ -26,6 +24,8 @@
 import java.util.Collection;
 import java.util.HashSet;
 
+import org.junit.jupiter.api.extension.ExtensionContext;
+
 class FileCleaner extends AbstractFileCleaner {
     @Override
     Collection<Path> getPathsForTest(final ExtensionContext context) {
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/LogManagerLoggerContextFactoryRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LogManagerLoggerContextFactoryRule.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/LogManagerLoggerContextFactoryRule.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LogManagerLoggerContextFactoryRule.java
index 6fcdbd0..6b4d0d9 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/LogManagerLoggerContextFactoryRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LogManagerLoggerContextFactoryRule.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/LoggerContextFactoryExtension.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/LoggerContextFactoryExtension.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
index 1131e1b..0b63e3a 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/LoggerContextFactoryExtension.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/Mutable.java
similarity index 95%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/Mutable.java
index b81a12b..2e89bd1 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/Mutable.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/Mutable.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 /**
  * Helper class for JUnit tests.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
similarity index 98%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
index 57ac55d..57a9f71 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SecurityManagerTestRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SecurityManagerTestRule.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SerialUtil.java
similarity index 95%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SerialUtil.java
index 211eca6..5fe8e2d 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/SerialUtil.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/SerialUtil.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -52,7 +52,7 @@
      * @param data byte array representing the serialized object
      * @return the deserialized object
      */
-    @SuppressWarnings("unchecked")
+    @SuppressWarnings({"unchecked", "BanSerializableRead"})
     public static <T> T deserialize(final byte[] data) {
         try {
             final ByteArrayInputStream bas = new ByteArrayInputStream(data);
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevel.java
similarity index 96%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevel.java
index ef36d97..dcceba9 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevel.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.parallel.ResourceLock;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevelExtension.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevelExtension.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevelExtension.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevelExtension.java
index 2b0a5cd..13a86fa 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevelExtension.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerLevelExtension.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.status.StatusLogger;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerRule.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerRule.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerRule.java
index 987216c..ab41d2c 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/StatusLoggerRule.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.status.StatusLogger;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextExtension.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextExtension.java
similarity index 95%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextExtension.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextExtension.java
index e163578..56ed1d1 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextExtension.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextExtension.java
@@ -15,10 +15,10 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.ThreadContextHolder;
+import org.apache.logging.log4j.test.ThreadContextHolder;
 import org.junit.jupiter.api.extension.AfterEachCallback;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextMapRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextMapRule.java
similarity index 96%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextMapRule.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextMapRule.java
index 6b153fb..deb7c77 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextMapRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextMapRule.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 /**
  * Restores the ThreadContext to it's initial map values after a JUnit test.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextRule.java
similarity index 95%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextRule.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextRule.java
index 1d95bf7..1ec1789 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextRule.java
@@ -14,10 +14,10 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.ThreadContextHolder;
+import org.apache.logging.log4j.test.ThreadContextHolder;
 import org.junit.rules.ExternalResource;
 
 /**
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextStackRule.java
similarity index 96%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextStackRule.java
index b51c0b9..77c74cd 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/ThreadContextStackRule.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 /**
  * Restores the ThreadContext to it's initial stack values after a JUnit test.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
similarity index 98%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java
copy to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
index 2d68b58..287b591 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import java.lang.reflect.Field;
 import java.net.URL;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingAnyThreadContext.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingAnyThreadContext.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingAnyThreadContext.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingAnyThreadContext.java
index cd45243..d0a2993 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingAnyThreadContext.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingAnyThreadContext.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextMap.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextMap.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextMap.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextMap.java
index 19cd705..b42902c 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextMap.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextMap.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextStack.java b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextStack.java
similarity index 97%
rename from log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextStack.java
rename to log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextStack.java
index 5e4fdac..b0b3db5 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/UsingThreadContextStack.java
+++ b/log4j-api/src/test/java-test/org/apache/logging/log4j/test/junit/UsingThreadContextStack.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.test.junit;
 
 import org.junit.jupiter.api.extension.ExtendWith;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
diff --git a/log4j-api/src/test/java/module-info.java b/log4j-api/src/test/java/module-info.java
new file mode 100644
index 0000000..9ff63a2
--- /dev/null
+++ b/log4j-api/src/test/java/module-info.java
@@ -0,0 +1,18 @@
+open module org.apache.logging.log4j {
+    exports org.apache.logging.log4j.test.junit;
+
+    requires com.fasterxml.jackson.core;
+    requires com.fasterxml.jackson.databind;
+    requires org.assertj.core;
+    requires org.junit.jupiter.api;
+    requires org.junit.jupiter.engine;
+    requires org.junit.jupiter.params;
+    requires org.junit.platform.commons;
+    requires org.junit.platform.engine;
+    requires junit;
+
+    uses org.apache.logging.log4j.spi.Provider;
+    provides org.apache.logging.log4j.spi.Provider with org.apache.logging.log4j.TestProvider;
+    uses org.apache.logging.log4j.util.PropertySource;
+    uses org.apache.logging.log4j.message.ThreadDumpMessage.ThreadInfoFactory;
+}
\ No newline at end of file
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
index 817f082..ef0cc47 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/AbstractLoggerTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j;
 
-import org.apache.logging.log4j.junit.StatusLoggerLevel;
+import org.apache.logging.log4j.test.junit.StatusLoggerLevel;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ObjectMessage;
 import org.apache.logging.log4j.message.ParameterizedMessage;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/EventLoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/EventLoggerTest.java
index fe66f2e..91ea0a4 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/EventLoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/EventLoggerTest.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j;
 
 import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.test.TestLogger;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceLock;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerSupplierTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerSupplierTest.java
index 5ca79ab..1f70762 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerSupplierTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerSupplierTest.java
@@ -1,188 +1,188 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-package org.apache.logging.log4j;

-

-import org.apache.logging.log4j.message.FormattedMessage;

-import org.apache.logging.log4j.message.JsonMessage;

-import org.apache.logging.log4j.message.LocalizedMessage;

-import org.apache.logging.log4j.message.MessageFormatMessage;

-import org.apache.logging.log4j.message.ObjectArrayMessage;

-import org.apache.logging.log4j.message.ObjectMessage;

-import org.apache.logging.log4j.message.ParameterizedMessage;

-import org.apache.logging.log4j.message.SimpleMessage;

-import org.apache.logging.log4j.message.StringFormattedMessage;

-import org.apache.logging.log4j.message.ThreadDumpMessage;

-import org.apache.logging.log4j.util.Supplier;

-import org.junit.jupiter.api.AfterEach;

-import org.junit.jupiter.api.BeforeEach;

-import org.junit.jupiter.api.Test;

-import org.junit.jupiter.api.parallel.ResourceAccessMode;

-import org.junit.jupiter.api.parallel.ResourceLock;

-import org.junit.jupiter.api.parallel.Resources;

-

-import java.util.List;

-import java.util.Locale;

-import java.util.Properties;

-

-import static org.assertj.core.api.Assertions.assertThat;

-

-/**

- * Tests Logger APIs with {@link Supplier}.

- */

-@ResourceLock(Resources.LOCALE)

-@ResourceLock("log4j2.TestLogger")

-public class LoggerSupplierTest {

-

-    private final TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");

-

-    private final List<String> results = logger.getEntries();

-

-    Locale defaultLocale;

-

-    @Test

-    public void flowTracing_SupplierOfFormattedMessage() {

-        logger.traceEntry(() -> new FormattedMessage("int foo={}", 1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(int foo=1234567890)")

-                .doesNotContain("FormattedMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfJsonMessage() {

-        Properties props = new Properties();

-        props.setProperty("foo", "bar");

-        logger.traceEntry(() -> new JsonMessage(props));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("\"foo\":\"bar\"")

-                .doesNotContain("JsonMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfLocalizedMessage() {

-        logger.traceEntry(() -> new LocalizedMessage("int foo={}", 1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(int foo=1234567890)")

-                .doesNotContain("LocalizedMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfLong() {

-        logger.traceEntry(() -> 1234567890L);

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(1234567890)")

-                .doesNotContain("SimpleMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfMessageFormatMessage() {

-        logger.traceEntry(() -> new MessageFormatMessage("int foo={0}", 1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(int foo=1,234,567,890)")

-                .doesNotContain("MessageFormatMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfObjectArrayMessage() {

-        logger.traceEntry(() -> new ObjectArrayMessage(1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("([1234567890])")

-                .doesNotContain("ObjectArrayMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfObjectMessage() {

-        logger.traceEntry(() -> new ObjectMessage(1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(1234567890)")

-                .doesNotContain("ObjectMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfParameterizedMessage() {

-        logger.traceEntry(() -> new ParameterizedMessage("int foo={}", 1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(int foo=1234567890)")

-                .doesNotContain("ParameterizedMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfSimpleMessage() {

-        logger.traceEntry(() -> new SimpleMessage("1234567890"));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(1234567890)")

-                .doesNotContain("SimpleMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfString() {

-        logger.traceEntry(() -> "1234567890");

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(1234567890)")

-                .doesNotContain("SimpleMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfStringFormattedMessage() {

-        logger.traceEntry(() -> new StringFormattedMessage("int foo=%,d", 1234567890));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")

-                .contains("(int foo=1,234,567,890)")

-                .doesNotContain("StringFormattedMessage");

-    }

-

-    @Test

-    public void flowTracing_SupplierOfThreadDumpMessage() {

-        logger.traceEntry(() -> new ThreadDumpMessage("Title of ..."));

-        assertThat(results).hasSize(1);

-        String entry = results.get(0);

-        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter").contains("RUNNABLE", "Title of ...", getClass().getName());

-    }

-    

-    @BeforeEach

-    public void setup() {

-        results.clear();

-        defaultLocale = Locale.getDefault(Locale.Category.FORMAT);

-        Locale.setDefault(Locale.Category.FORMAT, java.util.Locale.US);

-    }

-    

-    @AfterEach

-    public void tearDown() {

-        Locale.setDefault(Locale.Category.FORMAT, defaultLocale);

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j;
+
+import org.apache.logging.log4j.message.FormattedMessage;
+import org.apache.logging.log4j.message.JsonMessage;
+import org.apache.logging.log4j.message.LocalizedMessage;
+import org.apache.logging.log4j.message.MessageFormatMessage;
+import org.apache.logging.log4j.message.ObjectArrayMessage;
+import org.apache.logging.log4j.message.ObjectMessage;
+import org.apache.logging.log4j.message.ParameterizedMessage;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.message.StringFormattedMessage;
+import org.apache.logging.log4j.message.ThreadDumpMessage;
+import org.apache.logging.log4j.test.TestLogger;
+import org.apache.logging.log4j.util.Supplier;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
+import org.junit.jupiter.api.parallel.Resources;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests Logger APIs with {@link Supplier}.
+ */
+@ResourceLock(Resources.LOCALE)
+@ResourceLock("log4j2.TestLogger")
+public class LoggerSupplierTest {
+
+    private final TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");
+
+    private final List<String> results = logger.getEntries();
+
+    Locale defaultLocale;
+
+    @Test
+    public void flowTracing_SupplierOfFormattedMessage() {
+        logger.traceEntry(() -> new FormattedMessage("int foo={}", 1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(int foo=1234567890)")
+                .doesNotContain("FormattedMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfJsonMessage() {
+        Properties props = new Properties();
+        props.setProperty("foo", "bar");
+        logger.traceEntry(() -> new JsonMessage(props));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("\"foo\":\"bar\"")
+                .doesNotContain("JsonMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfLocalizedMessage() {
+        logger.traceEntry(() -> new LocalizedMessage("int foo={}", 1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(int foo=1234567890)")
+                .doesNotContain("LocalizedMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfLong() {
+        logger.traceEntry(() -> 1234567890L);
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(1234567890)")
+                .doesNotContain("SimpleMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfMessageFormatMessage() {
+        logger.traceEntry(() -> new MessageFormatMessage("int foo={0}", 1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(int foo=1,234,567,890)")
+                .doesNotContain("MessageFormatMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfObjectArrayMessage() {
+        logger.traceEntry(() -> new ObjectArrayMessage(1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("([1234567890])")
+                .doesNotContain("ObjectArrayMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfObjectMessage() {
+        logger.traceEntry(() -> new ObjectMessage(1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(1234567890)")
+                .doesNotContain("ObjectMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfParameterizedMessage() {
+        logger.traceEntry(() -> new ParameterizedMessage("int foo={}", 1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(int foo=1234567890)")
+                .doesNotContain("ParameterizedMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfSimpleMessage() {
+        logger.traceEntry(() -> new SimpleMessage("1234567890"));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(1234567890)")
+                .doesNotContain("SimpleMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfString() {
+        logger.traceEntry(() -> "1234567890");
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(1234567890)")
+                .doesNotContain("SimpleMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfStringFormattedMessage() {
+        logger.traceEntry(() -> new StringFormattedMessage("int foo=%,d", 1234567890));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter")
+                .contains("(int foo=1,234,567,890)")
+                .doesNotContain("StringFormattedMessage");
+    }
+
+    @Test
+    public void flowTracing_SupplierOfThreadDumpMessage() {
+        logger.traceEntry(() -> new ThreadDumpMessage("Title of ..."));
+        assertThat(results).hasSize(1);
+        String entry = results.get(0);
+        assertThat(entry).startsWith("ENTER[ FLOW ] TRACE Enter").contains("RUNNABLE", "Title of ...", getClass().getName());
+    }
+    
+    @BeforeEach
+    public void setup() {
+        results.clear();
+        defaultLocale = Locale.getDefault(Locale.Category.FORMAT);
+        Locale.setDefault(Locale.Category.FORMAT, java.util.Locale.US);
+    }
+    
+    @AfterEach
+    public void tearDown() {
+        Locale.setDefault(Locale.Category.FORMAT, defaultLocale);
+    }
+
+}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
index 1c25397..8832874 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/LoggerTest.java
@@ -1,633 +1,632 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-package org.apache.logging.log4j;

-

-import org.apache.logging.log4j.message.EntryMessage;

-import org.apache.logging.log4j.message.JsonMessage;

-import org.apache.logging.log4j.message.Message;

-import org.apache.logging.log4j.message.MessageFactory;

-import org.apache.logging.log4j.message.ObjectMessage;

-import org.apache.logging.log4j.message.ParameterizedMessageFactory;

-import org.apache.logging.log4j.message.SimpleMessage;

-import org.apache.logging.log4j.message.SimpleMessageFactory;

-import org.apache.logging.log4j.message.StringFormatterMessageFactory;

-import org.apache.logging.log4j.message.StructuredDataMessage;

-import org.apache.logging.log4j.util.Strings;

-import org.apache.logging.log4j.util.Supplier;

-import org.junit.jupiter.api.BeforeEach;

-import org.junit.jupiter.api.Test;

-import org.junit.jupiter.api.parallel.ResourceAccessMode;

-import org.junit.jupiter.api.parallel.ResourceLock;

-import org.junit.jupiter.api.parallel.Resources;

-

-import java.util.Date;

-import java.util.List;

-import java.util.Locale;

-import java.util.Properties;

-

-import static org.hamcrest.CoreMatchers.*;

-import static org.hamcrest.MatcherAssert.assertThat;

-import static org.junit.jupiter.api.Assertions.*;

-

-@ResourceLock("log4j2.MarkerManager")

-@ResourceLock("log4j2.TestLogger")

-public class LoggerTest {

-

-    private static class TestParameterizedMessageFactory {

-        // empty

-    }

-

-    private static class TestStringFormatterMessageFactory {

-        // empty

-    }

-

-    private final TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");

-    private final Marker marker = MarkerManager.getMarker("test");

-    private final List<String> results = logger.getEntries();

-

-    @Test

-    public void builder() {

-        logger.atDebug().withLocation().log("Hello");

-        logger.atError().withMarker(marker).log("Hello {}", "John");

-        logger.atWarn().withThrowable(new Throwable("This is a test")).log((Message) new SimpleMessage("Log4j rocks!"));

-        assertEquals(3, results.size());

-        assertThat("Incorrect message 1", results.get(0),

-                equalTo(" DEBUG org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:64) Hello"));

-        assertThat("Incorrect message 2", results.get(1), equalTo("test ERROR Hello John"));

-        assertThat("Incorrect message 3", results.get(2),

-                startsWith(" WARN Log4j rocks! java.lang.Throwable: This is a test"));

-        assertThat("Throwable incorrect in message 3", results.get(2),

-                containsString("at org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:66)"));

-    }

-

-    @Test

-    public void basicFlow() {

-        logger.traceEntry();

-        logger.traceExit();

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), equalTo("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("incorrect Exit", results.get(1), equalTo("EXIT[ FLOW ] TRACE Exit"));

-

-    }

-

-    @Test

-    public void flowTracingMessage() {

-        Properties props = new Properties();

-        props.setProperty("foo", "bar");

-        logger.traceEntry(new JsonMessage(props));

-        final Response response = new Response(-1, "Generic error");

-        logger.traceExit(new JsonMessage(response),  response);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("\"foo\":\"bar\""));

-        assertThat("incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("\"message\":\"Generic error\""));

-    }

-

-    @Test

-    public void flowTracingString_ObjectArray1() {

-        logger.traceEntry("doFoo(a={}, b={})", 1, 2);

-        logger.traceExit("doFoo(a=1, b=2): {}", 3);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));

-    }

-

-    @Test

-    public void flowTracingExitValueOnly() {

-        logger.traceEntry("doFoo(a={}, b={})", 1, 2);

-        logger.traceExit(3);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("3"));

-    }

-

-    @Test

-    public void flowTracingString_ObjectArray2() {

-        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);

-        logger.traceExit(msg, 3);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));

-    }

-

-    @Test

-    public void flowTracingVoidReturn() {

-        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);

-        logger.traceExit(msg);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), endsWith("doFoo(a=1, b=2)"));

-    }

-

-    @Test

-    public void flowTracingNoExitArgs() {

-        logger.traceEntry();

-        logger.traceExit();

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-    }

-

-    @Test

-    public void flowTracingNoArgs() {

-        final EntryMessage message = logger.traceEntry();

-        logger.traceExit(message);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-    }

-

-    @Test

-    public void flowTracingString_SupplierOfObjectMessages() {

-        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<Message>() {

-            @Override

-            public Message get() {

-                return new ObjectMessage(1);

-            }

-        }, new Supplier<Message>() {

-            @Override

-            public Message get() {

-                return new ObjectMessage(2);

-            }

-        });

-        logger.traceExit(msg, 3);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));

-    }

-

-    @Test

-    public void flowTracingString_SupplierOfStrings() {

-        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<String>() {

-            @Override

-            public String get() {

-                return "1";

-            }

-        }, new Supplier<String>() {

-            @Override

-            public String get() {

-                return "2";

-            }

-        });

-        logger.traceExit(msg, 3);

-        assertEquals(2, results.size());

-        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));

-        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));

-        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));

-        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));

-    }

-

-    @Test

-    public void catching() {

-        try {

-            throw new NullPointerException();

-        } catch (final Exception e) {

-            logger.catching(e);

-            assertEquals(1, results.size());

-            assertThat("Incorrect Catching",

-                    results.get(0), startsWith("CATCHING[ EXCEPTION ] ERROR Catching java.lang.NullPointerException"));

-        }

-    }

-

-    @Test

-    public void debug() {

-        logger.debug("Debug message");

-        assertEquals(1, results.size());

-        assertTrue(results.get(0).startsWith(" DEBUG Debug message"), "Incorrect message");

-    }

-

-    @Test

-    public void debugObject() {

-        logger.debug(new Date());

-        assertEquals(1, results.size());

-        assertTrue(results.get(0).length() > 7, "Invalid length");

-    }

-

-    @Test

-    public void debugWithParms() {

-        logger.debug("Hello, {}", "World");

-        assertEquals(1, results.size());

-        assertTrue(results.get(0).startsWith(" DEBUG Hello, World"), "Incorrect substitution");

-    }

-

-    @Test

-    public void debugWithParmsAndThrowable() {

-        logger.debug("Hello, {}", "World", new RuntimeException("Test Exception"));

-        assertEquals(1, results.size());

-        assertTrue(

-                results.get(0).startsWith(" DEBUG Hello, World java.lang.RuntimeException: Test Exception"),

-                "Unexpected results: " + results.get(0));

-    }

-

-    @Test

-    public void getFormatterLogger() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger();

-        final TestLogger altLogger = (TestLogger) LogManager.getFormatterLogger(getClass());

-        assertEquals(testLogger.getName(), altLogger.getName());

-        assertNotNull(testLogger);

-        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);

-        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getFormatterLogger_Class() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(TestStringFormatterMessageFactory.class);

-        assertNotNull(testLogger);

-        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);

-        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    private static void assertMessageFactoryInstanceOf(MessageFactory factory, final Class<?> cls) {

-        assertTrue(factory.getClass().isAssignableFrom(cls));

-    }

-

-    @Test

-    public void getFormatterLogger_Object() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(new TestStringFormatterMessageFactory());

-        assertNotNull(testLogger);

-        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);

-        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getFormatterLogger_String() {

-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger("getLogger_String_StringFormatterMessageFactory");

-        assertNotNull(testLogger);

-        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_Class_ParameterizedMessageFactory() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class,

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("{}", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_Class_StringFormatterMessageFactory() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestStringFormatterMessageFactory.class,

-                StringFormatterMessageFactory.INSTANCE);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_Object_ParameterizedMessageFactory() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(),

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("{}", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));

-    }

-

-    private void assertEqualMessageFactory(final MessageFactory messageFactory, final TestLogger testLogger) {

-        MessageFactory actual = testLogger.getMessageFactory();

-        assertEquals(messageFactory, actual);

-    }

-

-    @Test

-    public void getLogger_Object_StringFormatterMessageFactory() {

-        // The TestLogger logger was already created in an instance variable for this class.

-        // The message factory is only used when the logger is created.

-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestStringFormatterMessageFactory(),

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_String_MessageFactoryMismatch() {

-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        final TestLogger testLogger2 = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",

-                ParameterizedMessageFactory.INSTANCE);

-        assertNotNull(testLogger2);

-        //TODO: How to test?

-        //This test context always creates new loggers, other test context impls I tried fail other tests.

-        //assertEquals(messageFactory, testLogger2.getMessageFactory());

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_String_ParameterizedMessageFactory() {

-        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory",

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("{}", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_String_SimpleMessageFactory() {

-        final SimpleMessageFactory messageFactory = SimpleMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("{} %,d {foo}", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(" DEBUG {} %,d {foo}", testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLogger_String_StringFormatterMessageFactory() {

-        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;

-        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",

-                messageFactory);

-        assertNotNull(testLogger);

-        assertEqualMessageFactory(messageFactory, testLogger);

-        testLogger.debug("%,d", Integer.MAX_VALUE);

-        assertEquals(1, testLogger.getEntries().size());

-        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));

-    }

-

-    @Test

-    public void getLoggerByClass() {

-        final Logger classLogger = LogManager.getLogger(LoggerTest.class);

-        assertNotNull(classLogger);

-    }

-

-    @Test

-    public void getLoggerByNullClass() {

-        // Returns a SimpleLogger

-        assertNotNull(LogManager.getLogger((Class<?>) null));

-    }

-

-    @Test

-    public void getLoggerByNullObject() {

-        // Returns a SimpleLogger

-        assertNotNull(LogManager.getLogger((Object) null));

-    }

-

-    @Test

-    public void getLoggerByNullString() {

-        // Returns a SimpleLogger

-        assertNotNull(LogManager.getLogger((String) null));

-    }

-

-    @Test

-    public void getLoggerByObject() {

-        final Logger classLogger = LogManager.getLogger(this);

-        assertNotNull(classLogger);

-        assertEquals(classLogger, LogManager.getLogger(LoggerTest.class));

-    }

-

-    @Test

-    public void getRootLogger() {

-        assertNotNull(LogManager.getRootLogger());

-        assertNotNull(LogManager.getLogger(Strings.EMPTY));

-        assertNotNull(LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));

-        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(Strings.EMPTY));

-        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));

-    }

-

-    @Test

-    public void isAllEnabled() {

-        assertTrue(logger.isEnabled(Level.ALL), "Incorrect level");

-    }

-

-    @Test

-    public void isDebugEnabled() {

-        assertTrue(logger.isDebugEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.DEBUG), "Incorrect level");

-    }

-

-    @Test

-    public void isErrorEnabled() {

-        assertTrue(logger.isErrorEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.ERROR), "Incorrect level");

-    }

-

-    @Test

-    public void isFatalEnabled() {

-        assertTrue(logger.isFatalEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.FATAL), "Incorrect level");

-    }

-

-    @Test

-    public void isInfoEnabled() {

-        assertTrue(logger.isInfoEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.INFO), "Incorrect level");

-    }

-

-    @Test

-    public void isOffEnabled() {

-        assertTrue(logger.isEnabled(Level.OFF), "Incorrect level");

-    }

-

-    @Test

-    public void isTraceEnabled() {

-        assertTrue(logger.isTraceEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.TRACE), "Incorrect level");

-    }

-

-    @Test

-    public void isWarnEnabled() {

-        assertTrue(logger.isWarnEnabled(), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.WARN), "Incorrect level");

-    }

-

-    @Test

-    public void isAllEnabledWithMarker() {

-        assertTrue(logger.isEnabled(Level.ALL, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isDebugEnabledWithMarker() {

-        assertTrue(logger.isDebugEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.DEBUG, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isErrorEnabledWithMarker() {

-        assertTrue(logger.isErrorEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.ERROR, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isFatalEnabledWithMarker() {

-        assertTrue(logger.isFatalEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.FATAL, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isInfoEnabledWithMarker() {

-        assertTrue(logger.isInfoEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.INFO, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isOffEnabledWithMarker() {

-        assertTrue(logger.isEnabled(Level.OFF, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isTraceEnabledWithMarker() {

-        assertTrue(logger.isTraceEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.TRACE, marker), "Incorrect level");

-    }

-

-    @Test

-    public void isWarnEnabledWithMarker() {

-        assertTrue(logger.isWarnEnabled(marker), "Incorrect level");

-        assertTrue(logger.isEnabled(Level.WARN, marker), "Incorrect level");

-    }

-

-    @Test

-    public void mdc() {

-

-        ThreadContext.put("TestYear", Integer.valueOf(2010).toString());

-        logger.debug("Debug message");

-        String testYear = ThreadContext.get("TestYear");

-        assertNotNull(testYear, "Test Year is null");

-        assertEquals("2010", testYear, "Incorrect test year: " + testYear);

-        ThreadContext.clearMap();

-        logger.debug("Debug message");

-        assertEquals(2, results.size());

-        System.out.println("Log line 1: " + results.get(0));

-        System.out.println("log line 2: " + results.get(1));

-        assertTrue(

-                results.get(0).startsWith(" DEBUG Debug message {TestYear=2010}"), "Incorrect MDC: " + results.get(0));

-        assertTrue(

-                results.get(1).startsWith(" DEBUG Debug message"), "MDC not cleared?: " + results.get(1));

-    }

-

-    @Test

-    public void printf() {

-        logger.printf(Level.DEBUG, "Debug message %d", 1);

-        logger.printf(Level.DEBUG, MarkerManager.getMarker("Test"), "Debug message %d", 2);

-        assertEquals(2, results.size());

-        assertThat("Incorrect message", results.get(0), startsWith(" DEBUG Debug message 1"));

-        assertThat("Incorrect message", results.get(1), startsWith("Test DEBUG Debug message 2"));

-    }

-

-    @BeforeEach

-    public void setup() {

-        results.clear();

-    }

-

-    @Test

-    public void structuredData() {

-        ThreadContext.put("loginId", "JohnDoe");

-        ThreadContext.put("ipAddress", "192.168.0.120");

-        ThreadContext.put("locale", Locale.US.getDisplayName());

-        final StructuredDataMessage msg = new StructuredDataMessage("Audit@18060", "Transfer Complete", "Transfer");

-        msg.put("ToAccount", "123456");

-        msg.put("FromAccount", "123457");

-        msg.put("Amount", "200.00");

-        logger.info(MarkerManager.getMarker("EVENT"), msg);

-        ThreadContext.clearMap();

-        assertEquals(1, results.size());

-        assertThat("Incorrect structured data: ", results.get(0), startsWith(

-                "EVENT INFO Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete"));

-    }

-

-    @Test

-    public void throwing() {

-        logger.throwing(new IllegalArgumentException("Test Exception"));

-        assertEquals(1, results.size());

-        assertThat("Incorrect Throwing",

-                results.get(0), startsWith("THROWING[ EXCEPTION ] ERROR Throwing java.lang.IllegalArgumentException: Test Exception"));

-    }

-

-

-    private static class Response {

-        int status;

-        String message;

-

-        public Response(final int status, final String message) {

-            this.status = status;

-            this.message = message;

-        }

-

-        public int getStatus() {

-            return status;

-        }

-

-        public void setStatus(final int status) {

-            this.status = status;

-        }

-

-        public String getMessage() {

-            return message;

-        }

-

-        public void setMessage(final String message) {

-            this.message = message;

-        }

-    }

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j;
+
+import org.apache.logging.log4j.message.EntryMessage;
+import org.apache.logging.log4j.message.JsonMessage;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.message.ObjectMessage;
+import org.apache.logging.log4j.message.ParameterizedMessageFactory;
+import org.apache.logging.log4j.message.SimpleMessage;
+import org.apache.logging.log4j.message.SimpleMessageFactory;
+import org.apache.logging.log4j.message.StringFormatterMessageFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.apache.logging.log4j.test.TestLogger;
+import org.apache.logging.log4j.util.Strings;
+import org.apache.logging.log4j.util.Supplier;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.parallel.ResourceLock;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
+
+@ResourceLock("log4j2.MarkerManager")
+@ResourceLock("log4j2.TestLogger")
+public class LoggerTest {
+
+    private static class TestParameterizedMessageFactory {
+        // empty
+    }
+
+    private static class TestStringFormatterMessageFactory {
+        // empty
+    }
+
+    private final TestLogger logger = (TestLogger) LogManager.getLogger("LoggerTest");
+    private final Marker marker = MarkerManager.getMarker("test");
+    private final List<String> results = logger.getEntries();
+
+    @Test
+    public void builder() {
+        logger.atDebug().withLocation().log("Hello");
+        logger.atError().withMarker(marker).log("Hello {}", "John");
+        logger.atWarn().withThrowable(new Throwable("This is a test")).log((Message) new SimpleMessage("Log4j rocks!"));
+        assertEquals(3, results.size());
+        assertThat("Incorrect message 1", results.get(0),
+                equalTo(" DEBUG org.apache.logging.log4j/org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:63) Hello"));
+        assertThat("Incorrect message 2", results.get(1), equalTo("test ERROR Hello John"));
+        assertThat("Incorrect message 3", results.get(2),
+                startsWith(" WARN Log4j rocks! java.lang.Throwable: This is a test"));
+        assertThat("Throwable incorrect in message 3", results.get(2),
+                containsString("at org.apache.logging.log4j/org.apache.logging.log4j.LoggerTest.builder(LoggerTest.java:65)"));
+    }
+
+    @Test
+    public void basicFlow() {
+        logger.traceEntry();
+        logger.traceExit();
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), equalTo("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("incorrect Exit", results.get(1), equalTo("EXIT[ FLOW ] TRACE Exit"));
+
+    }
+
+    @Test
+    public void flowTracingMessage() {
+        Properties props = new Properties();
+        props.setProperty("foo", "bar");
+        logger.traceEntry(new JsonMessage(props));
+        final Response response = new Response(-1, "Generic error");
+        logger.traceExit(new JsonMessage(response),  response);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("\"foo\":\"bar\""));
+        assertThat("incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("\"message\":\"Generic error\""));
+    }
+
+    @Test
+    public void flowTracingString_ObjectArray1() {
+        logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+        logger.traceExit("doFoo(a=1, b=2): {}", 3);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+    }
+
+    @Test
+    public void flowTracingExitValueOnly() {
+        logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+        logger.traceExit(3);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("3"));
+    }
+
+    @Test
+    public void flowTracingString_ObjectArray2() {
+        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+        logger.traceExit(msg, 3);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+    }
+
+    @Test
+    public void flowTracingVoidReturn() {
+        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", 1, 2);
+        logger.traceExit(msg);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), endsWith("doFoo(a=1, b=2)"));
+    }
+
+    @Test
+    public void flowTracingNoExitArgs() {
+        logger.traceEntry();
+        logger.traceExit();
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+    }
+
+    @Test
+    public void flowTracingNoArgs() {
+        final EntryMessage message = logger.traceEntry();
+        logger.traceExit(message);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+    }
+
+    @Test
+    public void flowTracingString_SupplierOfObjectMessages() {
+        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<Message>() {
+            @Override
+            public Message get() {
+                return new ObjectMessage(1);
+            }
+        }, new Supplier<Message>() {
+            @Override
+            public Message get() {
+                return new ObjectMessage(2);
+            }
+        });
+        logger.traceExit(msg, 3);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+    }
+
+    @Test
+    public void flowTracingString_SupplierOfStrings() {
+        final EntryMessage msg = logger.traceEntry("doFoo(a={}, b={})", new Supplier<String>() {
+            @Override
+            public String get() {
+                return "1";
+            }
+        }, new Supplier<String>() {
+            @Override
+            public String get() {
+                return "2";
+            }
+        });
+        logger.traceExit(msg, 3);
+        assertEquals(2, results.size());
+        assertThat("Incorrect Entry", results.get(0), startsWith("ENTER[ FLOW ] TRACE Enter"));
+        assertThat("Missing entry data", results.get(0), containsString("doFoo(a=1, b=2)"));
+        assertThat("Incorrect Exit", results.get(1), startsWith("EXIT[ FLOW ] TRACE Exit"));
+        assertThat("Missing exit data", results.get(1), containsString("doFoo(a=1, b=2): 3"));
+    }
+
+    @Test
+    public void catching() {
+        try {
+            throw new NullPointerException();
+        } catch (final Exception e) {
+            logger.catching(e);
+            assertEquals(1, results.size());
+            assertThat("Incorrect Catching",
+                    results.get(0), startsWith("CATCHING[ EXCEPTION ] ERROR Catching java.lang.NullPointerException"));
+        }
+    }
+
+    @Test
+    public void debug() {
+        logger.debug("Debug message");
+        assertEquals(1, results.size());
+        assertTrue(results.get(0).startsWith(" DEBUG Debug message"), "Incorrect message");
+    }
+
+    @Test
+    public void debugObject() {
+        logger.debug(new Date());
+        assertEquals(1, results.size());
+        assertTrue(results.get(0).length() > 7, "Invalid length");
+    }
+
+    @Test
+    public void debugWithParms() {
+        logger.debug("Hello, {}", "World");
+        assertEquals(1, results.size());
+        assertTrue(results.get(0).startsWith(" DEBUG Hello, World"), "Incorrect substitution");
+    }
+
+    @Test
+    public void debugWithParmsAndThrowable() {
+        logger.debug("Hello, {}", "World", new RuntimeException("Test Exception"));
+        assertEquals(1, results.size());
+        assertTrue(
+                results.get(0).startsWith(" DEBUG Hello, World java.lang.RuntimeException: Test Exception"),
+                "Unexpected results: " + results.get(0));
+    }
+
+    @Test
+    public void getFormatterLogger() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger();
+        final TestLogger altLogger = (TestLogger) LogManager.getFormatterLogger(getClass());
+        assertEquals(testLogger.getName(), altLogger.getName());
+        assertNotNull(testLogger);
+        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getFormatterLogger_Class() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(TestStringFormatterMessageFactory.class);
+        assertNotNull(testLogger);
+        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    private static void assertMessageFactoryInstanceOf(MessageFactory factory, final Class<?> cls) {
+        assertTrue(factory.getClass().isAssignableFrom(cls));
+    }
+
+    @Test
+    public void getFormatterLogger_Object() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger(new TestStringFormatterMessageFactory());
+        assertNotNull(testLogger);
+        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getFormatterLogger_String() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getFormatterLogger("getLogger_String_StringFormatterMessageFactory");
+        assertNotNull(testLogger);
+        assertMessageFactoryInstanceOf(testLogger.getMessageFactory(), StringFormatterMessageFactory.class);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Class_ParameterizedMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final ParameterizedMessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestParameterizedMessageFactory.class,
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Class_StringFormatterMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(TestStringFormatterMessageFactory.class,
+                StringFormatterMessageFactory.INSTANCE);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(StringFormatterMessageFactory.INSTANCE, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_Object_ParameterizedMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestParameterizedMessageFactory(),
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    private void assertEqualMessageFactory(final MessageFactory messageFactory, final TestLogger testLogger) {
+        MessageFactory actual = testLogger.getMessageFactory();
+        assertEquals(messageFactory, actual);
+    }
+
+    @Test
+    public void getLogger_Object_StringFormatterMessageFactory() {
+        // The TestLogger logger was already created in an instance variable for this class.
+        // The message factory is only used when the logger is created.
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger(new TestStringFormatterMessageFactory(),
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_MessageFactoryMismatch() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        final TestLogger testLogger2 = (TestLogger) LogManager.getLogger("getLogger_String_MessageFactoryMismatch",
+                ParameterizedMessageFactory.INSTANCE);
+        assertNotNull(testLogger2);
+        //TODO: How to test?
+        //This test context always creates new loggers, other test context impls I tried fail other tests.
+        //assertEquals(messageFactory, testLogger2.getMessageFactory());
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_ParameterizedMessageFactory() {
+        final ParameterizedMessageFactory messageFactory =  ParameterizedMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_ParameterizedMessageFactory",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("{}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG " + Integer.MAX_VALUE, testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_SimpleMessageFactory() {
+        final SimpleMessageFactory messageFactory = SimpleMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("{} %,d {foo}", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(" DEBUG {} %,d {foo}", testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLogger_String_StringFormatterMessageFactory() {
+        final StringFormatterMessageFactory messageFactory = StringFormatterMessageFactory.INSTANCE;
+        final TestLogger testLogger = (TestLogger) LogManager.getLogger("getLogger_String_StringFormatterMessageFactory",
+                messageFactory);
+        assertNotNull(testLogger);
+        assertEqualMessageFactory(messageFactory, testLogger);
+        testLogger.debug("%,d", Integer.MAX_VALUE);
+        assertEquals(1, testLogger.getEntries().size());
+        assertEquals(String.format(" DEBUG %,d", Integer.MAX_VALUE), testLogger.getEntries().get(0));
+    }
+
+    @Test
+    public void getLoggerByClass() {
+        final Logger classLogger = LogManager.getLogger(LoggerTest.class);
+        assertNotNull(classLogger);
+    }
+
+    @Test
+    public void getLoggerByNullClass() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((Class<?>) null));
+    }
+
+    @Test
+    public void getLoggerByNullObject() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((Object) null));
+    }
+
+    @Test
+    public void getLoggerByNullString() {
+        // Returns a SimpleLogger
+        assertNotNull(LogManager.getLogger((String) null));
+    }
+
+    @Test
+    public void getLoggerByObject() {
+        final Logger classLogger = LogManager.getLogger(this);
+        assertNotNull(classLogger);
+        assertEquals(classLogger, LogManager.getLogger(LoggerTest.class));
+    }
+
+    @Test
+    public void getRootLogger() {
+        assertNotNull(LogManager.getRootLogger());
+        assertNotNull(LogManager.getLogger(Strings.EMPTY));
+        assertNotNull(LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(Strings.EMPTY));
+        assertEquals(LogManager.getRootLogger(), LogManager.getLogger(LogManager.ROOT_LOGGER_NAME));
+    }
+
+    @Test
+    public void isAllEnabled() {
+        assertTrue(logger.isEnabled(Level.ALL), "Incorrect level");
+    }
+
+    @Test
+    public void isDebugEnabled() {
+        assertTrue(logger.isDebugEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.DEBUG), "Incorrect level");
+    }
+
+    @Test
+    public void isErrorEnabled() {
+        assertTrue(logger.isErrorEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.ERROR), "Incorrect level");
+    }
+
+    @Test
+    public void isFatalEnabled() {
+        assertTrue(logger.isFatalEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.FATAL), "Incorrect level");
+    }
+
+    @Test
+    public void isInfoEnabled() {
+        assertTrue(logger.isInfoEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.INFO), "Incorrect level");
+    }
+
+    @Test
+    public void isOffEnabled() {
+        assertTrue(logger.isEnabled(Level.OFF), "Incorrect level");
+    }
+
+    @Test
+    public void isTraceEnabled() {
+        assertTrue(logger.isTraceEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.TRACE), "Incorrect level");
+    }
+
+    @Test
+    public void isWarnEnabled() {
+        assertTrue(logger.isWarnEnabled(), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.WARN), "Incorrect level");
+    }
+
+    @Test
+    public void isAllEnabledWithMarker() {
+        assertTrue(logger.isEnabled(Level.ALL, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isDebugEnabledWithMarker() {
+        assertTrue(logger.isDebugEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.DEBUG, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isErrorEnabledWithMarker() {
+        assertTrue(logger.isErrorEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.ERROR, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isFatalEnabledWithMarker() {
+        assertTrue(logger.isFatalEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.FATAL, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isInfoEnabledWithMarker() {
+        assertTrue(logger.isInfoEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.INFO, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isOffEnabledWithMarker() {
+        assertTrue(logger.isEnabled(Level.OFF, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isTraceEnabledWithMarker() {
+        assertTrue(logger.isTraceEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.TRACE, marker), "Incorrect level");
+    }
+
+    @Test
+    public void isWarnEnabledWithMarker() {
+        assertTrue(logger.isWarnEnabled(marker), "Incorrect level");
+        assertTrue(logger.isEnabled(Level.WARN, marker), "Incorrect level");
+    }
+
+    @Test
+    public void mdc() {
+
+        ThreadContext.put("TestYear", Integer.valueOf(2010).toString());
+        logger.debug("Debug message");
+        String testYear = ThreadContext.get("TestYear");
+        assertNotNull(testYear, "Test Year is null");
+        assertEquals("2010", testYear, "Incorrect test year: " + testYear);
+        ThreadContext.clearMap();
+        logger.debug("Debug message");
+        assertEquals(2, results.size());
+        System.out.println("Log line 1: " + results.get(0));
+        System.out.println("log line 2: " + results.get(1));
+        assertTrue(
+                results.get(0).startsWith(" DEBUG Debug message {TestYear=2010}"), "Incorrect MDC: " + results.get(0));
+        assertTrue(
+                results.get(1).startsWith(" DEBUG Debug message"), "MDC not cleared?: " + results.get(1));
+    }
+
+    @Test
+    public void printf() {
+        logger.printf(Level.DEBUG, "Debug message %d", 1);
+        logger.printf(Level.DEBUG, MarkerManager.getMarker("Test"), "Debug message %d", 2);
+        assertEquals(2, results.size());
+        assertThat("Incorrect message", results.get(0), startsWith(" DEBUG Debug message 1"));
+        assertThat("Incorrect message", results.get(1), startsWith("Test DEBUG Debug message 2"));
+    }
+
+    @BeforeEach
+    public void setup() {
+        results.clear();
+    }
+
+    @Test
+    public void structuredData() {
+        ThreadContext.put("loginId", "JohnDoe");
+        ThreadContext.put("ipAddress", "192.168.0.120");
+        ThreadContext.put("locale", Locale.US.getDisplayName());
+        final StructuredDataMessage msg = new StructuredDataMessage("Audit@18060", "Transfer Complete", "Transfer");
+        msg.put("ToAccount", "123456");
+        msg.put("FromAccount", "123457");
+        msg.put("Amount", "200.00");
+        logger.info(MarkerManager.getMarker("EVENT"), msg);
+        ThreadContext.clearMap();
+        assertEquals(1, results.size());
+        assertThat("Incorrect structured data: ", results.get(0), startsWith(
+                "EVENT INFO Transfer [Audit@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete"));
+    }
+
+    @Test
+    public void throwing() {
+        logger.throwing(new IllegalArgumentException("Test Exception"));
+        assertEquals(1, results.size());
+        assertThat("Incorrect Throwing",
+                results.get(0), startsWith("THROWING[ EXCEPTION ] ERROR Throwing java.lang.IllegalArgumentException: Test Exception"));
+    }
+
+
+    private static class Response {
+        int status;
+        String message;
+
+        public Response(final int status, final String message) {
+            this.status = status;
+            this.message = message;
+        }
+
+        public int getStatus() {
+            return status;
+        }
+
+        public void setStatus(final int status) {
+            this.status = status;
+        }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public void setMessage(final String message) {
+            this.message = message;
+        }
+    }
+}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/TestProvider.java b/log4j-api/src/test/java/org/apache/logging/log4j/TestProvider.java
index f96181a..6eff8c6 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/TestProvider.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/TestProvider.java
@@ -17,6 +17,7 @@
 package org.apache.logging.log4j;
 
 import org.apache.logging.log4j.spi.Provider;
+import org.apache.logging.log4j.test.TestLoggerContextFactory;
 
 /**
  * Binding for the Log4j API.
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextInheritanceTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextInheritanceTest.java
index 76f8ccd..51f8a59 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextInheritanceTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/ThreadContextInheritanceTest.java
@@ -16,7 +16,8 @@
  */
 package org.apache.logging.log4j;
 
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.ThreadContextUtilityClass;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.spi.DefaultThreadContextMap;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/FormattedMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/FormattedMessageTest.java
index ff5913c..70f3c73 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/FormattedMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/FormattedMessageTest.java
@@ -23,7 +23,7 @@
 import java.io.ObjectOutputStream;
 import java.util.Locale;
 
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.apache.logging.log4j.util.Constants;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
@@ -158,6 +158,7 @@
         assertEquals("Test message abc", actual, "Should use initial param value");
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testSerialization() throws IOException, ClassNotFoundException {
         final FormattedMessage expected = new FormattedMessage("Msg", "a", "b", "c");
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/LocalizedMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/LocalizedMessageTest.java
index 918e93d..292ce76 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/LocalizedMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/LocalizedMessageTest.java
@@ -20,7 +20,7 @@
 import java.util.Locale;
 
 import org.apache.commons.lang3.SerializationUtils;
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
 import org.junit.jupiter.api.parallel.ResourceLock;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
index 73be0d0..d420e2b 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.message;
 
-import com.google.common.base.Strings;
 import org.apache.logging.log4j.util.StringBuilderFormattable;
+import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
 
 import java.math.BigDecimal;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageSerializationTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageSerializationTest.java
index 82480b0..5c5a465 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageSerializationTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageSerializationTest.java
@@ -20,7 +20,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.AbstractSerializationTest;
+import org.apache.logging.log4j.test.AbstractSerializationTest;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
 import org.junit.jupiter.api.parallel.ResourceLock;
 import org.junit.jupiter.api.parallel.Resources;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageTest.java
index 2969467..aa7e9b3 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/MessageFormatMessageTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.message;
 
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.apache.logging.log4j.util.Constants;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectArrayMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectArrayMessageTest.java
index cfc8cf5..6196200 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectArrayMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectArrayMessageTest.java
@@ -1,42 +1,42 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-package org.apache.logging.log4j.message;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.assertArrayEquals;

-import static org.junit.jupiter.api.Assertions.assertNull;

-

-/**

- * @since 2.4

- */

-public class ObjectArrayMessageTest {

-    

-    private static final Object[] ARRAY = { "A", "B", "C" };

-    private static final ObjectArrayMessage OBJECT_ARRAY_MESSAGE = new ObjectArrayMessage(ARRAY);

-

-    @Test

-    public void testGetParameters() {

-        assertArrayEquals(ARRAY, OBJECT_ARRAY_MESSAGE.getParameters());

-    }

-

-    @Test

-    public void testGetThrowable() {

-        assertNull(OBJECT_ARRAY_MESSAGE.getThrowable());

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.message;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * @since 2.4
+ */
+public class ObjectArrayMessageTest {
+    
+    private static final Object[] ARRAY = { "A", "B", "C" };
+    private static final ObjectArrayMessage OBJECT_ARRAY_MESSAGE = new ObjectArrayMessage(ARRAY);
+
+    @Test
+    public void testGetParameters() {
+        assertArrayEquals(ARRAY, OBJECT_ARRAY_MESSAGE.getParameters());
+    }
+
+    @Test
+    public void testGetThrowable() {
+        assertNull(OBJECT_ARRAY_MESSAGE.getThrowable());
+    }
+
+}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectMessageTest.java
index c616aa9..4f3218e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/ObjectMessageTest.java
@@ -19,8 +19,8 @@
 import java.io.Serializable;
 import java.math.BigDecimal;
 
-import org.apache.logging.log4j.junit.Mutable;
-import org.apache.logging.log4j.junit.SerialUtil;
+import org.apache.logging.log4j.test.junit.Mutable;
+import org.apache.logging.log4j.test.junit.SerialUtil;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
index 42978a9..1c15c5e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.message;
 
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
index 70cc7c4..262cf8e 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/ReusableParameterizedMessageTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.message;
 
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.junit.jupiter.api.Test;
 
 import java.util.LinkedList;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/StringFormattedMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/StringFormattedMessageTest.java
index 0dd8041..ddd96a6 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/StringFormattedMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/StringFormattedMessageTest.java
@@ -23,7 +23,7 @@
 import java.io.ObjectOutputStream;
 import java.util.Locale;
 
-import org.apache.logging.log4j.junit.Mutable;
+import org.apache.logging.log4j.test.junit.Mutable;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceAccessMode;
 import org.junit.jupiter.api.parallel.ResourceLock;
@@ -113,6 +113,7 @@
         assertEquals("Test message abc", actual, "Should use initial param value");
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testSerialization() throws IOException, ClassNotFoundException {
         final StringFormattedMessage expected = new StringFormattedMessage("Msg", "a", "b", "c");
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/simple/SimpleLoggerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/simple/SimpleLoggerTest.java
index 4f144ac..7e5bdbc 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/simple/SimpleLoggerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/simple/SimpleLoggerTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextFactoryExtension;
+import org.apache.logging.log4j.test.junit.LoggerContextFactoryExtension;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java
index 70c54f9..a7a1214 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextMapTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.spi;
 
-import org.apache.logging.log4j.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceLock;
 import org.junit.jupiter.api.parallel.Resources;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextStackTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextStackTest.java
index 68936a2..b9a1761 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextStackTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/spi/DefaultThreadContextStackTest.java
@@ -21,7 +21,7 @@
 import java.util.Iterator;
 
 import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerAdapterTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerAdapterTest.java
index c2fa28b..6a8ed7b 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerAdapterTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerAdapterTest.java
@@ -17,9 +17,9 @@
 package org.apache.logging.log4j.spi;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.TestLogger;
-import org.apache.logging.log4j.TestLoggerContext;
-import org.apache.logging.log4j.TestLoggerContextFactory;
+import org.apache.logging.log4j.test.TestLogger;
+import org.apache.logging.log4j.test.TestLoggerContext;
+import org.apache.logging.log4j.test.TestLoggerContextFactory;
 import org.apache.logging.log4j.simple.SimpleLoggerContext;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/status/StatusLoggerSerializationTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/status/StatusLoggerSerializationTest.java
index 373fdff..68a282a 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/status/StatusLoggerSerializationTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/status/StatusLoggerSerializationTest.java
@@ -20,7 +20,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.AbstractSerializationTest;
+import org.apache.logging.log4j.test.AbstractSerializationTest;
 import org.junit.Ignore;
 import org.junit.runners.Parameterized.Parameters;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/DeserializerHelper.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/DeserializerHelper.java
index 930471d..31030d3 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/DeserializerHelper.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/DeserializerHelper.java
@@ -26,6 +26,7 @@
  * @see SortedArrayStringMapTest#testDeserializationOfUnknownClass()
  */
 public class DeserializerHelper {
+    @SuppressWarnings("BanSerializableRead")
     public static void main(final String... args) throws Exception {
         final File file = new File(args[0]);
         ObjectInputStream in = null;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/EnvironmentPropertySourceSecurityManagerIT.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/EnvironmentPropertySourceSecurityManagerIT.java
index 1d3dac4..58ed8a1 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/EnvironmentPropertySourceSecurityManagerIT.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/EnvironmentPropertySourceSecurityManagerIT.java
@@ -19,7 +19,7 @@
 
 import java.security.Permission;
 
-import org.apache.logging.log4j.junit.SecurityManagerTestRule;
+import org.apache.logging.log4j.test.junit.SecurityManagerTestRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.jupiter.api.parallel.ResourceLock;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertyFilePropertySourceSecurityManagerIT.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertyFilePropertySourceSecurityManagerIT.java
index 76d363e..c586c9d 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertyFilePropertySourceSecurityManagerIT.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertyFilePropertySourceSecurityManagerIT.java
@@ -23,8 +23,7 @@
 import java.security.Permission;
 import java.util.PropertyPermission;
 
-import org.apache.logging.log4j.junit.SecurityManagerTestRule;
-import org.junit.Assert;
+import org.apache.logging.log4j.test.junit.SecurityManagerTestRule;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
index 209df05..9db29e4 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.util;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.TestLoggerContext;
+import org.apache.logging.log4j.test.TestLoggerContext;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
index 82db1a1..98040a0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
@@ -167,6 +167,7 @@
         return arr.toByteArray();
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private SortedArrayStringMap deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
         final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
         try (final ObjectInputStream in = new FilteredObjectInputStream(inArr)) {
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/StackLocatorUtilTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/StackLocatorUtilTest.java
index c4becc7..08b4dfa 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/StackLocatorUtilTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/StackLocatorUtilTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.logging.log4j.util;
 
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
 import java.util.Stack;
 
 import org.junit.Test;
@@ -26,7 +23,6 @@
 import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.ParentRunner;
 
-import static org.apache.logging.log4j.junit.ClassMatchers.*;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.*;
 import static org.junit.Assume.assumeThat;
@@ -37,14 +33,8 @@
 
     @Test
     public void testStackTraceEquivalence() throws Throwable {
-        String reflectionClassName = "sun.reflect.Reflection";
-        assumeThat("Running in a JDK without deprecated " + reflectionClassName,
-                reflectionClassName, is(loadableClassName()));
-        Class<?> reflectionClass = LoaderUtil.loadClass(reflectionClassName);
-        MethodHandle getCallerClass = MethodHandles.lookup()
-                .findStatic(reflectionClass, "getCallerClass", MethodType.methodType(Class.class, int.class));
         for (int i = 1; i < 15; i++) {
-            final Class<?> expected = (Class<?>) getCallerClass.invoke(i + StackLocator.JDK_7u25_OFFSET);
+            final Class<?> expected = StackLocatorUtilTest.class;
             final Class<?> actual = StackLocatorUtil.getCallerClass(i);
             final Class<?> fallbackActual = Class.forName(
                 StackLocatorUtil.getStackTraceElement(i).getClassName());
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/SystemPropertiesPropertySourceSecurityManagerIT.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/SystemPropertiesPropertySourceSecurityManagerIT.java
index 811222e..fe7014a 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/SystemPropertiesPropertySourceSecurityManagerIT.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/SystemPropertiesPropertySourceSecurityManagerIT.java
@@ -20,8 +20,7 @@
 import java.security.Permission;
 import java.util.PropertyPermission;
 
-import org.apache.logging.log4j.junit.SecurityManagerTestRule;
-import org.junit.Assert;
+import org.apache.logging.log4j.test.junit.SecurityManagerTestRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.jupiter.api.parallel.ResourceLock;
diff --git a/log4j-api/src/test/resources/Log4j-charsets.properties b/log4j-api/src/test/resources/Log4j-charsets.properties
new file mode 100644
index 0000000..b7e4c8e
--- /dev/null
+++ b/log4j-api/src/test/resources/Log4j-charsets.properties
@@ -0,0 +1,48 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache license, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the license for the specific language governing permissions and
+# limitations under the license.
+
+# Mapping based on https://msdn.microsoft.com/en-us/en-en/library/windows/desktop/dd317756(v=vs.85).aspx
+# Reference for supported Java encodings: https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html
+cp65001 = UTF-8
+cp20127 = US-ASCII
+cp54936 = gb18030
+cp28592 = iso-8859-2
+cp28593 = iso-8859-3
+cp28594 = iso-8859-4
+cp28595 = iso-8859-5
+cp28596 = iso-8859-6
+cp28597 = iso-8859-7
+cp28598 = iso-8859-8
+cp28599 = iso-8859-9
+cp28603 = iso-8859-13
+cp28605 = iso-8859-15
+cp51949 = euc-kr
+cp20866 = koi8-r
+cp21866 = koi8-u
+cp10000 = x-MacRoman
+cp10006 = x-MacGreek
+cp10007 = x-MacCyrillic
+cp10029 = x-MacCentralEurope
+cp10081 = x-MacTurkish
+cp57002 = x-ISCII91
+cp57003 = x-ISCII91
+cp57011 = x-ISCII91
+cp57010 = x-ISCII91
+cp57007 = x-ISCII91
+cp57004 = x-ISCII91
+cp57005 = x-ISCII91
+cp57008 = x-ISCII91
+cp57009 = x-ISCII91
+cp708 = ISO-8859-6
diff --git a/log4j-cassandra/pom.xml b/log4j-cassandra/pom.xml
index 4f4e113..5af51cd 100644
--- a/log4j-cassandra/pom.xml
+++ b/log4j-cassandra/pom.xml
@@ -62,6 +62,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
diff --git a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
index 9cd0794..b24643b 100644
--- a/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
+++ b/log4j-cassandra/src/test/java/org/apache/logging/log4j/cassandra/CassandraAppenderIT.java
@@ -27,8 +27,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core-its/pom.xml b/log4j-core-its/pom.xml
index 9d82307..6e10973 100644
--- a/log4j-core-its/pom.xml
+++ b/log4j-core-its/pom.xml
@@ -276,8 +276,8 @@
             <exclude>**/ForceNoDefClassFoundError.*</exclude>
           </excludes>
           <groups>
-            org.apache.logging.log4j.categories.PerformanceTests,
-            org.apache.logging.log4j.categories.Appenders$Jms
+            org.apache.logging.log4j.core.categories.PerformanceTests,
+            org.apache.logging.log4j.core.categories.Appenders$Jms
           </groups>
         </configuration>
       </plugin>
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java
index 541394e..edff772 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/FilterPerformanceComparison.java
@@ -20,7 +20,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.logging.log4j.categories.PerformanceTests;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.After;
 import org.junit.AfterClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceComparison.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceComparison.java
index 2af0421..30636b5 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceComparison.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceComparison.java
@@ -25,7 +25,7 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 
-import org.apache.logging.log4j.categories.PerformanceTests;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Profiler;
 import org.junit.AfterClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceRun.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceRun.java
index 64f0e35..982039a 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceRun.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/PerformanceRun.java
@@ -24,8 +24,8 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 
-import org.apache.logging.log4j.categories.PerformanceTests;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Ignore;
 import org.junit.Test;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/SimplePerfTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/SimplePerfTest.java
index 8498fbc..7a0b430 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/SimplePerfTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/SimplePerfTest.java
@@ -23,7 +23,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.util.Timer;
-import org.apache.logging.log4j.categories.PerformanceTests;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.junit.BeforeClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedPerfTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedPerfTest.java
index 42bd307..e734085 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedPerfTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedPerfTest.java
@@ -21,7 +21,7 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.PerformanceTests;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
 import org.apache.logging.log4j.util.Timer;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedTest.java
index 3df298a..a5363f0 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/ThreadedTest.java
@@ -23,8 +23,8 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.PerformanceTests;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.PerformanceTests;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderTest.java
index 46cd3d8..a0b8df9 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderTest.java
@@ -41,7 +41,7 @@
 import org.apache.logging.log4j.core.net.ssl.TestConstants;
 import org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration;
 import org.apache.logging.log4j.jackson.json.layout.JsonLayout;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusListener;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/JsonCompleteFileAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/JsonCompleteFileAppenderTest.java
index 4c2da52..7111225 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/JsonCompleteFileAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/JsonCompleteFileAppenderTest.java
@@ -24,13 +24,13 @@
 import java.util.List;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.impl.Log4jLogEventTest;
 import org.apache.logging.log4j.core.selector.ContextSelector;
 import org.apache.logging.log4j.core.selector.CoreContextSelectors;
 import org.apache.logging.log4j.core.time.ClockFactory;
-import org.apache.logging.log4j.junit.CleanFiles;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
index abee218..ecccfb0 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SecureSocketAppenderSocketOptionsTest.java
@@ -32,7 +32,7 @@
 import org.apache.logging.log4j.core.net.ssl.TestConstants;
 import org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration;
 import org.apache.logging.log4j.core.util.NullOutputStream;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.AfterClass;
 import org.junit.Assert;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderBufferSizeTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderBufferSizeTest.java
index 85b6b17..8d8b905 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderBufferSizeTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderBufferSizeTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.SocketAppenderTest.TcpSocketTestServer;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.After;
 import org.junit.Before;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderSocketOptionsTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderSocketOptionsTest.java
index 030fa80..db37ffd 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderSocketOptionsTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/SocketAppenderSocketOptionsTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.core.net.SocketOptions;
 import org.apache.logging.log4j.core.net.TcpSocketManager;
 import org.apache.logging.log4j.core.util.NullOutputStream;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.AfterClass;
 import org.junit.Assert;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderTest.java
index eea989a..f25cd4d 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderTest.java
@@ -25,7 +25,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderValidationTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderValidationTest.java
index 9b4da79..9fca9cf 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderValidationTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAppenderValidationTest.java
@@ -29,7 +29,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configurator;
 import org.junit.After;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAsyncAppenderValidationTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAsyncAppenderValidationTest.java
index 1e048b1..2f8b255 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAsyncAppenderValidationTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompactFileAsyncAppenderValidationTest.java
@@ -29,7 +29,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompleteFileAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompleteFileAppenderTest.java
index 9d86f6e..cdf350b 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompleteFileAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlCompleteFileAppenderTest.java
@@ -28,12 +28,12 @@
 import java.util.List;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.selector.ContextSelector;
 import org.apache.logging.log4j.core.selector.CoreContextSelectors;
-import org.apache.logging.log4j.junit.CleanFiles;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlFileAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlFileAppenderTest.java
index 107ef22..c7a6e43 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlFileAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlFileAppenderTest.java
@@ -25,7 +25,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlRandomAccessFileAppenderTest.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlRandomAccessFileAppenderTest.java
index 1794160..3244bfa 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlRandomAccessFileAppenderTest.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/XmlRandomAccessFileAppenderTest.java
@@ -25,7 +25,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core-java9/pom.xml b/log4j-core-java9/pom.xml
deleted file mode 100644
index f0e533e..0000000
--- a/log4j-core-java9/pom.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?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/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-  <artifactId>log4j-core-java9</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Log4j Core Java 9 support</name>
-  <description>The Apache Log4j Implementation (Java 9)</description>
-  <properties>
-    <log4jParentDir>${basedir}/..</log4jParentDir>
-    <docLabel>Log4j Implementation Documentation</docLabel>
-    <projectDir>/core</projectDir>
-  </properties>
-  <dependencies>
-    <!-- Naturally, all implementations require the log4j-api JAR -->
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[11, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <phase>compile</phase>
-            <goals>
-              <goal>compile</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>default-test-compile</id>
-            <phase>test-compile</phase>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <!-- Do not upgrade until https://issues.apache.org/jira/browse/SUREFIRE-720 is fixed -->
-        <version>2.13</version>
-        <executions>
-          <execution>
-            <id>test</id>
-            <phase>test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <systemPropertyVariables>
-            <java.awt.headless>true</java.awt.headless>
-          </systemPropertyVariables>
-          <includes>
-            <include>**/Test*.java</include>
-            <include>**/*Test.java</include>
-          </includes>
-          <excludes>
-            <exclude>**/*FuncTest.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>zip</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-            <configuration>
-              <finalName>log4j-core-java9-${project.version}</finalName>
-              <appendAssemblyId>false</appendAssemblyId>
-              <descriptors>
-                <descriptor>src/assembly/java9.xml</descriptor>
-              </descriptors>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <version>${deploy.plugin.version}</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-          <skipDeploy>true</skipDeploy>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-doap-plugin</artifactId>
-        <version>1.2</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
-
diff --git a/log4j-core-java9/src/assembly/java9.xml b/log4j-core-java9/src/assembly/java9.xml
deleted file mode 100644
index f8f129d..0000000
--- a/log4j-core-java9/src/assembly/java9.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-<?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.
--->
-
-<assembly>
-  <id>src</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <baseDirectory>/</baseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${project.build.outputDirectory}</directory>
-      <outputDirectory>/classes/META-INF/versions/9</outputDirectory>
-      <includes>
-        <include>**/*.class</include>
-      </includes>
-      <excludes>
-        <exclude>module-info.class</exclude>
-        <exclude>**/Dummy.class</exclude>
-        <exclude>**/util/Clock.class</exclude>
-        <exclude>**/util/Instant.class</exclude>
-        <exclude>**/util/MutableInstant.class</exclude>
-        <exclude>**/util/PreciseClock.class</exclude>
-      </excludes>
-    </fileSet>
-    <fileSet>
-      <directory>${project.build.outputDirectory}</directory>
-      <outputDirectory>/classes</outputDirectory>
-      <includes>
-        <include>module-info.class</include>
-      </includes>
-    </fileSet>
-  </fileSets>
-</assembly>
diff --git a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Clock.java b/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Clock.java
deleted file mode 100644
index 8c961d4..0000000
--- a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Clock.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-// This class is here to allow {@link SystemClock}, {@link SystemMillisClock}
-// to compile. It will not be copied into the log4j-core module.
-
-/**
- * Provides the time stamp used in log events.
- */
-public interface Clock {
-    /**
-     * Returns the time in milliseconds since the epoch.
-     *
-     * @return the time in milliseconds since the epoch
-     */
-    long currentTimeMillis();
-}
diff --git a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Instant.java b/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Instant.java
deleted file mode 100644
index 829e486..0000000
--- a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/Instant.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-// This class is here to allow {@link SystemClock}, {@link SystemMillisClock}
-// to compile. It will not be copied into the log4j-core module.
-
-/**
- * Models a point in time, suitable for event timestamps.
- * <p>
- * Provides methods for obtaining high precision time information similar to the
- * <a href="https://docs.oracle.com/javase/9/docs/api/java/time/Instant.html">Instant</a> class introduced in Java 8,
- * while also supporting the legacy millisecond precision API.
- * </p><p>
- * Depending on the platform, time sources ({@link Clock} implementations) may produce high precision or millisecond
- * precision time values. At the same time, some time value consumers (for example timestamp formatters) may only be
- * able to consume time values of millisecond precision, while some others may require a high precision time value.
- * </p><p>
- * This class bridges these two time APIs.
- * </p>
- * @since 2.11.0
- */
-public interface Instant {
-    /**
-     * Gets the number of seconds from the Java epoch of 1970-01-01T00:00:00Z.
-     * <p>
-     * The epoch second count is a simple incrementing count of seconds where second 0 is 1970-01-01T00:00:00Z.
-     * The nanosecond part of the day is returned by {@link #getNanoOfSecond()}.
-     * </p>
-     * @return the seconds from the epoch of 1970-01-01T00:00:00Z
-     */
-    long getEpochSecond();
-
-    /**
-     * Gets the number of nanoseconds, later along the time-line, from the start of the second.
-     * <p>
-     * The nanosecond-of-second value measures the total number of nanoseconds from the second returned by {@link #getEpochSecond()}.
-     * </p>
-     * @return the nanoseconds within the second, always positive, never exceeds {@code 999,999,999}
-     */
-    int getNanoOfSecond();
-
-    /**
-     * Gets the number of milliseconds from the Java epoch of 1970-01-01T00:00:00Z.
-     * <p>
-     * The epoch millisecond count is a simple incrementing count of milliseconds where millisecond 0 is 1970-01-01T00:00:00Z.
-     * The nanosecond part of the day is returned by {@link #getNanoOfMillisecond()}.
-     * </p>
-     * @return the milliseconds from the epoch of 1970-01-01T00:00:00Z
-     */
-    long getEpochMillisecond();
-
-    /**
-     * Gets the number of nanoseconds, later along the time-line, from the start of the millisecond.
-     * <p>
-     * The nanosecond-of-millisecond value measures the total number of nanoseconds from the millisecond returned by {@link #getEpochMillisecond()}.
-     * </p>
-     * @return the nanoseconds within the millisecond, always positive, never exceeds {@code 999,999}
-     */
-    int getNanoOfMillisecond();
-}
diff --git a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/MutableInstant.java b/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/MutableInstant.java
deleted file mode 100644
index a885101..0000000
--- a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/MutableInstant.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-import org.apache.logging.log4j.util.PerformanceSensitive;
-
-import java.io.Serializable;
-
-// This class is here to allow {@link SystemClock}, {@link SystemMillisClock}
-// to compile. It will not be copied into the log4j-core module.
-
-/**
- * An instantaneous point on the time line, used for high-precision log event timestamps.
- * Modelled on <a href="https://docs.oracle.com/javase/9/docs/api/index.html?java/time/class-use/Instant.html">java.time.Instant</a>,
- * except that this version is mutable to prevent allocating temporary objects that need to be garbage-collected later.
- * <p>
- * Instances of this class are <em>not</em> thread-safe and should not be shared between threads.
- * </p>
- *
- * @since 2.11.0
- */
-@PerformanceSensitive("allocation")
-public class MutableInstant implements Instant, Serializable {
-
-    private static final int MILLIS_PER_SECOND = 1000;
-    private static final int NANOS_PER_MILLI = 1000_000;
-    static final int NANOS_PER_SECOND = MILLIS_PER_SECOND * NANOS_PER_MILLI;
-
-    private long epochSecond;
-    private int nanoOfSecond;
-
-    @Override
-    public long getEpochSecond() {
-        return epochSecond;
-    }
-
-    @Override
-    public int getNanoOfSecond() {
-        return nanoOfSecond;
-    }
-
-    @Override
-    public long getEpochMillisecond() {
-        final int millis = nanoOfSecond / NANOS_PER_MILLI;
-        long epochMillisecond = epochSecond * MILLIS_PER_SECOND + millis;
-        return epochMillisecond;
-    }
-
-    @Override
-    public int getNanoOfMillisecond() {
-        final int millis = nanoOfSecond / NANOS_PER_MILLI;
-        int nanoOfMillisecond = nanoOfSecond - (millis * NANOS_PER_MILLI); // cheaper than nanoOfSecond % NANOS_PER_MILLI
-        return nanoOfMillisecond;
-    }
-
-    public void initFrom(final Instant other) {
-        this.epochSecond = other.getEpochSecond();
-        this.nanoOfSecond = other.getNanoOfSecond();
-    }
-
-    /**
-     * Updates the fields of this {@code MutableInstant} from the specified epoch millis.
-     * @param epochMilli the number of milliseconds from the Java epoch of 1970-01-01T00:00:00Z
-     * @param nanoOfMillisecond the number of nanoseconds, later along the time-line, from the start of the millisecond
-     */
-    public void initFromEpochMilli(final long epochMilli, final int nanoOfMillisecond) {
-        validateNanoOfMillisecond(nanoOfMillisecond);
-        this.epochSecond = epochMilli / MILLIS_PER_SECOND;
-        this.nanoOfSecond = (int) (epochMilli - (epochSecond * MILLIS_PER_SECOND)) * NANOS_PER_MILLI + nanoOfMillisecond;
-    }
-
-    private void validateNanoOfMillisecond(final int nanoOfMillisecond) {
-        if (nanoOfMillisecond < 0 || nanoOfMillisecond >= NANOS_PER_MILLI) {
-            throw new IllegalArgumentException("Invalid nanoOfMillisecond " + nanoOfMillisecond);
-        }
-    }
-
-    public void initFrom(final Clock clock) {
-        if (clock instanceof PreciseClock) {
-            ((PreciseClock) clock).init(this);
-        } else {
-            initFromEpochMilli(clock.currentTimeMillis(), 0);
-        }
-    }
-
-    /**
-     * Updates the fields of this {@code MutableInstant} from the specified instant components.
-     * @param epochSecond the number of seconds from the Java epoch of 1970-01-01T00:00:00Z
-     * @param nano the number of nanoseconds, later along the time-line, from the start of the second
-     */
-    public void initFromEpochSecond(final long epochSecond, final int nano) {
-        validateNanoOfSecond(nano);
-        this.epochSecond = epochSecond;
-        this.nanoOfSecond = nano;
-    }
-
-    private void validateNanoOfSecond(final int nano) {
-        if (nano < 0 || nano >= NANOS_PER_SECOND) {
-            throw new IllegalArgumentException("Invalid nanoOfSecond " + nano);
-        }
-    }
-
-    /**
-     * Updates the elements of the specified {@code long[]} result array from the specified instant components.
-     * @param epochSecond (input) the number of seconds from the Java epoch of 1970-01-01T00:00:00Z
-     * @param nano (input) the number of nanoseconds, later along the time-line, from the start of the second
-     * @param result (output) a two-element array to store the result: the first element is the number of milliseconds
-     *               from the Java epoch of 1970-01-01T00:00:00Z,
-     *               the second element is the number of nanoseconds, later along the time-line, from the start of the millisecond
-     */
-    public static void instantToMillisAndNanos(final long epochSecond, final int nano, final long[] result) {
-        int millis = nano / NANOS_PER_MILLI;
-        result[0] = epochSecond * MILLIS_PER_SECOND + millis;
-        result[1] = nano - (millis * NANOS_PER_MILLI); // cheaper than nanoOfSecond % NANOS_PER_MILLI
-    }
-
-    @Override
-    public boolean equals(final Object object) {
-        if (object == this) {
-            return true;
-        }
-        if (!(object instanceof MutableInstant)) {
-            return false;
-        }
-        MutableInstant other = (MutableInstant) object;
-        return epochSecond == other.epochSecond && nanoOfSecond == other.nanoOfSecond;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = 17;
-        result = 31 * result + (int) (epochSecond ^ (epochSecond >>> 32));
-        result = 31 * result + nanoOfSecond;
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return "MutableInstant[epochSecond=" + epochSecond + ", nano=" + nanoOfSecond + "]";
-    }
-}
diff --git a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/PreciseClock.java b/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/PreciseClock.java
deleted file mode 100644
index 7dc0700..0000000
--- a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/PreciseClock.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-// This class is here to allow {@link SystemClock}, {@link SystemMillisClock}
-// to compile. It will not be copied into the log4j-core module.
-
-/**
- * Extension of the {@link Clock} interface that is able to provide more accurate time information than milliseconds
- * since the epoch. {@code PreciseClock} implementations are free to return millisecond-precision time
- * if that is the most accurate time information available on this platform.
- * @since 2.11.0
- */
-public interface PreciseClock extends Clock {
-
-    /**
-     * Initializes the specified instant with time information as accurate as available on this platform.
-     * @param mutableInstant the container to be initialized with the accurate time information
-     * @since 2.11.0
-     */
-    void init(final MutableInstant mutableInstant);
-}
diff --git a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/SystemClock.java b/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/SystemClock.java
deleted file mode 100644
index 6eb2379..0000000
--- a/log4j-core-java9/src/main/java/org/apache/logging/log4j/core/util/SystemClock.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-import java.time.Instant;
-
-/**
- * Implementation of the {@code Clock} interface that returns the system time.
- * @since 2.11.0
- */
-public final class SystemClock implements Clock, PreciseClock {
-
-    /**
-     * Returns the system time.
-     * @return the result of calling {@code System.currentTimeMillis()}
-     */
-    @Override
-    public long currentTimeMillis() {
-        return System.currentTimeMillis();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void init(MutableInstant mutableInstant) {
-        Instant instant = java.time.Clock.systemUTC().instant();
-        mutableInstant.initFromEpochSecond(instant.getEpochSecond(), instant.getNano());
-    }
-}
diff --git a/log4j-core-java9/src/test/java/org/apache/logging/log4j/core/util/Dummy.java b/log4j-core-java9/src/test/java/org/apache/logging/log4j/core/util/Dummy.java
deleted file mode 100644
index 6bffac6..0000000
--- a/log4j-core-java9/src/test/java/org/apache/logging/log4j/core/util/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.core.util;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 7d4b224..f7d81f8 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -44,13 +44,6 @@
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-plugins</artifactId>
     </dependency>
-    <!-- Classes and resources to be shaded into the core jar -->
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core-java9</artifactId>
-      <scope>provided</scope>
-      <type>zip</type>
-    </dependency>
     <!-- Used for OSGi bundle support -->
     <dependency>
       <groupId>org.osgi</groupId>
@@ -350,55 +343,6 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <version>3.0.2</version>
-        <executions>
-          <execution>
-            <id>unpack-classes</id>
-            <phase>prepare-package</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.logging.log4j</groupId>
-                  <artifactId>log4j-core-java9</artifactId>
-                  <version>${project.version}</version>
-                  <type>zip</type>
-                  <overWrite>false</overWrite>
-                </artifactItem>
-              </artifactItems>
-              <includes>**/*.class</includes>
-              <excludes>**/*.java</excludes>
-              <outputDirectory>${project.build.directory}</outputDirectory>
-              <overWriteReleases>false</overWriteReleases>
-              <overWriteSnapshots>true</overWriteSnapshots>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <version>1.7</version>
-        <executions>
-          <execution>
-            <id>add-source</id>
-            <phase>generate-sources</phase>
-            <goals>
-              <goal>add-source</goal>
-            </goals>
-            <configuration>
-              <sources>
-                <source>${project.build.directory}/log4j-core-java9</source>
-              </sources>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
           <excludedGroups>
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
index 7d5fd8d..09e2d78 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java
@@ -21,6 +21,7 @@
 import java.io.OutputStream;
 import java.io.RandomAccessFile;
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
@@ -216,11 +217,12 @@
         AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
             @Override
             public Object run() throws Exception {
-                final Method getCleanerMethod = mbb.getClass().getMethod("cleaner");
-                getCleanerMethod.setAccessible(true);
-                final Object cleaner = getCleanerMethod.invoke(mbb); // sun.misc.Cleaner instance
-                final Method cleanMethod = cleaner.getClass().getMethod("clean");
-                cleanMethod.invoke(cleaner);
+                final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
+                final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
+                unsafeField.setAccessible(true);
+                final Object unsafe = unsafeField.get(null);
+                Method invokeCleaner = unsafeClass.getMethod("invokeCleaner", ByteBuffer.class);
+                invokeCleaner.invoke(unsafe, mbb);
                 return null;
             }
         });
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ExtendedStackTraceElement.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ExtendedStackTraceElement.java
index 06183e4..083f356 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ExtendedStackTraceElement.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ExtendedStackTraceElement.java
@@ -20,6 +20,7 @@
 
 import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 import org.apache.logging.log4j.core.pattern.TextRenderer;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * Wraps and extends the concept of the JRE's final class {@link StackTraceElement} by adding more location information.
@@ -55,6 +56,17 @@
                 new ExtendedClassInfo(exact, location, version));
     }
 
+    /**
+     * Called from Jackson for XML and JSON IO.
+     */
+    public ExtendedStackTraceElement(final String classLoaderName, final String moduleName, final String moduleVersion,
+            final String declaringClass, final String methodName, final String fileName, final int lineNumber,
+            final boolean exact, final String location, final String version) {
+        this(new StackTraceElement(classLoaderName, moduleName, moduleVersion, declaringClass, methodName, fileName,
+                        lineNumber),
+                new ExtendedClassInfo(exact, location, version));
+    }
+
     @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
@@ -84,6 +96,18 @@
         return true;
     }
 
+    public String getClassLoaderName() {
+        return this.stackTraceElement.getClassLoaderName();
+    }
+
+    public String getModuleName() {
+        return this.stackTraceElement.getModuleName();
+    }
+
+    public String getModuleVersion() {
+        return this.stackTraceElement.getModuleVersion();
+    }
+
     public String getClassName() {
         return this.stackTraceElement.getClassName();
     }
@@ -142,6 +166,11 @@
     private void render(final StackTraceElement stElement, final StringBuilder output, final TextRenderer textRenderer) {
         final String fileName = stElement.getFileName();
         final int lineNumber = stElement.getLineNumber();
+        String moduleName = getModuleName();
+        if (Strings.isNotEmpty(moduleName)) {
+            textRenderer.render(moduleName, output, "StackTraceElement.ModuleName");
+            textRenderer.render("/", output, "StackTraceElement.ModuleNameSeparator");
+        }
         textRenderer.render(getClassName(), output, "StackTraceElement.ClassName");
         textRenderer.render(".", output, "StackTraceElement.ClassMethodSeparator");
         textRenderer.render(stElement.getMethodName(), output, "StackTraceElement.MethodName");
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/time/internal/SystemClock.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/time/internal/SystemClock.java
index 473b0e8..45f5257 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/time/internal/SystemClock.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/time/internal/SystemClock.java
@@ -16,13 +16,22 @@
  */
 package org.apache.logging.log4j.core.time.internal;
 
+import java.time.Instant;
+
 import org.apache.logging.log4j.core.time.Clock;
+import org.apache.logging.log4j.core.time.MutableInstant;
+import org.apache.logging.log4j.core.time.PreciseClock;
+import org.apache.logging.log4j.util.PropertiesUtil;
 
 /**
  * Implementation of the {@code Clock} interface that returns the system time.
+ * @since 2.11.0
  */
-public final class SystemClock implements Clock {
+// Precise clock is not implemented because the instant() method in the init method is not garbage free.
+public final class SystemClock implements Clock, PreciseClock {
 
+    private static final boolean USE_PRECISE_CLOCK = PropertiesUtil.getProperties()
+            .getBooleanProperty("log4j2.usePreciseClock", false);
     /**
      * Returns the system time.
      * @return the result of calling {@code System.currentTimeMillis()}
@@ -32,4 +41,16 @@
         return System.currentTimeMillis();
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void init(MutableInstant mutableInstant) {
+        if (USE_PRECISE_CLOCK) {
+            Instant instant = java.time.Clock.systemUTC().instant();
+            mutableInstant.initFromEpochSecond(instant.getEpochSecond(), instant.getNano());
+        } else {
+            mutableInstant.initFromEpochMilli(System.currentTimeMillis(), 0);
+        }
+    }
 }
diff --git a/log4j-core/src/main/resources/Log4j-config.xsd b/log4j-core/src/main/resources/Log4j-config.xsd
index f0c9081..ebe0031 100644
--- a/log4j-core/src/main/resources/Log4j-config.xsd
+++ b/log4j-core/src/main/resources/Log4j-config.xsd
@@ -521,7 +521,33 @@
 
    <complexType name="GelfLayoutType">
       <sequence minOccurs="0">
-         <element name="MessagePattern" type="string" minOccurs="0" />
+         <choice minOccurs="0">
+            <element name="LevelPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+            <element name="MarkerPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+            <element name="ScriptPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+            <element name="MessagePattern" type="string" minOccurs="0" />
+         </choice>
          <element name="KeyValuePair" type="tns:KeyValuePairType" minOccurs="0" maxOccurs="unbounded">
             <annotation>
                <documentation>
@@ -547,6 +573,11 @@
       <attribute name="messagePattern" type="string" />
       <attribute name="threadContextExcludes" type="string" />
       <attribute name="threadContextIncludes" type="string" />
+      <attribute name="threadContextPrefix" type="string"/>
+      <attribute name="mapMessageExcludes" type="string" />
+      <attribute name="mapMessageIncludes" type="string" />
+      <attribute name="mapPrefix" type="string"/>
+      <attribute name="omitEmptyFields" type="tns:BooleanType"/>
    </complexType>
 
    <complexType name="JsonLayoutType">
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/ThreadContextTestAccess.java b/log4j-core/src/test/java/org/apache/logging/log4j/ThreadContextTestAccess.java
index 67c2d98..5245899 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/ThreadContextTestAccess.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/ThreadContextTestAccess.java
@@ -16,6 +16,12 @@
  */
 package org.apache.logging.log4j;
 
+import java.lang.reflect.Method;
+
+import org.apache.logging.log4j.ThreadContext;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
 /**
  * <p>
  * Utility class to access package protected methods in {@code ThreadContext}.
@@ -29,6 +35,13 @@
     }
 
     public static void init() {
-        ThreadContext.init();
+        try {
+            Class<ThreadContext> clazz = ThreadContext.class;
+            Method method = clazz.getDeclaredMethod("init");
+            method.setAccessible(true);
+            method.invoke(null);
+        } catch (Exception ex) {
+            fail("Unable to reinitialize ThreadContext");
+        }
     }
 }
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelJsonTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelJsonTest.java
index f09a3a2..82d9370 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelJsonTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelJsonTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelTest.java
index dbe5658..bc40848 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/AppenderRefLevelTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/CollectionLoggingTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/CollectionLoggingTest.java
index 80ab899..e892312 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/CollectionLoggingTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/CollectionLoggingTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.message.StringMapMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Disabled;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsOverrideTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsOverrideTest.java
index 50c63ed..20826dd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsOverrideTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsOverrideTest.java
@@ -21,8 +21,8 @@
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsTest.java
index 98978aa..0512ba5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsTest.java
@@ -21,8 +21,8 @@
 import static org.junit.jupiter.api.Assertions.*;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsWithFiltersTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsWithFiltersTest.java
index 20b350d..6df5f06 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsWithFiltersTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/CustomLevelsWithFiltersTest.java
@@ -21,8 +21,8 @@
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.filter.CompositeFilter;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/DeadlockTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/DeadlockTest.java
index 0f08f3e..7738058 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/DeadlockTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/DeadlockTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core;
 
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ExtendedLevelTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/ExtendedLevelTest.java
index d9ceb4f..6401015 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ExtendedLevelTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ExtendedLevelTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.ExtendedLevels;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
index 103233f..d9289b8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/GcFreeLoggingTestUtil.java
@@ -167,10 +167,11 @@
                         "pattern mismatch at line 1: " + line);
             }
 
-            // Check the rest of the lines.
+            // Check the rest of the lines. We are looking for the messages written to System.err
+            // in the sampleAllocation() method above in executeLogging().
             else {
                 assertFalse(
-                        line.contains("allocated") || line.contains("array"),
+                        line.contains(" allocated ") || line.contains(" array "),
                         "(allocated|array) pattern matches at line " + lineNumber + ": " + line);
             }
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/HostNameTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/HostNameTest.java
index 86b5e07..c51df79 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/HostNameTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/HostNameTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.util.NetUtils;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LevelTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LevelTest.java
index 393751b..c60c904 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LevelTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LevelTest.java
@@ -22,8 +22,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.ObjectMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/Log4j1222Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/Log4j1222Test.java
index 073dfaa..b22b2d0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/Log4j1222Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/Log4j1222Test.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.TestLogger;
+import org.apache.logging.log4j.test.TestLogger;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventFactoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventFactoryTest.java
index b7ecf8b..c728e75 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventFactoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventFactoryTest.java
@@ -31,7 +31,7 @@
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.impl.LogEventFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventTest.java
index a707b37..22d35ae 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LogEventTest.java
@@ -41,6 +41,7 @@
     private static Message MESSAGE = new SimpleMessage("This is a test");
     private static TestClass TESTER = new TestClass();
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testSerialization() throws Exception {
         final LogEvent event1 = Log4jLogEvent.newBuilder() //
@@ -78,6 +79,7 @@
         }
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testNanoTimeIsNotSerialized1() throws Exception {
         final LogEvent event1 = Log4jLogEvent.newBuilder() //
@@ -103,6 +105,7 @@
         assertEquals(0, actual.getNanoTime(), "deserialized nanoTime is zero");
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testNanoTimeIsNotSerialized2() throws Exception {
         final LogEvent event1 = Log4jLogEvent.newBuilder() //
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerDateTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerDateTest.java
index f8bfde9..4763d10 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerDateTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerDateTest.java
@@ -19,8 +19,8 @@
 import java.util.Calendar;
 
 import org.apache.logging.log4j.core.appender.FileAppender;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
index 2637de5..4da35fb 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerSerializationTest.java
@@ -20,8 +20,8 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.AbstractSerializationTest;
 import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.test.AbstractSerializationTest;
 import org.junit.runners.Parameterized.Parameters;
 
 public class LoggerSerializationTest extends AbstractSerializationTest {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
index 75af436..1b23796 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerTest.java
@@ -24,9 +24,9 @@
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.Configurator;
 import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.ReconfigurationPolicy;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.ReconfigurationPolicy;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.message.ParameterizedMessageFactory;
@@ -390,8 +390,8 @@
         final Configuration config = context.getConfiguration();
         final LoggerConfig loggerConfig = config.getLoggerConfig("org.apache.logging.log4j.core.LoggerTest");
         assertNotNull(loggerConfig);
-        assertEquals(loggerConfig.getName(), "org.apache.logging.log4j.core.LoggerTest");
-        assertEquals(loggerConfig.getLevel(), Level.DEBUG);
+        assertEquals("org.apache.logging.log4j.core.LoggerTest", loggerConfig.getName());
+        assertEquals(Level.DEBUG, loggerConfig.getLevel());
         final Logger localLogger = context.getLogger("org.apache.logging.log4j.core.LoggerTest");
         assertSame(localLogger.getLevel(), Level.DEBUG, "Incorrect level - expected DEBUG, actual " + localLogger.getLevel());
     }
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerUpdateTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerUpdateTest.java
index 854fbef..a595186 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerUpdateTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LoggerUpdateTest.java
@@ -20,8 +20,8 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/LookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/LookupTest.java
index 0bab663..801b8ff 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/LookupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/LookupTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
index 7fb6cae..4806e6a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/PatternSelectorTest.java
@@ -19,8 +19,8 @@
 import java.util.List;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/PropertiesFileConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/PropertiesFileConfigTest.java
index 9d12ce3..0914758 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/PropertiesFileConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/PropertiesFileConfigTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core;
 
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownDisabledTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownDisabledTest.java
index ef53e89..0771742 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownDisabledTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownDisabledTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core;
 
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertFalse;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
index dc34879..2037a99 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ShutdownTimeoutConfigurationTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core;
 
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/StrictXmlConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/StrictXmlConfigTest.java
index 4bf661f..29293f7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/StrictXmlConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/StrictXmlConfigTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.EntryMessage;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/TimestampMessageTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/TimestampMessageTest.java
index d22f4e6..1131464 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/TimestampMessageTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/TimestampMessageTest.java
@@ -21,8 +21,8 @@
 import org.apache.logging.log4j.core.time.ClockFactory;
 import org.apache.logging.log4j.core.time.ClockFactoryTest;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.message.TimestampMessage;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/XmlEvents.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/XmlEvents.java
index cf56051..9ae8f21 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/XmlEvents.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/XmlEvents.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.AsynchronouslyFormattable;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.junit.jupiter.api.Disabled;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderQueueFullPolicyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderQueueFullPolicyTest.java
index ef7a35f..c1616c6 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderQueueFullPolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderQueueFullPolicyTest.java
@@ -21,8 +21,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.async.DefaultAsyncQueueFullPolicy;
 import org.apache.logging.log4j.core.async.EventRoute;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.BlockingAppender;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
index d0f3f0d..ad4efed 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/AsyncAppenderTest.java
@@ -19,8 +19,8 @@
 
 import org.apache.logging.log4j.LoggingException;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Tag;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConfigurationTestUtils.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConfigurationTestUtils.java
index c0e4dc8..54a7676 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConfigurationTestUtils.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConfigurationTestUtils.java
@@ -1,37 +1,37 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender;

-

-import org.apache.logging.log4j.Level;

-import org.apache.logging.log4j.core.Appender;

-import org.apache.logging.log4j.core.Filter;

-import org.apache.logging.log4j.core.config.Configuration;

-import org.apache.logging.log4j.core.config.LoggerConfig;

-

-public class ConfigurationTestUtils {

-

-    static void updateLoggers(final Appender appender, final Configuration config) {

-        final Level level = null;

-        final Filter filter = null;

-        for (final LoggerConfig loggerConfig : config.getLoggers().values()) {

-            loggerConfig.addAppender(appender, level, filter);

-        }

-        config.getRootLogger().addAppender(appender, level, filter);

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+
+public class ConfigurationTestUtils {
+
+    static void updateLoggers(final Appender appender, final Configuration config) {
+        final Level level = null;
+        final Filter filter = null;
+        for (final LoggerConfig loggerConfig : config.getLoggers().values()) {
+            loggerConfig.addAppender(appender, level, filter);
+        }
+        config.getRootLogger().addAppender(appender, level, filter);
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java
index 3a150a0..70c5d1d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configurator;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java
index 34901ff..4e65f5e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java
@@ -21,7 +21,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configurator;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FailoverAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FailoverAppenderTest.java
index 56c886d..8239342 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FailoverAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FailoverAppenderTest.java
@@ -19,8 +19,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.FailOnceAppender;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.AfterEach;
@@ -38,8 +38,8 @@
     private final Logger logger;
     private final Logger onceLogger;
 
-    public FailoverAppenderTest(
-            final LoggerContext context, @Named("List") final ListAppender app, @Named("Once") final FailOnceAppender foApp) {
+    public FailoverAppenderTest(final LoggerContext context, @Named("List") final ListAppender app,
+            @Named("Once") final FailOnceAppender foApp) {
         this.app = app;
         this.foApp = foApp;
         logger = context.getLogger("LoggerTest");
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
index c287e7e..e12673c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderPermissionsTest.java
@@ -24,8 +24,8 @@
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.FileUtils;
-import org.apache.logging.log4j.junit.CleanUpDirectories;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.CleanUpDirectories;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderTest.java
index 223ce3e..3927458 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/FileAppenderTest.java
@@ -35,7 +35,7 @@
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.core.util.Throwables;
-import org.apache.logging.log4j.junit.CleanUpFiles;
+import org.apache.logging.log4j.test.junit.CleanUpFiles;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Disabled;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppenderTest.java
index 9dcf88e..69d24c2 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppenderTest.java
@@ -19,8 +19,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.util.Integers;
-import org.apache.logging.log4j.junit.CleanUpFiles;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.CleanUpFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import java.nio.file.Files;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
index af194b8..5bd2c32 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
@@ -1,123 +1,123 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-package org.apache.logging.log4j.core.appender;

-

-import java.io.BufferedOutputStream;

-import java.io.ByteArrayOutputStream;

-import java.io.OutputStream;

-

-import org.apache.logging.log4j.LogManager;

-import org.apache.logging.log4j.Logger;

-import org.apache.logging.log4j.core.Appender;

-import org.apache.logging.log4j.core.LoggerContext;

-import org.apache.logging.log4j.core.config.Configuration;

-import org.apache.logging.log4j.core.filter.NoMarkerFilter;

-import org.apache.logging.log4j.core.layout.PatternLayout;

-import org.junit.Assert;

-import org.junit.Rule;

-import org.junit.Test;

-import org.junit.rules.TestName;

-

-/**

- * Tests {@link OutputStreamAppender}.

- */

-public class OutputStreamAppenderTest {

-

-    private static final String TEST_MSG = "FOO ERROR";

-

-    @Rule

-    public TestName testName = new TestName();

-

-    private String getName(final OutputStream out) {

-        return out.getClass().getSimpleName() + "." + testName.getMethodName();

-    }

-

-    /**

-     * Tests that you can add an output stream appender dynamically.

-     */

-    private void addAppender(final OutputStream outputStream, final String outputStreamName) {

-        final LoggerContext context = LoggerContext.getContext(false);

-        final Configuration config = context.getConfiguration();

-        final PatternLayout layout = PatternLayout.createDefaultLayout(config);

-        final Appender appender = OutputStreamAppender.createAppender(layout, null, outputStream, outputStreamName, false, true);

-        appender.start();

-        config.addAppender(appender);

-        ConfigurationTestUtils.updateLoggers(appender, config);

-    }

-

-    @Test

-    public void testBuildFilter() {

-        final NoMarkerFilter filter = NoMarkerFilter.newBuilder().build();

-        // @formatter:off

-        final OutputStreamAppender.Builder builder = OutputStreamAppender.newBuilder()

-                .setName("test")

-                .setFilter(filter);

-        // @formatter:on

-        Assert.assertEquals(filter, builder.getFilter());

-        final OutputStreamAppender appender = builder.build();

-        Assert.assertEquals(filter, appender.getFilter());

-    }

-

-    @Test

-    public void testOutputStreamAppenderToBufferedOutputStream() {

-        final ByteArrayOutputStream out = new ByteArrayOutputStream();

-        final OutputStream os = new BufferedOutputStream(out);

-        final String name = getName(out);

-        final Logger logger = LogManager.getLogger(name);

-        addAppender(os, name);

-        logger.error(TEST_MSG);

-        final String actual = out.toString();

-        Assert.assertTrue(actual, actual.contains(TEST_MSG));

-    }

-

-    @Test

-    public void testOutputStreamAppenderToByteArrayOutputStream() {

-        final OutputStream out = new ByteArrayOutputStream();

-        final String name = getName(out);

-        final Logger logger = LogManager.getLogger(name);

-        addAppender(out, name);

-        logger.error(TEST_MSG);

-        final String actual = out.toString();

-        Assert.assertTrue(actual, actual.contains(TEST_MSG));

-    }

-

-    /**

-     * Validates that the code pattern we use to add an appender on the fly

-     * works with a basic appender that is not the new OutputStream appender or

-     * new Writer appender.

-     */

-    @Test

-    public void testUpdatePatternWithFileAppender() {

-        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);

-        final Configuration config = ctx.getConfiguration();

-        // @formatter:off

-        final Appender appender = FileAppender.newBuilder()

-            .setFileName("target/" + getClass().getName() + ".log")

-            .setAppend(false)

-            .setName("File")

-            .setIgnoreExceptions(false)

-            .setBufferedIo(false)

-            .setBufferSize(4000)

-            .setConfiguration(config)

-            .build();

-        // @formatter:on

-        appender.start();

-        config.addAppender(appender);

-        ConfigurationTestUtils.updateLoggers(appender, config);

-        LogManager.getLogger().error("FOO MSG");

-    }

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.appender;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.filter.NoMarkerFilter;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+/**
+ * Tests {@link OutputStreamAppender}.
+ */
+public class OutputStreamAppenderTest {
+
+    private static final String TEST_MSG = "FOO ERROR";
+
+    @Rule
+    public TestName testName = new TestName();
+
+    private String getName(final OutputStream out) {
+        return out.getClass().getSimpleName() + "." + testName.getMethodName();
+    }
+
+    /**
+     * Tests that you can add an output stream appender dynamically.
+     */
+    private void addAppender(final OutputStream outputStream, final String outputStreamName) {
+        final LoggerContext context = LoggerContext.getContext(false);
+        final Configuration config = context.getConfiguration();
+        final PatternLayout layout = PatternLayout.createDefaultLayout(config);
+        final Appender appender = OutputStreamAppender.createAppender(layout, null, outputStream, outputStreamName, false, true);
+        appender.start();
+        config.addAppender(appender);
+        ConfigurationTestUtils.updateLoggers(appender, config);
+    }
+
+    @Test
+    public void testBuildFilter() {
+        final NoMarkerFilter filter = NoMarkerFilter.newBuilder().build();
+        // @formatter:off
+        final OutputStreamAppender.Builder builder = OutputStreamAppender.newBuilder()
+                .setName("test")
+                .setFilter(filter);
+        // @formatter:on
+        Assert.assertEquals(filter, builder.getFilter());
+        final OutputStreamAppender appender = builder.build();
+        Assert.assertEquals(filter, appender.getFilter());
+    }
+
+    @Test
+    public void testOutputStreamAppenderToBufferedOutputStream() {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final OutputStream os = new BufferedOutputStream(out);
+        final String name = getName(out);
+        final Logger logger = LogManager.getLogger(name);
+        addAppender(os, name);
+        logger.error(TEST_MSG);
+        final String actual = out.toString();
+        Assert.assertTrue(actual, actual.contains(TEST_MSG));
+    }
+
+    @Test
+    public void testOutputStreamAppenderToByteArrayOutputStream() {
+        final OutputStream out = new ByteArrayOutputStream();
+        final String name = getName(out);
+        final Logger logger = LogManager.getLogger(name);
+        addAppender(out, name);
+        logger.error(TEST_MSG);
+        final String actual = out.toString();
+        Assert.assertTrue(actual, actual.contains(TEST_MSG));
+    }
+
+    /**
+     * Validates that the code pattern we use to add an appender on the fly
+     * works with a basic appender that is not the new OutputStream appender or
+     * new Writer appender.
+     */
+    @Test
+    public void testUpdatePatternWithFileAppender() {
+        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final Configuration config = ctx.getConfiguration();
+        // @formatter:off
+        final Appender appender = FileAppender.newBuilder()
+            .setFileName("target/" + getClass().getName() + ".log")
+            .setAppend(false)
+            .setName("File")
+            .setIgnoreExceptions(false)
+            .setBufferedIo(false)
+            .setBufferSize(4000)
+            .setConfiguration(config)
+            .build();
+        // @formatter:on
+        appender.start();
+        config.addAppender(appender);
+        ConfigurationTestUtils.updateLoggers(appender, config);
+        LogManager.getLogger().error("FOO MSG");
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
index 609a8ff..0cf8559 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamManagerTest.java
@@ -24,7 +24,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppenderTest.java
index ac60227..69adad7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppenderTest.java
@@ -23,8 +23,8 @@
 import java.util.Collection;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.CleanFiles;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
index 6b3800f..3959594 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelectorTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
index 63ae624..ee5510b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/nosql/NoSqlDatabaseManagerTest.java
@@ -39,7 +39,7 @@
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
 import org.apache.logging.log4j.core.impl.ContextDataFactory;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.ThreadContextStackRule;
+import org.apache.logging.log4j.test.junit.ThreadContextStackRule;
 import org.apache.logging.log4j.message.Message;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicyTest.java
index c9f0c51..7c4e65c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/MapRewritePolicyTest.java
@@ -35,7 +35,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import static org.apache.logging.log4j.hamcrest.MapMatchers.hasSize;
+import static org.apache.logging.log4j.core.hamcrest.MapMatchers.hasSize;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasEntry;
 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppenderTest.java
index 9a94289..2eea61d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rewrite/RewriteAppenderTest.java
@@ -20,9 +20,9 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.hamcrest.MapMatchers;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.hamcrest.MapMatchers;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java
index c24fa50..9b67454 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RandomRollingAppenderOnStartupTest.java
@@ -23,7 +23,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCountTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCountTest.java
index 2ce95c9..264f3aa 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCountTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCountTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronAndSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronAndSizeTest.java
index 652389a..b7c7820 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronAndSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronAndSizeTest.java
@@ -21,14 +21,14 @@
 import java.util.Random;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertEquals;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2DirectTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2DirectTest.java
index 5fb4309..e241d37 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2DirectTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2DirectTest.java
@@ -21,13 +21,13 @@
 import java.util.Random;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertTrue;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2Test.java
index 228b97b..6bf40c9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronEvery2Test.java
@@ -21,13 +21,13 @@
 import java.util.Random;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronOnceADayTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronOnceADayTest.java
index 0c38a30..6b6f16e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronOnceADayTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronOnceADayTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
@@ -33,7 +33,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.util.CronExpression;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.hamcrest.Matcher;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java
index d6e31fe..35cda82 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCronTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertNotNull;
@@ -34,7 +34,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.util.CronExpression;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java
index 3b30bd8..d2c4c72 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderCustomDeleteActionTest.java
@@ -24,7 +24,7 @@
 import java.util.regex.Pattern;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
index b9d627b..8f85263 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount1Test.java
@@ -34,7 +34,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedFormat;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
index f27f7c4..4231619 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedCount2Test.java
@@ -34,7 +34,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedFormat;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java
index d7ef4bb..fb5e5b9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteAccumulatedSizeTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedFormat;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java
index 740f9ec..e414953 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteMaxDepthTest.java
@@ -31,7 +31,7 @@
 import java.util.regex.Pattern;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
index 134d621..6cb2abd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteNestedTest.java
@@ -34,7 +34,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat.FixedFormat;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
index 38dca95..a4df290 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptFri13thTest.java
@@ -23,7 +23,7 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
index 91da1a7..fee0ba3 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDeleteScriptTest.java
@@ -21,7 +21,7 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWrite1906Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWrite1906Test.java
index a055fc2..0c06172 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWrite1906Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWrite1906Test.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusListener;
 import org.apache.logging.log4j.status.StatusLogger;
@@ -34,8 +34,8 @@
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertNotNull;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java
index 0e997ef..3223e9d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java
@@ -20,8 +20,8 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
-import org.apache.logging.log4j.junit.CleanFolders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.CleanFolders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
index 06f1cbc..2945d2f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTempCompressedFilePatternTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertNotNull;
@@ -34,7 +34,7 @@
 
 import org.apache.commons.lang3.SystemUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTest.java
index 379f083..a829fbd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteTest.java
@@ -24,13 +24,13 @@
 import java.util.zip.GZIPInputStream;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithFilenameTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithFilenameTest.java
index 2f346c1..7bc308e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithFilenameTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithFilenameTest.java
@@ -19,7 +19,7 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithHtmlLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithHtmlLayoutTest.java
index 24799ed..d65de65 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithHtmlLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithHtmlLayoutTest.java
@@ -16,17 +16,14 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
 import org.apache.logging.log4j.core.util.IOUtils;
-import org.apache.logging.log4j.junit.CleanFolders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.hamcrest.Matchers;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
@@ -34,10 +31,9 @@
 import java.io.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-import java.util.zip.GZIPInputStream;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithReconfigureTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithReconfigureTest.java
index 0d8edaf..ce5f003 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithReconfigureTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteWithReconfigureTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java
index 0d34be6..57df32c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderNoUnconditionalDeleteTest.java
@@ -24,7 +24,7 @@
 import java.util.List;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
index 15961d4..5f1a0fe 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderReconfigureTest.java
@@ -14,8 +14,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertThat;
@@ -25,7 +25,7 @@
 
 import org.apache.commons.io.FileUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderRestartTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderRestartTest.java
index bf8b39b..20cef41 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderRestartTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderRestartTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.commons.io.file.PathUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -38,8 +38,8 @@
 import java.time.temporal.ChronoUnit;
 import java.util.Arrays;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertTrue;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
index 403b399..8161f11 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeCompressPermissionsTest.java
@@ -25,7 +25,7 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.util.FileUtils;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeNoCompressTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeNoCompressTest.java
index 2c73dcb..ba94f32 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeNoCompressTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeNoCompressTest.java
@@ -30,7 +30,7 @@
 
 import org.apache.commons.compress.utils.IOUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java
index 625c2eb..3dba35a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertNotNull;
@@ -43,7 +43,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
 import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java
index 7370060..639ba89 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderSizeWithTimeTest.java
@@ -26,7 +26,7 @@
 
 import org.apache.commons.compress.utils.IOUtils;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
index 03fd6be..77ebf43 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTempCompressedFilePatternTest.java
@@ -41,7 +41,7 @@
 import org.apache.commons.lang3.SystemUtils;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeDirectTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeDirectTest.java
index b0ea9db..7cdbc30 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeDirectTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeDirectTest.java
@@ -19,13 +19,13 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java
index b0235b4..f947774 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeAndSizeTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.appender.rolling;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -29,8 +29,8 @@
 import java.util.Arrays;
 import java.util.Random;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java
index 089908d..f8ef484 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderTimeTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.appender.rolling;
 
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.assertTrue;
@@ -26,7 +26,7 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.hamcrest.Matcher;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderUncompressedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderUncompressedTest.java
index 730e1b2..b969295 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderUncompressedTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderUncompressedTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.CleanFolders;
+import org.apache.logging.log4j.test.junit.CleanFolders;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectSizeTimeNewDirectoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectSizeTimeNewDirectoryTest.java
index eee0d8b..0211c6a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectSizeTimeNewDirectoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectSizeTimeNewDirectoryTest.java
@@ -25,7 +25,7 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.appender.RollingFileAppender;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectTimeNewDirectoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectTimeNewDirectoryTest.java
index c1a2667..20c8a33 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectTimeNewDirectoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingDirectTimeNewDirectoryTest.java
@@ -19,7 +19,7 @@
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.filefilter.TrueFileFilter;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureTest.java
index 8c4657a..97dcab2 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.core.appender.rolling;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureUndefinedSystemPropertyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureUndefinedSystemPropertyTest.java
index 31a21b1..ade5e94 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureUndefinedSystemPropertyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderReconfigureUndefinedSystemPropertyTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.core.appender.rolling;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
index c1b9471..07274d8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingNewDirectoryTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.appender.rolling;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
index 6734d6b..e02a2a1 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerHeaderFooterTest.java
@@ -27,7 +27,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
 import org.apache.logging.log4j.core.util.Closer;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
index b365322..9f1c6aa 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAccessFileManagerTest.java
@@ -37,10 +37,10 @@
 import java.util.Set;
 import java.util.concurrent.locks.LockSupport;
 
-import static org.apache.logging.log4j.hamcrest.FileMatchers.beforeNow;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasLength;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.isEmpty;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.lastModified;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.beforeNow;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasLength;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.isEmpty;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.lastModified;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.lessThanOrEqualTo;
 import static org.junit.Assert.assertEquals;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
index 3aba52e..22e4a73 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteTest.java
@@ -19,13 +19,13 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import static org.apache.logging.log4j.hamcrest.Descriptors.that;
-import static org.apache.logging.log4j.hamcrest.FileMatchers.hasName;
+import static org.apache.logging.log4j.core.hamcrest.Descriptors.that;
+import static org.apache.logging.log4j.core.hamcrest.FileMatchers.hasName;
 import static org.hamcrest.Matchers.endsWith;
 import static org.hamcrest.Matchers.hasItemInArray;
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteWithFilenameTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteWithFilenameTest.java
index b270671..3b1b7d0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteWithFilenameTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingRandomAppenderDirectWriteWithFilenameTest.java
@@ -19,7 +19,7 @@
 import java.io.File;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithDeletedOldFileTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithDeletedOldFileTest.java
index 7956024..20b96f8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithDeletedOldFileTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithDeletedOldFileTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.appender.rolling;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithPaddingTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithPaddingTest.java
index 7b0fb22..44d519c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithPaddingTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/RolloverWithPaddingTest.java
@@ -25,7 +25,7 @@
 import java.util.List;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractActionTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractActionTest.java
index 09a518b..b48d274 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractActionTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/AbstractActionTest.java
@@ -1,7 +1,7 @@
 package org.apache.logging.log4j.core.appender.rolling.action;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.junit.StatusLoggerLevel;
+import org.apache.logging.log4j.test.junit.StatusLoggerLevel;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
index 81e316f..5ba9429 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/DummyFileAttributes.java
@@ -1,86 +1,86 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender.rolling.action;

-

-import java.nio.file.attribute.BasicFileAttributes;

-import java.nio.file.attribute.FileTime;

-

-/**

- * Test helper class: file attributes.

- */

-public class DummyFileAttributes implements BasicFileAttributes {

-

-    public FileTime lastModified;

-    public FileTime lastAccessTime;

-    public FileTime creationTime;

-    public boolean isRegularFile;

-    public boolean isDirectory;

-    public boolean isSymbolicLink;

-    public boolean isOther;

-    public long size;

-    public Object fileKey;

-    

-    public DummyFileAttributes() {

-    }

-

-    @Override

-    public FileTime lastModifiedTime() {

-        return lastModified;

-    }

-

-    @Override

-    public FileTime lastAccessTime() {

-        return lastAccessTime;

-    }

-

-    @Override

-    public FileTime creationTime() {

-        return creationTime;

-    }

-

-    @Override

-    public boolean isRegularFile() {

-        return isRegularFile;

-    }

-

-    @Override

-    public boolean isDirectory() {

-        return isDirectory;

-    }

-

-    @Override

-    public boolean isSymbolicLink() {

-        return isSymbolicLink;

-    }

-

-    @Override

-    public boolean isOther() {

-        return isOther;

-    }

-

-    @Override

-    public long size() {

-        return size;

-    }

-

-    @Override

-    public Object fileKey() {

-        return fileKey;

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+
+/**
+ * Test helper class: file attributes.
+ */
+public class DummyFileAttributes implements BasicFileAttributes {
+
+    public FileTime lastModified;
+    public FileTime lastAccessTime;
+    public FileTime creationTime;
+    public boolean isRegularFile;
+    public boolean isDirectory;
+    public boolean isSymbolicLink;
+    public boolean isOther;
+    public long size;
+    public Object fileKey;
+    
+    public DummyFileAttributes() {
+    }
+
+    @Override
+    public FileTime lastModifiedTime() {
+        return lastModified;
+    }
+
+    @Override
+    public FileTime lastAccessTime() {
+        return lastAccessTime;
+    }
+
+    @Override
+    public FileTime creationTime() {
+        return creationTime;
+    }
+
+    @Override
+    public boolean isRegularFile() {
+        return isRegularFile;
+    }
+
+    @Override
+    public boolean isDirectory() {
+        return isDirectory;
+    }
+
+    @Override
+    public boolean isSymbolicLink() {
+        return isSymbolicLink;
+    }
+
+    @Override
+    public boolean isOther() {
+        return isOther;
+    }
+
+    @Override
+    public long size() {
+        return size;
+    }
+
+    @Override
+    public Object fileKey() {
+        return fileKey;
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAllTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAllTest.java
index 2e3f1fb..5e85d1c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAllTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAllTest.java
@@ -1,52 +1,52 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender.rolling.action;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.*;

-

-/**

- * Tests the And composite condition.

- */

-public class IfAllTest {

-

-    @Test

-    public void testAccept() {

-        final PathCondition TRUE = new FixedCondition(true);

-        final PathCondition FALSE = new FixedCondition(false);

-        assertTrue(IfAll.createAndCondition(TRUE, TRUE).accept(null, null, null));

-        assertFalse(IfAll.createAndCondition(FALSE, TRUE).accept(null, null, null));

-        assertFalse(IfAll.createAndCondition(TRUE, FALSE).accept(null, null, null));

-        assertFalse(IfAll.createAndCondition(FALSE, FALSE).accept(null, null, null));

-    }

-    

-    @Test

-    public void testEmptyIsFalse() {

-        assertFalse(IfAll.createAndCondition().accept(null, null, null));

-    }

-    

-    @Test

-    public void testBeforeTreeWalk() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfAll and = IfAll.createAndCondition(counter, counter, counter);

-        and.beforeFileTreeWalk();

-        assertEquals(3, counter.getBeforeFileTreeWalkCount());

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests the And composite condition.
+ */
+public class IfAllTest {
+
+    @Test
+    public void testAccept() {
+        final PathCondition TRUE = new FixedCondition(true);
+        final PathCondition FALSE = new FixedCondition(false);
+        assertTrue(IfAll.createAndCondition(TRUE, TRUE).accept(null, null, null));
+        assertFalse(IfAll.createAndCondition(FALSE, TRUE).accept(null, null, null));
+        assertFalse(IfAll.createAndCondition(TRUE, FALSE).accept(null, null, null));
+        assertFalse(IfAll.createAndCondition(FALSE, FALSE).accept(null, null, null));
+    }
+    
+    @Test
+    public void testEmptyIsFalse() {
+        assertFalse(IfAll.createAndCondition().accept(null, null, null));
+    }
+    
+    @Test
+    public void testBeforeTreeWalk() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfAll and = IfAll.createAndCondition(counter, counter, counter);
+        and.beforeFileTreeWalk();
+        assertEquals(3, counter.getBeforeFileTreeWalkCount());
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAnyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAnyTest.java
index 4eaaaa0..2a2c7db 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAnyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfAnyTest.java
@@ -1,52 +1,52 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender.rolling.action;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.*;

-

-/**

- * Tests the Or composite condition.

- */

-public class IfAnyTest {

-

-    @Test

-    public void test() {

-        final PathCondition TRUE = new FixedCondition(true);

-        final PathCondition FALSE = new FixedCondition(false);

-        assertTrue(IfAny.createOrCondition(TRUE, TRUE).accept(null, null, null));

-        assertTrue(IfAny.createOrCondition(FALSE, TRUE).accept(null, null, null));

-        assertTrue(IfAny.createOrCondition(TRUE, FALSE).accept(null, null, null));

-        assertFalse(IfAny.createOrCondition(FALSE, FALSE).accept(null, null, null));

-    }

-    

-    @Test

-    public void testEmptyIsFalse() {

-        assertFalse(IfAny.createOrCondition().accept(null, null, null));

-    }

-    

-    @Test

-    public void testBeforeTreeWalk() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfAny or = IfAny.createOrCondition(counter, counter, counter);

-        or.beforeFileTreeWalk();

-        assertEquals(3, counter.getBeforeFileTreeWalkCount());

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests the Or composite condition.
+ */
+public class IfAnyTest {
+
+    @Test
+    public void test() {
+        final PathCondition TRUE = new FixedCondition(true);
+        final PathCondition FALSE = new FixedCondition(false);
+        assertTrue(IfAny.createOrCondition(TRUE, TRUE).accept(null, null, null));
+        assertTrue(IfAny.createOrCondition(FALSE, TRUE).accept(null, null, null));
+        assertTrue(IfAny.createOrCondition(TRUE, FALSE).accept(null, null, null));
+        assertFalse(IfAny.createOrCondition(FALSE, FALSE).accept(null, null, null));
+    }
+    
+    @Test
+    public void testEmptyIsFalse() {
+        assertFalse(IfAny.createOrCondition().accept(null, null, null));
+    }
+    
+    @Test
+    public void testBeforeTreeWalk() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfAny or = IfAny.createOrCondition(counter, counter, counter);
+        or.beforeFileTreeWalk();
+        assertEquals(3, counter.getBeforeFileTreeWalkCount());
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
index bac7179..9b0b0db 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfFileNameTest.java
@@ -1,131 +1,131 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender.rolling.action;

-

-import java.nio.file.Path;

-import java.nio.file.Paths;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.*;

-

-public class IfFileNameTest {

-

-    @Test

-    public void testCreateNameConditionFailsIfBothRegexAndPathAreNull() {

-        assertThrows(IllegalArgumentException.class, () -> IfFileName.createNameCondition(null, null));

-    }

-

-    @Test

-    public void testCreateNameConditionAcceptsIfEitherRegexOrPathOrBothAreNonNull() {

-        IfFileName.createNameCondition("bar", null);

-        IfFileName.createNameCondition(null, "foo");

-        IfFileName.createNameCondition("bar", "foo");

-    }

-

-    @Test

-    public void testGetSyntaxAndPattern() {

-        assertEquals("glob:path", IfFileName.createNameCondition("path", null).getSyntaxAndPattern());

-        assertEquals("glob:path", IfFileName.createNameCondition("glob:path", null).getSyntaxAndPattern());

-        assertEquals("regex:bar", IfFileName.createNameCondition(null, "bar").getSyntaxAndPattern());

-        assertEquals("regex:bar", IfFileName.createNameCondition(null, "regex:bar").getSyntaxAndPattern());

-    }

-

-    @Test

-    public void testAcceptUsesPathPatternIfExists() {

-        final IfFileName filter = IfFileName.createNameCondition("path", "regex");

-        final Path relativePath = Paths.get("path");

-        assertTrue(filter.accept(null, relativePath, null));

-        

-        final Path pathMatchingRegex = Paths.get("regex");

-        assertFalse(filter.accept(null, pathMatchingRegex, null));

-    }

-

-    @Test

-    public void testAcceptUsesRegexIfNoPathPatternExists() {

-        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex");

-        final Path pathMatchingRegex = Paths.get("regex");

-        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));

-        

-        final Path noMatch = Paths.get("nomatch");

-        assertFalse(regexFilter.accept(null, noMatch, null));

-    }

-

-    @Test

-    public void testAcceptIgnoresBasePathAndAttributes() {

-        final IfFileName pathFilter = IfFileName.createNameCondition("path", null);

-        final Path relativePath = Paths.get("path");

-        assertTrue(pathFilter.accept(null, relativePath, null));

-        

-        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex");

-        final Path pathMatchingRegex = Paths.get("regex");

-        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));

-    }

-

-    @Test

-    public void testAcceptCallsNestedConditionsOnlyIfPathAccepted1() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex", counter);

-        final Path pathMatchingRegex = Paths.get("regex");

-        

-        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));

-        assertEquals(1, counter.getAcceptCount());

-        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));

-        assertEquals(2, counter.getAcceptCount());

-        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));

-        assertEquals(3, counter.getAcceptCount());

-        

-        final Path noMatch = Paths.get("nomatch");

-        assertFalse(regexFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount()); // no increase

-        assertFalse(regexFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount());

-        assertFalse(regexFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount());

-    }

-

-    @Test

-    public void testAcceptCallsNestedConditionsOnlyIfPathAccepted2() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfFileName globFilter = IfFileName.createNameCondition("glob", null, counter);

-        final Path pathMatchingGlob = Paths.get("glob");

-        

-        assertTrue(globFilter.accept(null, pathMatchingGlob, null));

-        assertEquals(1, counter.getAcceptCount());

-        assertTrue(globFilter.accept(null, pathMatchingGlob, null));

-        assertEquals(2, counter.getAcceptCount());

-        assertTrue(globFilter.accept(null, pathMatchingGlob, null));

-        assertEquals(3, counter.getAcceptCount());

-

-        final Path noMatch = Paths.get("nomatch");

-        assertFalse(globFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount()); // no increase

-        assertFalse(globFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount());

-        assertFalse(globFilter.accept(null, noMatch, null));

-        assertEquals(3, counter.getAcceptCount());

-    }

-

-    @Test

-    public void testBeforeTreeWalk() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfFileName pathFilter = IfFileName.createNameCondition("path", null, counter, counter, counter);

-        pathFilter.beforeFileTreeWalk();

-        assertEquals(3, counter.getBeforeFileTreeWalkCount());

-    }

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class IfFileNameTest {
+
+    @Test
+    public void testCreateNameConditionFailsIfBothRegexAndPathAreNull() {
+        assertThrows(IllegalArgumentException.class, () -> IfFileName.createNameCondition(null, null));
+    }
+
+    @Test
+    public void testCreateNameConditionAcceptsIfEitherRegexOrPathOrBothAreNonNull() {
+        IfFileName.createNameCondition("bar", null);
+        IfFileName.createNameCondition(null, "foo");
+        IfFileName.createNameCondition("bar", "foo");
+    }
+
+    @Test
+    public void testGetSyntaxAndPattern() {
+        assertEquals("glob:path", IfFileName.createNameCondition("path", null).getSyntaxAndPattern());
+        assertEquals("glob:path", IfFileName.createNameCondition("glob:path", null).getSyntaxAndPattern());
+        assertEquals("regex:bar", IfFileName.createNameCondition(null, "bar").getSyntaxAndPattern());
+        assertEquals("regex:bar", IfFileName.createNameCondition(null, "regex:bar").getSyntaxAndPattern());
+    }
+
+    @Test
+    public void testAcceptUsesPathPatternIfExists() {
+        final IfFileName filter = IfFileName.createNameCondition("path", "regex");
+        final Path relativePath = Paths.get("path");
+        assertTrue(filter.accept(null, relativePath, null));
+        
+        final Path pathMatchingRegex = Paths.get("regex");
+        assertFalse(filter.accept(null, pathMatchingRegex, null));
+    }
+
+    @Test
+    public void testAcceptUsesRegexIfNoPathPatternExists() {
+        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex");
+        final Path pathMatchingRegex = Paths.get("regex");
+        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+        
+        final Path noMatch = Paths.get("nomatch");
+        assertFalse(regexFilter.accept(null, noMatch, null));
+    }
+
+    @Test
+    public void testAcceptIgnoresBasePathAndAttributes() {
+        final IfFileName pathFilter = IfFileName.createNameCondition("path", null);
+        final Path relativePath = Paths.get("path");
+        assertTrue(pathFilter.accept(null, relativePath, null));
+        
+        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex");
+        final Path pathMatchingRegex = Paths.get("regex");
+        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+    }
+
+    @Test
+    public void testAcceptCallsNestedConditionsOnlyIfPathAccepted1() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfFileName regexFilter = IfFileName.createNameCondition(null, "regex", counter);
+        final Path pathMatchingRegex = Paths.get("regex");
+        
+        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+        assertEquals(1, counter.getAcceptCount());
+        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+        assertEquals(2, counter.getAcceptCount());
+        assertTrue(regexFilter.accept(null, pathMatchingRegex, null));
+        assertEquals(3, counter.getAcceptCount());
+        
+        final Path noMatch = Paths.get("nomatch");
+        assertFalse(regexFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount()); // no increase
+        assertFalse(regexFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount());
+        assertFalse(regexFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount());
+    }
+
+    @Test
+    public void testAcceptCallsNestedConditionsOnlyIfPathAccepted2() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfFileName globFilter = IfFileName.createNameCondition("glob", null, counter);
+        final Path pathMatchingGlob = Paths.get("glob");
+        
+        assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+        assertEquals(1, counter.getAcceptCount());
+        assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+        assertEquals(2, counter.getAcceptCount());
+        assertTrue(globFilter.accept(null, pathMatchingGlob, null));
+        assertEquals(3, counter.getAcceptCount());
+
+        final Path noMatch = Paths.get("nomatch");
+        assertFalse(globFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount()); // no increase
+        assertFalse(globFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount());
+        assertFalse(globFilter.accept(null, noMatch, null));
+        assertEquals(3, counter.getAcceptCount());
+    }
+
+    @Test
+    public void testBeforeTreeWalk() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfFileName pathFilter = IfFileName.createNameCondition("path", null, counter, counter, counter);
+        pathFilter.beforeFileTreeWalk();
+        assertEquals(3, counter.getBeforeFileTreeWalkCount());
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfNotTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfNotTest.java
index 3563bb1..6906908 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfNotTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/rolling/action/IfNotTest.java
@@ -1,52 +1,52 @@
-/*

- * Licensed to the Apache Software Foundation (ASF) under one or more

- * contributor license agreements. See the NOTICE file distributed with

- * this work for additional information regarding copyright ownership.

- * The ASF licenses this file to You under the Apache license, Version 2.0

- * (the "License"); you may not use this file except in compliance with

- * the License. You may obtain a copy of the License at

- *

- *      http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the license for the specific language governing permissions and

- * limitations under the license.

- */

-

-package org.apache.logging.log4j.core.appender.rolling.action;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.*;

-

-/**

- * Tests the Not composite condition.

- */

-public class IfNotTest {

-

-    @Test

-    public void test() {

-        assertTrue(new FixedCondition(true).accept(null, null, null));

-        assertFalse(IfNot.createNotCondition(new FixedCondition(true)).accept(null, null, null));

-

-        assertFalse(new FixedCondition(false).accept(null, null, null));

-        assertTrue(IfNot.createNotCondition(new FixedCondition(false)).accept(null, null, null));

-    }

-

-    @Test

-    public void testEmptyIsFalse() {

-        assertThrows(NullPointerException.class,

-                () -> IfNot.createNotCondition(null).accept(null, null, null));

-    }

-

-    @Test

-    public void testBeforeTreeWalk() {

-        final CountingCondition counter = new CountingCondition(true);

-        final IfNot not = IfNot.createNotCondition(counter);

-        not.beforeFileTreeWalk();

-        assertEquals(1, counter.getBeforeFileTreeWalkCount());

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.appender.rolling.action;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests the Not composite condition.
+ */
+public class IfNotTest {
+
+    @Test
+    public void test() {
+        assertTrue(new FixedCondition(true).accept(null, null, null));
+        assertFalse(IfNot.createNotCondition(new FixedCondition(true)).accept(null, null, null));
+
+        assertFalse(new FixedCondition(false).accept(null, null, null));
+        assertTrue(IfNot.createNotCondition(new FixedCondition(false)).accept(null, null, null));
+    }
+
+    @Test
+    public void testEmptyIsFalse() {
+        assertThrows(NullPointerException.class,
+                () -> IfNot.createNotCondition(null).accept(null, null, null));
+    }
+
+    @Test
+    public void testBeforeTreeWalk() {
+        final CountingCondition counter = new CountingCondition(true);
+        final IfNot not = IfNot.createNotCondition(counter);
+        not.beforeFileTreeWalk();
+        assertEquals(1, counter.getBeforeFileTreeWalkCount());
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
index 4e14e8d..a50f877 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/DefaultRouteScriptAppenderTest.java
@@ -23,7 +23,7 @@
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.config.AppenderControl;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Assert;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppender2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppender2Test.java
index d749fdd..2efa56b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppender2Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppender2Test.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppenderTest.java
index 93ed334..dcccad2 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/JsonRoutingAppenderTest.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/PropertiesRoutingAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/PropertiesRoutingAppenderTest.java
index 30c3e8d..fd361d1 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/PropertiesRoutingAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/PropertiesRoutingAppenderTest.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
index 3b20f8f..ab55bec 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutesScriptAppenderTest.java
@@ -26,12 +26,12 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.categories.Scripts;
+import org.apache.logging.log4j.core.categories.Scripts;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.config.AppenderControl;
 import org.apache.logging.log4j.core.impl.DefaultLogEventFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Assert;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender2767Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender2767Test.java
index 1348351..006769f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender2767Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppender2767Test.java
@@ -17,9 +17,7 @@
 package org.apache.logging.log4j.core.appender.routing;
 
 import org.apache.logging.log4j.EventLogger;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.junit.After;
 import org.junit.Before;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderTest.java
index 03ec829..0d3423d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderTest.java
@@ -21,7 +21,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
index 02a8a79..14a245f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
@@ -23,8 +23,8 @@
 import javax.naming.NamingException;
 
 import org.apache.logging.log4j.EventLogger;
-import org.apache.logging.log4j.junit.JndiRule;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithPurgingTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithPurgingTest.java
index 82a571f..373820b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithPurgingTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithPurgingTest.java
@@ -28,7 +28,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingDefaultAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingDefaultAppenderTest.java
index c56e7f5..a40403c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingDefaultAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingDefaultAppenderTest.java
@@ -24,7 +24,7 @@
 
 import org.apache.logging.log4j.EventLogger;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncAppenderConfigTest_LOG4J2_2032.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncAppenderConfigTest_LOG4J2_2032.java
index fa5ddf4..9671ac2 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncAppenderConfigTest_LOG4J2_2032.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncAppenderConfigTest_LOG4J2_2032.java
@@ -20,7 +20,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
index 347b4f8..cd3df67 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerClassLoadDeadlockTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAutoFlushTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAutoFlushTest.java
index d032943..da037c7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAutoFlushTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigAutoFlushTest.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java
index 57ed7fd..e4c06f1 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigErrorOnFormat.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.impl.DefaultLogEventFactory;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
index 1e713d5..f9b7014 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest.java
@@ -27,7 +27,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.AppenderRef;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest2.java
index 3c09ff5..b865849 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest2.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest3.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest3.java
index 301fb73..8361772 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest3.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest3.java
@@ -23,7 +23,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.message.Message;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest4.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest4.java
index f4f6764..f237fbb 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest4.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigTest4.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
index 274f95a..4419820 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextCopyOnWriteTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 
 // Note: the different ThreadContextMap implementations cannot be parameterized:
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
index d022611..9247c17 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextDefaultTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 
 // Note: the different ThreadContextMap implementations cannot be parameterized:
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
index 8e6ca46..8da16ed 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigThreadContextGarbageFreeTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 
 // Note: the different ThreadContextMap implementations cannot be parameterized:
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigUseAfterShutdownTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigUseAfterShutdownTest.java
index e7dcf82..d8914cd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigUseAfterShutdownTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigUseAfterShutdownTest.java
@@ -19,7 +19,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.message.SimpleMessage;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigWithAsyncEnabledTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigWithAsyncEnabledTest.java
index 454c08e..9b21e4b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigWithAsyncEnabledTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerConfigWithAsyncEnabledTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorInitialStateTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorInitialStateTest.java
index e7b59d6..a4c68b3 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorInitialStateTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorInitialStateTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorTest.java
index 4948290..951ca42 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextSelectorTest.java
@@ -18,7 +18,7 @@
 
 import java.util.List;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextTest.java
index 875eb4c..6d53e88 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerContextTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.async;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerCustomSelectorLocationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerCustomSelectorLocationTest.java
index 94a8776..8f76278 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerCustomSelectorLocationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerCustomSelectorLocationTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerLocationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerLocationTest.java
index 5b61d8e..17cd2f0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerLocationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerLocationTest.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
index aab205b..6862dce 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTest.java
@@ -21,7 +21,7 @@
 import java.io.FileReader;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestArgumentFreedOnError.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestArgumentFreedOnError.java
index 5f9f4b5..a6a6a7d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestArgumentFreedOnError.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestArgumentFreedOnError.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.async;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.GarbageCollectionHelper;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.message.Message;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java
index 361aa6c..ca2d244 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestCachedThreadName.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestNanoTime.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestNanoTime.java
index 7995f11..fac5d06 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestNanoTime.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestNanoTime.java
@@ -22,7 +22,7 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java
index c200f26..b35bb9c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTestUncachedThreadName.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
index 0741fa9..65a2243 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextCopyOnWriteTest.java
@@ -19,7 +19,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
index e19d4c6..fbe0150 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextDefaultTest.java
@@ -19,7 +19,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
index be85037..ddb62a6 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextGarbageFreeTest.java
@@ -19,7 +19,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
index 0b5ff64..4588cc3 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadContextTest.java
@@ -23,7 +23,7 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java
index bc5945e..b3b209f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerThreadNameStrategyTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.async;
 
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTimestampMessageTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTimestampMessageTest.java
index fccb4f4..e073df6 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTimestampMessageTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerTimestampMessageTest.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.time.Clock;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerUseAfterShutdownTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerUseAfterShutdownTest.java
index 2e4ab33..70d1ad7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerUseAfterShutdownTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggerUseAfterShutdownTest.java
@@ -19,7 +19,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
index 0b345ec..d3ad6dc 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncAppenderTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncLoggerConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncLoggerConfigTest.java
index bd4747c..8360c9e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncLoggerConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncLoggersWithAsyncLoggerConfigTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java
index cd5e461..4808473 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.async;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.util.PropertiesUtil;
 import org.junit.After;
 import org.junit.Before;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncRootReloadTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncRootReloadTest.java
index 27ee560..8e37394 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncRootReloadTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/AsyncRootReloadTest.java
@@ -22,10 +22,10 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.util.FileUtils;
-import org.apache.logging.log4j.junit.CleanFiles;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DefaultAsyncQueueFullPolicyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DefaultAsyncQueueFullPolicyTest.java
index 63379ee..e29633b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DefaultAsyncQueueFullPolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DefaultAsyncQueueFullPolicyTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.async;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DiscardingAsyncQueueFullPolicyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DiscardingAsyncQueueFullPolicyTest.java
index ddcb2b6..19f38be 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DiscardingAsyncQueueFullPolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/DiscardingAsyncQueueFullPolicyTest.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.async;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java
index d4de80a..e8b2896 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688AsyncTest.java
@@ -22,10 +22,10 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java
index 5fda3d0..a885e29 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/Log4j2Jira1688Test.java
@@ -22,10 +22,10 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest.java
index b0aa3ea..d949254 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest.java
@@ -21,9 +21,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest2.java
index b592dc8..311a479 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncAppenderTest2.java
@@ -20,9 +20,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
index b13bbd3..a849c21 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest.java
@@ -23,9 +23,9 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.Before;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
index c248d99..a36125f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigLoggingFromToStringTest2.java
@@ -20,9 +20,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
index 28e6659..1b977f8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest.java
@@ -21,9 +21,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
index 6e38421..43ce2de 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerConfigTest2.java
@@ -20,9 +20,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
index 2020cbf..7d29076 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest.java
@@ -21,11 +21,11 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
index 0ff31af..96384cc 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerLoggingFromToStringTest2.java
@@ -21,11 +21,11 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
index 3bc8be4..af1bba4 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest.java
@@ -21,10 +21,10 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.ParameterizedMessage;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
index 3f06a5c..1840832 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest2.java
@@ -20,10 +20,10 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
 import org.junit.Before;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
index 2ec737c..12024ad 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/QueueFullAsyncLoggerTest3.java
@@ -18,11 +18,11 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.GarbageCollectionHelper;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
index 07a02c7..3e5faf8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java
@@ -28,7 +28,7 @@
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext.ContextStack;
-import org.apache.logging.log4j.categories.AsyncLoggers;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.time.internal.DummyNanoClock;
 import org.apache.logging.log4j.core.time.internal.FixedPreciseClock;
@@ -111,6 +111,7 @@
         assertEquals(456, evt.getInstant().getNanoOfMillisecond());
     }
 
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testSerializationDeserialization() throws IOException, ClassNotFoundException {
         final RingBufferLogEvent evt = new RingBufferLogEvent();
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Appenders.java
similarity index 67%
copy from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Appenders.java
index d53dc43..15fdba8 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Appenders.java
@@ -14,11 +14,20 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * Categories for appenders that require extra dependencies.
  */
-public class Dummy {
+public interface Appenders {
+    interface AsyncConversant {}
+    interface AsyncJcTools {}
+    interface Cassandra {}
+    interface CouchDb {}
+    interface Jms {}
+    interface Jpa {}
+    interface Kafka {}
+    interface MongoDb {}
+    interface Smtp {}
+    interface ZeroMq {}
 }
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/AsyncLoggers.java
similarity index 80%
copy from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/AsyncLoggers.java
index d53dc43..eb64669 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/AsyncLoggers.java
@@ -14,11 +14,10 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * Category for tests related to AsyncLogger (requires LMAX Disruptor dependency).
  */
-public class Dummy {
+public interface AsyncLoggers {
 }
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Configurations.java
similarity index 79%
copy from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Configurations.java
index d53dc43..e7eee4e 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Configurations.java
@@ -14,11 +14,12 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * Categories for configuration formats that require extra dependencies.
  */
-public class Dummy {
+public interface Configurations {
+    interface Json {}
+    interface Yaml {}
 }
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Layouts.java
similarity index 76%
copy from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Layouts.java
index d53dc43..1052f89 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Layouts.java
@@ -14,11 +14,15 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * Categories for layouts that require extra dependencies.
  */
-public class Dummy {
+public interface Layouts {
+    interface Csv {}
+    interface Jansi {}
+    interface Json {}
+    interface Xml {}
+    interface Yaml {}
 }
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/PerformanceTests.java
similarity index 62%
copy from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/PerformanceTests.java
index d53dc43..51e41f9 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/PerformanceTests.java
@@ -1,12 +1,12 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
+ * 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
+ * the License.  You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,11 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * JUnit category to indicate a test is primarily for testing performance.
  */
-public class Dummy {
+public interface PerformanceTests {
 }
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Scripts.java
similarity index 80%
rename from log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
rename to log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Scripts.java
index d53dc43..a9efac2 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/status/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/Scripts.java
@@ -14,11 +14,11 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.status;
+package org.apache.logging.log4j.core.categories;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * Categories for script plugins that require extra dependencies.
  */
-public class Dummy {
+public interface Scripts {
+    interface Groovy {}
 }
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/package-info.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/package-info.java
new file mode 100644
index 0000000..76ef43c
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/categories/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.
+ */
+
+/**
+ * JUnit test categories. Unit tests should not specify a category as most tests are unit tests. For performance and
+ * integration tests, an appropriate category interface should be specified.
+ */
+package org.apache.logging.log4j.core.categories;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
index ae59552..3db6ce0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CompositeConfigurationTest.java
@@ -27,7 +27,7 @@
 import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
 import org.apache.logging.log4j.core.filter.RegexFilter;
 import org.apache.logging.log4j.core.util.Throwables;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.Description;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfigurationFactoryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfigurationFactoryTest.java
index 4ebd877..bc1958a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfigurationFactoryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ConfigurationFactoryTest.java
@@ -24,8 +24,8 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.filter.ThreadContextMapFilter;
-import org.apache.logging.log4j.junit.CleanUpFiles;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.CleanUpFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java
index 69f17ab..41c04a0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/CustomConfigurationTest.java
@@ -23,8 +23,8 @@
 import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
 import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.junit.CleanUpFiles;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.CleanUpFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.status.StatusConsoleListener;
 import org.apache.logging.log4j.status.StatusListener;
 import org.apache.logging.log4j.status.StatusLogger;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/FileOutputTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/FileOutputTest.java
index 6e6094c..5b8a732 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/FileOutputTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/FileOutputTest.java
@@ -16,8 +16,8 @@
  */
 package org.apache.logging.log4j.core.config;
 
-import org.apache.logging.log4j.junit.CleanUpFiles;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.CleanUpFiles;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/JiraLog4j2_2134Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/JiraLog4j2_2134Test.java
index e1d1799..e9bae4f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/JiraLog4j2_2134Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/JiraLog4j2_2134Test.java
@@ -24,7 +24,7 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Tag;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/LoggersPluginTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/LoggersPluginTest.java
index 37d2307..0c06e97 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/LoggersPluginTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/LoggersPluginTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.status.StatusData;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
index 67e4d3e..a4d11db 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MissingRootLoggerTest.java
@@ -22,10 +22,10 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
-import static org.apache.logging.log4j.hamcrest.MapMatchers.hasSize;
+import static org.apache.logging.log4j.core.hamcrest.MapMatchers.hasSize;
 import static org.hamcrest.MatcherAssert.*;
 import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.instanceOf;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MultipleTriggeringPolicyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MultipleTriggeringPolicyTest.java
index 088495f..d73fefe 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MultipleTriggeringPolicyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/MultipleTriggeringPolicyTest.java
@@ -22,7 +22,7 @@
 import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
 import org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy;
 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/PropertyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/PropertyTest.java
index e021185..6cd1213 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/PropertyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/PropertyTest.java
@@ -18,8 +18,8 @@
 import java.util.List;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
index 399e3e5..6849734 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReconfigurationDeadlockTest.java
@@ -27,7 +27,7 @@
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.validation.constraints.Required;
 import org.junit.jupiter.api.AfterEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReliabilityStrategyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReliabilityStrategyTest.java
index 0b68e27..6a23135 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReliabilityStrategyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/ReliabilityStrategyTest.java
@@ -18,8 +18,8 @@
 package org.apache.logging.log4j.core.config;
 
 import org.apache.logging.log4j.core.appender.AsyncAppender;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
index e6d8541..12ae352 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfigurator.java
@@ -43,7 +43,7 @@
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
-import static org.apache.logging.log4j.hamcrest.MapMatchers.hasSize;
+import static org.apache.logging.log4j.core.hamcrest.MapMatchers.hasSize;
 import static org.hamcrest.MatcherAssert.*;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java
index 8649984..c7d67f7 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.config;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextFactoryExtension;
+import org.apache.logging.log4j.test.junit.LoggerContextFactoryExtension;
 import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/LegacyPluginTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/LegacyPluginTest.java
index 757089f..c28fc23 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/LegacyPluginTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/LegacyPluginTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import java.util.Map;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/PluginManagerPackagesTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/PluginManagerPackagesTest.java
index 7e4aae3..a6d9750 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/PluginManagerPackagesTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/PluginManagerPackagesTest.java
@@ -19,7 +19,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/RequiredValidatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/RequiredValidatorTest.java
index 97bfe36..195837f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/RequiredValidatorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/RequiredValidatorTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.ValidatingPlugin;
+import org.apache.logging.log4j.plugins.test.validation.ValidatingPlugin;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidHostValidatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidHostValidatorTest.java
index caf760f..d13b655 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidHostValidatorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidHostValidatorTest.java
@@ -18,11 +18,11 @@
 
 import org.apache.logging.log4j.core.config.NullConfiguration;
 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
-import org.apache.logging.log4j.junit.StatusLoggerLevel;
+import org.apache.logging.log4j.test.junit.StatusLoggerLevel;
 import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.HostAndPort;
+import org.apache.logging.log4j.plugins.test.validation.HostAndPort;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidPortValidatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidPortValidatorTest.java
index 3a4146d..3a11f56 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidPortValidatorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidPortValidatorTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.HostAndPort;
+import org.apache.logging.log4j.plugins.test.validation.HostAndPort;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericBuilderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericBuilderTest.java
index 4c42a7b..fe7f483 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericBuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericBuilderTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.ValidatingPluginWithGenericBuilder;
+import org.apache.logging.log4j.plugins.test.validation.ValidatingPluginWithGenericBuilder;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericSubclassFoo1BuilderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericSubclassFoo1BuilderTest.java
index f43ee88..bfd335d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericSubclassFoo1BuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithGenericSubclassFoo1BuilderTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.PluginWithGenericSubclassFoo1Builder;
+import org.apache.logging.log4j.plugins.test.validation.PluginWithGenericSubclassFoo1Builder;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithTypedBuilderTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithTypedBuilderTest.java
index cafc125..69e1127 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithTypedBuilderTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/validation/validators/ValidatingPluginWithTypedBuilderTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.core.config.plugins.util.PluginBuilder;
 import org.apache.logging.log4j.plugins.util.PluginManager;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.validation.ValidatingPluginWithTypedBuilder;
+import org.apache.logging.log4j.plugins.test.validation.ValidatingPluginWithTypedBuilder;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationTest.java
index 1a75512..c515fec 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/properties/PropertiesConfigurationTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Test;
 
 import java.util.Map;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlLoggerPropsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlLoggerPropsTest.java
index b191524..674eaa4 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlLoggerPropsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlLoggerPropsTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core.config.xml;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
index 6f2dc63..fc77496 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/AbstractScriptFilterTest.java
@@ -21,8 +21,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/BurstFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/BurstFilterTest.java
index 16484f4..309715e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/BurstFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/BurstFilterTest.java
@@ -21,8 +21,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java
index 87ba9dd..99374b8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/DynamicThresholdFilterTest.java
@@ -23,8 +23,8 @@
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.util.KeyValuePair;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/MapFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/MapFilterTest.java
index f44ac47..95456c5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/MapFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/MapFilterTest.java
@@ -27,8 +27,8 @@
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.util.KeyValuePair;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.message.StringMapMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
index 4d7acc4..1364619 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterPropertiesTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.filter;
 
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 
 @LoggerContextSource("log4j-scriptFile-filters.properties")
 public class ScriptFileFilterPropertiesTest extends AbstractScriptFilterTest {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
index 0cb652d..97fe6d2 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFileFilterTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.filter;
 
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 
 @LoggerContextSource("log4j-scriptFile-filters.xml")
 public class ScriptFileFilterTest extends AbstractScriptFilterTest {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
index ff0a51b..be25741 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptFilterTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.filter;
 
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 
 @LoggerContextSource("log4j-script-filters.xml")
 public class ScriptFilterTest extends AbstractScriptFilterTest {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
index 9d6b863..93131a4 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/ScriptRefFilterTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.filter;
 
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 
 @LoggerContextSource("log4j-scriptRef-filters.xml")
 public class ScriptRefFilterTest extends AbstractScriptFilterTest {
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java
index b1689dd..ca3b892 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/filter/StructuredDataFilterTest.java
@@ -22,7 +22,7 @@
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.util.KeyValuePair;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/Descriptors.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/Descriptors.java
new file mode 100644
index 0000000..f45a6a6
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/Descriptors.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.log4j.core.hamcrest;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.core.Is;
+
+/**
+ * Grammatical descriptor decorators for Matchers.
+ *
+ * @since 2.1
+ */
+public class Descriptors {
+    /**
+     * Decorating Matcher similar to {@code is()}, but for better grammar.
+     *
+     * @param matcher the Matcher to decorate.
+     * @param <T> the type expected by the Matcher.
+     * @return the decorated Matcher.
+     */
+    public static <T> Matcher<T> that(final Matcher<T> matcher) {
+        return new Is<T>(matcher) {
+            @Override
+            public void describeTo(final Description description) {
+                description.appendText("that ").appendDescriptionOf(matcher);
+            }
+        };
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/FileMatchers.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/FileMatchers.java
new file mode 100644
index 0000000..581ac40
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/FileMatchers.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.hamcrest;
+
+import java.io.File;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.number.OrderingComparison.greaterThan;
+import static org.hamcrest.number.OrderingComparison.lessThanOrEqualTo;
+
+/**
+ * Hamcrest Matchers that operate on File objects.
+ *
+ * @since 2.1
+ */
+public final class FileMatchers {
+
+    /**
+     * Matches if the File exists.
+     *
+     * @return the Matcher.
+     */
+    public static Matcher<File> exists() {
+        return new FeatureMatcher<File, Boolean>(is(true), "file exists", "file exists") {
+            @Override
+            protected Boolean featureValueOf(final File actual) {
+                return actual.exists();
+            }
+        };
+    }
+
+    /**
+     * Matches a Long Matcher against the file length.
+     *
+     * @param matcher the Matcher to use on the File length.
+     * @return the Matcher.
+     */
+    public static Matcher<File> hasLength(final Matcher<Long> matcher) {
+        return new FeatureMatcher<File, Long>(matcher, "file with size", "file with size") {
+            @Override
+            protected Long featureValueOf(final File actual) {
+                return actual.length();
+            }
+        };
+    }
+
+    /**
+     * Matches a specific file length.
+     *
+     * @param length the file length to match
+     * @param <T>    the type of the length.
+     * @return the Matcher.
+     */
+    public static <T extends Number> Matcher<File> hasLength(final T length) {
+        return hasLength(equalTo(length.longValue()));
+    }
+
+    /**
+     * Matches a specific file length.
+     *
+     * @param length the file length to match
+     * @return the Matcher.
+     */
+    public static Matcher<File> hasLength(final long length) {
+        return hasLength(equalTo(length));
+    }
+
+    /**
+     * Matches a file with length equal to zero.
+     *
+     * @return the Matcher.
+     */
+    public static Matcher<File> isEmpty() {
+        return hasLength(0L);
+    }
+
+    /**
+     * Matches against a file's last modification time in milliseconds.
+     *
+     * @param matcher the Matcher to use on the File modification time.
+     * @return the Matcher.
+     */
+    public static Matcher<File> lastModified(final Matcher<Long> matcher) {
+        return new FeatureMatcher<File, Long>(matcher, "was last modified", "was last modified") {
+            @Override
+            protected Long featureValueOf(final File actual) {
+                return actual.lastModified();
+            }
+        };
+    }
+
+    /**
+     * Matches a time in millis before the current time.
+     *
+     * @return the Matcher.
+     */
+    public static Matcher<Long> beforeNow() {
+        return lessThanOrEqualTo(System.currentTimeMillis());
+    }
+
+    /**
+     * Matches the number of files in a directory.
+     *
+     * @param matcher the Matcher to use on the number of files.
+     * @return the Matcher.
+     */
+    public static Matcher<File> hasNumberOfFiles(final Matcher<Integer> matcher) {
+        return new FeatureMatcher<File, Integer>(matcher, "directory with number of files",
+            "directory with number of files") {
+            @Override
+            protected Integer featureValueOf(final File actual) {
+                final File[] files = actual.listFiles();
+                return files == null ? 0 : files.length;
+            }
+        };
+    }
+
+    /**
+     * Matches a directory with at least one file.
+     *
+     * @return the Matcher.
+     */
+    public static Matcher<File> hasFiles() {
+        return hasNumberOfFiles(greaterThan(0));
+    }
+
+    /**
+     * Matches a file name.
+     *
+     * @param matcher the Matcher to use on the file name.
+     * @return the Matcher.
+     */
+    public static Matcher<File> hasName(final Matcher<String> matcher) {
+        return new FeatureMatcher<File, String>(matcher, "file named", "file named") {
+            @Override
+            protected String featureValueOf(final File actual) {
+                return actual.getName();
+            }
+        };
+    }
+
+    private FileMatchers() {
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/MapMatchers.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/MapMatchers.java
new file mode 100644
index 0000000..078214b
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/hamcrest/MapMatchers.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.hamcrest;
+
+import java.util.Map;
+
+import org.hamcrest.FeatureMatcher;
+import org.hamcrest.Matcher;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+
+/**
+ * Hamcrest Matchers for Maps.
+ *
+ * @since 2.1
+ */
+public final class MapMatchers {
+
+    /**
+     * Returns a Map Matcher matching on the size of a Map.
+     *
+     * @param matcher the Matcher to match against the Map size.
+     * @param <K>     the key type.
+     * @param <V>     the value type.
+     */
+    public static <K, V> Matcher<Map<? extends K, ? extends V>> hasSize(final Matcher<Integer> matcher) {
+        return new FeatureMatcher<Map<? extends K, ? extends V>, Integer>(matcher, "map with size", "map with size") {
+            @Override
+            protected Integer featureValueOf(final Map<? extends K, ? extends V> actual) {
+                return actual.size();
+            }
+        };
+    }
+
+    /**
+     * Returns a Map Matcher matching on the exact size of a Map.
+     *
+     * @param size the number of entries to match the Map against.
+     * @param <K>  the key type.
+     * @param <V>  the value type.
+     */
+    public static <K, V> Matcher<Map<? extends K, ? extends V>> hasSize(final int size) {
+        return hasSize(equalTo(size));
+    }
+
+    private MapMatchers() {
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/JdkMapAdapterStringMapTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/JdkMapAdapterStringMapTest.java
index b15e0d4..0f2d229 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/JdkMapAdapterStringMapTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/JdkMapAdapterStringMapTest.java
@@ -70,6 +70,7 @@
         return arr.toByteArray();
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private JdkMapAdapterStringMap deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
         final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
         final ObjectInputStream in = new ObjectInputStream(inArr);
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
index afdfd15..7692de9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java
@@ -157,6 +157,7 @@
         return arr.toByteArray();
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private Log4jLogEvent deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
         final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
         final ObjectInputStream in = new FilteredObjectInputStream(inArr);
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
index f7f5478..d6639b1 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java
@@ -364,6 +364,7 @@
         return arr.toByteArray();
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private Log4jLogEvent deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
         final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
         final ObjectInputStream in = useObjectInputStream ? new ObjectInputStream(inArr) :
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromThrowableMessageTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromThrowableMessageTest.java
index 912f1a8..59afd62 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromThrowableMessageTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromThrowableMessageTest.java
@@ -19,7 +19,7 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.CoreLoggerContexts;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromToStringTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromToStringTest.java
index 30dbef9..6563eff 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromToStringTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/NestedLoggingFromToStringTest.java
@@ -20,7 +20,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.BeforeClass;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
index 2742da1..9ffdddf 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java
@@ -4,9 +4,9 @@
 import java.util.concurrent.ExecutionException;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.ThreadContextTest;
 import org.apache.logging.log4j.core.ContextDataInjector;
 import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap;
+import org.apache.logging.log4j.test.ThreadContextTest;
 import org.apache.logging.log4j.util.PropertiesUtil;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
 import org.apache.logging.log4j.util.StringMap;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
index bf8b69d..893dced 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ThrowableProxyTest.java
@@ -67,6 +67,7 @@
         ThrowableProxy proxy = new ThrowableProxy(new IOException("test"));
     }
 
+    @SuppressWarnings("BanSerializableRead")
     private ThrowableProxy deserialize(final byte[] binary) throws IOException, ClassNotFoundException {
         final ByteArrayInputStream inArr = new ByteArrayInputStream(binary);
         final ObjectInputStream in = new ObjectInputStream(inArr);
@@ -367,6 +368,7 @@
      * unloaded known class (already compiled and available as a test resource:
      * org.apache.logging.log4j.core.impl.ForceNoDefClassFoundError.class).
      */
+    @SuppressWarnings("BanSerializableRead")
     @Test
     public void testStackWithUnloadableClass() throws Exception {
         final Stack<Class<?>> stack = new Stack<>();
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/AppenderResolver.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/AppenderResolver.java
new file mode 100644
index 0000000..88ec29b
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/AppenderResolver.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.junit;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+import static org.apache.logging.log4j.core.junit.LoggerContextResolver.getParameterLoggerContext;
+
+class AppenderResolver implements ParameterResolver {
+    @Override
+    public boolean supportsParameter(
+            ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return Appender.class.isAssignableFrom(parameterContext.getParameter().getType()) && parameterContext
+                .isAnnotated(Named.class);
+    }
+
+    @Override
+    public Object resolveParameter(
+            ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        final LoggerContext loggerContext = getParameterLoggerContext(parameterContext, extensionContext);
+        if (loggerContext == null) {
+            throw new ParameterResolutionException("No LoggerContext defined");
+        }
+        final String name = parameterContext.findAnnotation(Named.class)
+                .map(Named::value)
+                .map(s -> s.isEmpty() ? parameterContext.getParameter().getName() : s)
+                .orElseThrow(() -> new ParameterResolutionException("No @Named present after checking earlier"));
+        final Appender appender = loggerContext.getConfiguration().getAppender(name);
+        if (appender == null) {
+            throw new ParameterResolutionException("No appender named " + name);
+        }
+        return appender;
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ConfigurationResolver.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ConfigurationResolver.java
new file mode 100644
index 0000000..bb713f1
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ConfigurationResolver.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.junit;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver;
+
+import static org.apache.logging.log4j.core.junit.LoggerContextResolver.getParameterLoggerContext;
+
+class ConfigurationResolver extends TypeBasedParameterResolver<Configuration> {
+    @Override
+    public Configuration resolveParameter(
+            ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        final LoggerContext loggerContext = getParameterLoggerContext(parameterContext, extensionContext);
+        if (loggerContext == null) {
+            throw new ParameterResolutionException("No LoggerContext defined");
+        }
+        return loggerContext.getConfiguration();
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/JndiRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/JndiRule.java
new file mode 100644
index 0000000..4ade779
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/JndiRule.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.log4j.core.junit;
+
+import java.util.Collections;
+import java.util.Map;
+import javax.naming.Context;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.springframework.mock.jndi.SimpleNamingContextBuilder;
+
+/**
+ * JUnit rule to create a mock {@link Context} and bind an object to a name.
+ *
+ * @since 2.8
+ */
+public class JndiRule implements TestRule {
+
+    private final Map<String, Object> initialBindings;
+
+    public JndiRule(final String name, final Object value) {
+        this.initialBindings = Collections.singletonMap(name, value);
+    }
+
+    public JndiRule(final Map<String, Object> initialBindings) {
+        this.initialBindings = initialBindings;
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                final SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
+                for (final Map.Entry<String, Object> entry : initialBindings.entrySet()) {
+                    builder.bind(entry.getKey(), entry.getValue());
+                }
+                base.evaluate();
+            }
+        };
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextResolver.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextResolver.java
new file mode 100644
index 0000000..11193d5
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextResolver.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.junit;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.LoggerContextAccessor;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+class LoggerContextResolver extends TypeBasedParameterResolver<LoggerContext> implements BeforeAllCallback,
+        AfterAllCallback, BeforeEachCallback, AfterEachCallback {
+    @Override
+    public void beforeAll(ExtensionContext context) throws Exception {
+        final Class<?> testClass = context.getRequiredTestClass();
+        final LoggerContextSource testSource = testClass.getAnnotation(LoggerContextSource.class);
+        if (testSource != null) {
+            final LoggerContextConfig config = new LoggerContextConfig(testSource, context);
+            getTestClassStore(context).put(LoggerContext.class, config);
+        }
+    }
+
+    @Override
+    public void afterAll(ExtensionContext context) throws Exception {
+        final LoggerContextConfig config =
+                getTestClassStore(context).get(LoggerContext.class, LoggerContextConfig.class);
+        if (config != null) {
+            config.close();
+        }
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext context) throws Exception {
+        final Class<?> testClass = context.getRequiredTestClass();
+        if (testClass.isAnnotationPresent(LoggerContextSource.class)) {
+            final LoggerContextConfig config = getTestClassStore(context).get(LoggerContext.class, LoggerContextConfig.class);
+            if (config == null) {
+                throw new IllegalStateException(
+                        "Specified @LoggerContextSource but no LoggerContext found for test class " +
+                                testClass.getCanonicalName());
+            }
+            if (config.reconfigurationPolicy == ReconfigurationPolicy.BEFORE_EACH) {
+                config.reconfigure();
+            }
+        }
+        final LoggerContextSource source = context.getRequiredTestMethod().getAnnotation(LoggerContextSource.class);
+        if (source != null) {
+            final LoggerContextConfig config = new LoggerContextConfig(source, context);
+            if (config.reconfigurationPolicy == ReconfigurationPolicy.BEFORE_EACH) {
+                config.reconfigure();
+            }
+            getTestInstanceStore(context).put(LoggerContext.class, config);
+        }
+    }
+
+    @Override
+    public void afterEach(ExtensionContext context) throws Exception {
+        // method-annotated variant
+        final LoggerContextConfig testInstanceConfig =
+                getTestInstanceStore(context).get(LoggerContext.class, LoggerContextConfig.class);
+        if (testInstanceConfig != null) {
+            testInstanceConfig.close();
+        }
+        // reloadable variant
+        final Class<?> testClass = context.getRequiredTestClass();
+        if (testClass.isAnnotationPresent(LoggerContextSource.class)) {
+            final LoggerContextConfig config = getTestClassStore(context).get(LoggerContext.class, LoggerContextConfig.class);
+            if (config == null) {
+                throw new IllegalStateException(
+                        "Specified @LoggerContextSource but no LoggerContext found for test class " +
+                                testClass.getCanonicalName());
+            }
+            if (config.reconfigurationPolicy == ReconfigurationPolicy.AFTER_EACH) {
+                config.reconfigure();
+            }
+        }
+    }
+
+    @Override
+    public LoggerContext resolveParameter(
+            ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return getParameterLoggerContext(parameterContext, extensionContext);
+    }
+
+    private static ExtensionContext.Store getTestClassStore(final ExtensionContext context) {
+        return context.getStore(ExtensionContext.Namespace.create(LoggerContext.class, context.getRequiredTestClass()));
+    }
+
+    private static ExtensionContext.Store getTestInstanceStore(final ExtensionContext context) {
+        return context.getStore(ExtensionContext.Namespace.create(LoggerContext.class, context.getRequiredTestInstance()));
+    }
+
+    static LoggerContext getParameterLoggerContext(ParameterContext parameterContext, ExtensionContext extensionContext) {
+        if (parameterContext.getDeclaringExecutable() instanceof Method) {
+            final LoggerContextAccessor accessor =
+                    getTestInstanceStore(extensionContext).get(LoggerContext.class, LoggerContextAccessor.class);
+            return accessor != null ? accessor.getLoggerContext() :
+                    getTestClassStore(extensionContext).get(LoggerContext.class, LoggerContextAccessor.class).getLoggerContext();
+        }
+        return getTestClassStore(extensionContext).get(LoggerContext.class, LoggerContextAccessor.class).getLoggerContext();
+    }
+
+    private static class LoggerContextConfig implements AutoCloseable, LoggerContextAccessor {
+        private final LoggerContext context;
+        private final ReconfigurationPolicy reconfigurationPolicy;
+        private final long shutdownTimeout;
+        private final TimeUnit unit;
+
+        private LoggerContextConfig(final LoggerContextSource source, final ExtensionContext extensionContext) {
+            final String displayName = extensionContext.getDisplayName();
+            final ClassLoader classLoader = extensionContext.getRequiredTestClass().getClassLoader();
+            context = Configurator.initialize(displayName, classLoader, source.value());
+            reconfigurationPolicy = source.reconfigure();
+            shutdownTimeout = source.timeout();
+            unit = source.unit();
+        }
+
+        @Override
+        public LoggerContext getLoggerContext() {
+            return context;
+        }
+
+        public void reconfigure() {
+            context.reconfigure();
+        }
+
+        @Override
+        public void close() {
+            context.stop(shutdownTimeout, unit);
+        }
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextRule.java
new file mode 100644
index 0000000..af422bb
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextRule.java
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.junit;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.AbstractLifeCycle;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.LoggerContextAccessor;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.core.util.Constants;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.test.junit.CleanFolders;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import static org.junit.Assert.*;
+
+/**
+ * JUnit {@link TestRule} for constructing a new LoggerContext using a specified configuration file. If the system
+ * property {@code EBUG} is set (e.g., through the command line option {@code -DEBUG}), then the StatusLogger will be
+ * set to the debug level. This allows for more debug messages as the StatusLogger will be in the error level until a
+ * configuration file has been read and parsed into a tree of Nodes.
+ *
+ * @see LoggerContextSource
+ * @see Named
+ */
+public class LoggerContextRule implements TestRule, LoggerContextAccessor {
+
+    public static LoggerContextRule createShutdownTimeoutLoggerContextRule(final String config) {
+        return new LoggerContextRule(config, 10, TimeUnit.SECONDS);
+    }
+    
+    private static final String SYS_PROP_KEY_CLASS_NAME = "org.apache.logging.log4j.junit.LoggerContextRule#ClassName";
+    private static final String SYS_PROP_KEY_DISPLAY_NAME = "org.apache.logging.log4j.junit.LoggerContextRule#DisplayName";
+    private final String configurationLocation;
+    private LoggerContext loggerContext;
+    private Class<? extends ContextSelector> contextSelectorClass;
+    private String testClassName;
+    private final long shutdownTimeout;
+    private final TimeUnit shutdownTimeUnit;
+
+    /**
+     * Constructs a new LoggerContextRule without a configuration file.
+     */
+    public LoggerContextRule() {
+        this(null, null);
+    }
+
+    /**
+     * Constructs a new LoggerContextRule for a given configuration file.
+     *
+     * @param configurationLocation
+     *            path to configuration file
+     */
+    public LoggerContextRule(final String configurationLocation) {
+        this(configurationLocation, null);
+    }
+
+    /**
+     * Constructs a new LoggerContextRule for a given configuration file and a custom {@link ContextSelector} class.
+     *
+     * @param configurationLocation
+     *            path to configuration file
+     * @param contextSelectorClass
+     *            custom ContextSelector class to use instead of default
+     */
+    public LoggerContextRule(final String configurationLocation, final Class<? extends ContextSelector> contextSelectorClass) {
+        this(configurationLocation, contextSelectorClass, AbstractLifeCycle.DEFAULT_STOP_TIMEOUT,
+                AbstractLifeCycle.DEFAULT_STOP_TIMEUNIT);
+    }
+
+    public LoggerContextRule(final String configurationLocation, final Class<? extends ContextSelector> contextSelectorClass,
+            final long shutdownTimeout, final TimeUnit shutdownTimeUnit) {
+        this.configurationLocation = configurationLocation;
+        this.contextSelectorClass = contextSelectorClass;
+        this.shutdownTimeout = shutdownTimeout;
+        this.shutdownTimeUnit = shutdownTimeUnit;
+    }
+
+    public LoggerContextRule(final String configurationLocation, final int shutdownTimeout, final TimeUnit shutdownTimeUnit) {
+        this(configurationLocation, null, shutdownTimeout, shutdownTimeUnit);
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        // Hack: Using -DEBUG as a JVM param sets a property called "EBUG"...
+        if (System.getProperties().containsKey("EBUG")) {
+            StatusLogger.getLogger().setLevel(Level.DEBUG);
+        }
+        testClassName = description.getClassName();
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                if (contextSelectorClass != null) {
+                    System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR, contextSelectorClass.getName());
+                }
+                // TODO Consider instead of the above:
+                // LogManager.setFactory(new Log4jContextFactory(LoaderUtil.newInstanceOf(contextSelectorClass)));
+                System.setProperty(SYS_PROP_KEY_CLASS_NAME, description.getClassName());
+                System.setProperty(SYS_PROP_KEY_DISPLAY_NAME, description.getDisplayName());
+                loggerContext = Configurator.initialize(description.getDisplayName(),
+                        description.getTestClass().getClassLoader(), configurationLocation);
+                try {
+                    base.evaluate();
+                } finally {
+                    if (!Configurator.shutdown(loggerContext, shutdownTimeout, shutdownTimeUnit)) {
+                        StatusLogger.getLogger().error("Logger context {} did not shutdown completely after {} {}.",
+                                loggerContext.getName(), shutdownTimeout, shutdownTimeUnit);
+                    }
+                    loggerContext = null;
+                    contextSelectorClass = null;
+                    StatusLogger.getLogger().reset();
+                    System.clearProperty(Constants.LOG4J_CONTEXT_SELECTOR);
+                    System.clearProperty(SYS_PROP_KEY_CLASS_NAME);
+                    System.clearProperty(SYS_PROP_KEY_DISPLAY_NAME);
+                }
+            }
+        };
+
+    }
+
+    /**
+     * Gets a named Appender for this LoggerContext.
+     *
+     * @param name
+     *            the name of the Appender to look up.
+     * @return the named Appender or {@code null} if it wasn't defined in the configuration.
+     */
+    @SuppressWarnings("unchecked") // Assume the call site knows what it is doing.
+     public <T extends Appender> T getAppender(final String name) {
+         return (T) getConfiguration().getAppenders().get(name);
+     }
+
+    /**
+     * Gets a named Appender for this LoggerContext.
+     *
+     * @param <T>
+     *            The target Appender class
+     * @param name
+     *            the name of the Appender to look up.
+     * @param cls
+     *            The target Appender class
+     * @return the named Appender or {@code null} if it wasn't defined in the configuration.
+     */
+    public <T extends Appender> T getAppender(final String name, final Class<T> cls) {
+        return cls.cast(getConfiguration().getAppenders().get(name));
+    }
+
+    /**
+     * Gets the associated Configuration for the configuration file this was constructed with.
+     *
+     * @return this LoggerContext's Configuration.
+     */
+    public Configuration getConfiguration() {
+        return loggerContext.getConfiguration();
+    }
+
+    /**
+     * Gets the configuration location.
+     * 
+     * @return the configuration location.
+     */
+    public String getConfigurationLocation() {
+        return configurationLocation;
+    }
+
+    /**
+     * Gets the current LoggerContext associated with this rule.
+     *
+     * @return the current LoggerContext.
+     */
+    @Override
+    public LoggerContext getLoggerContext() {
+        return loggerContext;
+    }
+
+    /**
+     * Gets a named ListAppender or throws an exception for this LoggerContext.
+     *
+     * @param name
+     *            the name of the ListAppender to look up.
+     * @return the named ListAppender.
+     * @throws AssertionError
+     *             if the named ListAppender doesn't exist or isn't a ListAppender.
+     */
+    public ListAppender getListAppender(final String name) {
+        final Appender appender = getAppender(name);
+        if (appender instanceof ListAppender) {
+            return (ListAppender) appender;
+        }
+        throw new AssertionError("No ListAppender named " + name + " found.");
+    }
+
+    /**
+     * Gets a named Logger using the test class's name from this LoggerContext.
+     *
+     * @return the test class's named Logger.
+     */
+    public Logger getLogger() {
+        return loggerContext.getLogger(testClassName);
+    }
+
+    /**
+     * Gets a named Logger for the given class in this LoggerContext.
+     *
+     * @param clazz
+     *            The Class whose name should be used as the Logger name. If null it will default to the calling class.
+     * @return the named Logger.
+     */
+    public Logger getLogger(final Class<?> clazz) {
+        return loggerContext.getLogger(clazz.getName());
+    }
+
+    /**
+     * Gets a named Logger in this LoggerContext.
+     *
+     * @param name
+     *            the name of the Logger to look up or create.
+     * @return the named Logger.
+     */
+    public Logger getLogger(final String name) {
+        return loggerContext.getLogger(name);
+    }
+
+    /**
+     * Gets a named Appender or throws an exception for this LoggerContext.
+     *
+     * @param name
+     *            the name of the Appender to look up.
+     * @return the named Appender.
+     * @throws AssertionError
+     *             if the Appender doesn't exist.
+     */
+    public Appender getRequiredAppender(final String name) {
+        final Appender appender = getAppender(name);
+        assertNotNull("Appender named " + name + " was null.", appender);
+        return appender;
+    }
+
+    /**
+     * Gets a named Appender or throws an exception for this LoggerContext.
+     *
+     * @param <T>
+     *            The target Appender class
+     * @param name
+     *            the name of the Appender to look up.
+     * @param cls
+     *            The target Appender class
+     * @return the named Appender.
+     * @throws AssertionError
+     *             if the Appender doesn't exist.
+     */
+    public <T extends Appender> T getRequiredAppender(final String name, final Class<T> cls) {
+        final T appender = getAppender(name, cls);
+        assertNotNull("Appender named " + name + " was null in logger context " + loggerContext, appender);
+        return appender;
+    }
+
+    /**
+     * Gets the root logger.
+     *
+     * @return the root logger.
+     */
+    public Logger getRootLogger() {
+        return loggerContext.getRootLogger();
+    }
+
+    public void reconfigure() {
+        loggerContext.reconfigure();
+    }
+    
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder();
+        builder.append("LoggerContextRule [configLocation=");
+        builder.append(configurationLocation);
+        builder.append(", contextSelectorClass=");
+        builder.append(contextSelectorClass);
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public RuleChain withCleanFilesRule(final String... files) {
+        return RuleChain.outerRule(new CleanFiles(files)).around(this);
+    }
+
+    public RuleChain withCleanFoldersRule(final boolean before, final boolean after, final int maxTries, final String... folders) {
+        return RuleChain.outerRule(new CleanFolders(before, after, maxTries, folders)).around(this);
+    }
+
+    public RuleChain withCleanFoldersRule(final String... folders) {
+        return RuleChain.outerRule(new CleanFolders(folders)).around(this);
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextSource.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextSource.java
new file mode 100644
index 0000000..a63f0b8
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/LoggerContextSource.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.junit;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Specifies a configuration file to use for unit tests. This configuration file will be loaded once and used for all tests
+ * executed in the annotated test class unless otherwise specified by {@link #reconfigure()}. When annotated on a test method,
+ * this will override the class-level configuration if provided for that method. By using this JUnit 5 extension, the following
+ * types can be injected into tests via constructor or method parameters:
+ *
+ * <ul>
+ *     <li>{@link LoggerContext};</li>
+ *     <li>{@link Configuration};</li>
+ *     <li>any subclass of {@link Appender} paired with a {@link Named} annotation to select the appender by name.</li>
+ * </ul>
+ *
+ * Tests using this extension will automatically be tagged as {@code functional} to indicate they perform functional tests that
+ * rely on configuration files and production code.
+ *
+ * @since 2.14.0
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Documented
+@Inherited
+@Tag("functional")
+@ExtendWith(LoggerContextResolver.class)
+@ExtendWith(ConfigurationResolver.class)
+@ExtendWith(AppenderResolver.class)
+public @interface LoggerContextSource {
+    /**
+     * Specifies the name of the configuration file to use for the annotated test.
+     */
+    String value();
+
+    /**
+     * Specifies when to {@linkplain LoggerContext#reconfigure() reconfigure} the logging system.
+     */
+    ReconfigurationPolicy reconfigure() default ReconfigurationPolicy.NEVER;
+
+    /**
+     * Specifies the shutdown timeout limit. Defaults to 0 to mean no limit.
+     */
+    long timeout() default 0L;
+
+    /**
+     * Specifies the time unit {@link #timeout()} is measured in.
+     */
+    TimeUnit unit() default TimeUnit.SECONDS;
+}
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/Named.java
similarity index 66%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java
copy to log4j-core/src/test/java/org/apache/logging/log4j/core/junit/Named.java
index ef36d97..c8477ae 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/StatusLoggerLevel.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/Named.java
@@ -15,30 +15,27 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.junit;
-
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.jupiter.api.parallel.ResourceLock;
+package org.apache.logging.log4j.core.junit;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 /**
- * JUnit 5 test extension that sets a specific StatusLogger logging level for each test.
+ * Specifies the name of an {@link org.apache.logging.log4j.core.Appender} to inject into JUnit 5 tests from the specified
+ * configuration.
  *
+ * @see LoggerContextSource
  * @since 2.14.0
  */
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
+@Target(ElementType.PARAMETER)
 @Documented
-@Inherited
-@ExtendWith(StatusLoggerLevelExtension.class)
-@ResourceLock("log4j2.StatusLogger")
-public @interface StatusLoggerLevel {
-    /** Name of {@link org.apache.logging.log4j.Level} to use for status logger. */
-    String value();
+public @interface Named {
+    /**
+     * Specifies the name of the configuration item to inject. If blank, uses the name of the annotated parameter.
+     */
+    String value() default "";
 }
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ReconfigurationPolicy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ReconfigurationPolicy.java
new file mode 100644
index 0000000..14c5976
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/ReconfigurationPolicy.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.junit;
+
+import org.apache.logging.log4j.core.LoggerContext;
+
+/**
+ * Indicates when to {@linkplain LoggerContext#reconfigure() reconfigure} the logging system during unit tests.
+ *
+ * @see LoggerContextSource
+ * @since 2.14.0
+ */
+public enum ReconfigurationPolicy {
+    /** Performs no reconfiguration of the logging system for the entire run of tests in a test class. This is the default. */
+    NEVER,
+    /** Performs a reconfiguration before executing each test. */
+    BEFORE_EACH,
+    /** Performs a reconfiguration after executing each test. */
+    AFTER_EACH
+}
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/Dummy.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/package-info.java
similarity index 80%
rename from log4j-api-java9/src/main/java/org/apache/logging/log4j/Dummy.java
rename to log4j-core/src/test/java/org/apache/logging/log4j/core/junit/package-info.java
index 24012e6..cda2595 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/Dummy.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/junit/package-info.java
@@ -14,11 +14,9 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j;
 
 /**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * JUnit helper classes and TestRules.
+ * @see org.junit.rules.TestRule
  */
-public class Dummy {
-}
+package org.apache.logging.log4j.core.junit;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithGelfLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithGelfLayoutTest.java
index 9bef502..cbf2f72 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithGelfLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/ConcurrentLoggingWithGelfLayoutTest.java
@@ -18,7 +18,7 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout2Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout2Test.java
index f9f44f7..df9f7f5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout2Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout2Test.java
@@ -23,8 +23,8 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.lookup.JavaLookup;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout3Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout3Test.java
index e7f1b1d..642de54 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout3Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayout3Test.java
@@ -21,9 +21,9 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.message.StringMapMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Tag;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutPatternSelectorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutPatternSelectorTest.java
index f3f5712..bb01925 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutPatternSelectorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutPatternSelectorTest.java
@@ -21,9 +21,9 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Tag;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutTest.java
index 0f02ef0..55f59d9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/GelfLayoutTest.java
@@ -26,7 +26,7 @@
 import org.apache.logging.log4j.core.lookup.JavaLookup;
 import org.apache.logging.log4j.core.util.KeyValuePair;
 import org.apache.logging.log4j.core.util.NetUtils;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.test.appender.EncodingListAppender;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.AfterAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/HtmlLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/HtmlLayoutTest.java
index b9b261e..7442181 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/HtmlLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/HtmlLayoutTest.java
@@ -43,7 +43,7 @@
 import org.apache.logging.log4j.core.time.Instant;
 import org.apache.logging.log4j.core.time.MutableInstant;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_1482_Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_1482_Test.java
index 9ef0487..b75634b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_1482_Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_1482_Test.java
@@ -26,10 +26,10 @@
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.junit.CleanFolders;
+import org.apache.logging.log4j.test.junit.CleanFolders;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_2195_Test.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_2195_Test.java
index ea2433e..ebc8739 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_2195_Test.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Log4j2_2195_Test.java
@@ -23,8 +23,8 @@
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.layout.AbstractStringLayout.Serializer;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutLookupDateTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutLookupDateTest.java
index d814d1d..31548dd 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutLookupDateTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutLookupDateTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core.layout;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutMainMapLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutMainMapLookupTest.java
index 69b8aa3..9d7bc4b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutMainMapLookupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutMainMapLookupTest.java
@@ -21,11 +21,10 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.lookup.MainMapLookup;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.ReconfigurationPolicy;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.core.junit.ReconfigurationPolicy;
 import org.apache.logging.log4j.test.appender.ListAppender;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import java.util.List;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutNoLookupDateTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutNoLookupDateTest.java
index 78ae6dc..c66d66b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutNoLookupDateTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutNoLookupDateTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core.layout;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutRepeatTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutRepeatTest.java
index 5b233e8..9bf775d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutRepeatTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutRepeatTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.core.layout;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
index 89caca2..ef055a8 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/PatternLayoutTest.java
@@ -31,7 +31,7 @@
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
 import org.apache.logging.log4j.core.lookup.MainMapLookup;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
index c1d9156..54c5a5f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/Rfc5424LayoutTest.java
@@ -31,7 +31,7 @@
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.net.Facility;
 import org.apache.logging.log4j.core.util.KeyValuePair;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.message.StructuredDataCollectionMessage;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.status.StatusLogger;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java
index fd710b8..dd120ef 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java
@@ -28,7 +28,7 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.net.Facility;
-import org.apache.logging.log4j.junit.UsingAnyThreadContext;
+import org.apache.logging.log4j.test.junit.UsingAnyThreadContext;
 import org.apache.logging.log4j.message.StructuredDataMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.AfterAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ContextMapLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ContextMapLookupTest.java
index f35c8b1..59c911e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ContextMapLookupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/ContextMapLookupTest.java
@@ -21,12 +21,10 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
 import static org.junit.Assert.*;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
index 9e55563..5fa75cf 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
@@ -22,7 +22,7 @@
 import java.util.Map;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.rules.ExternalResource;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
index c2e34e3..3a8b432 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
@@ -21,7 +21,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.logging.log4j.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
 import org.junit.Rule;
 import org.junit.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
index 9b74ad8..063dbd5 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/MarkerLookupConfigTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/message/MutableLogEventWithReusableParamMsgTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/message/MutableLogEventWithReusableParamMsgTest.java
new file mode 100644
index 0000000..a9fa4b7
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/message/MutableLogEventWithReusableParamMsgTest.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.log4j.core.message;
+
+import org.apache.logging.log4j.core.impl.MutableLogEvent;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.ReusableParameterizedMessage;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsSame.sameInstance;
+
+/**
+ * LOG4J2-1409
+ */
+// test must be in log4j-core but in org.apache.logging.log4j.message package because it calls package-private methods
+public class MutableLogEventWithReusableParamMsgTest {
+    @Test
+    public void testInteractionWithReusableParameterizedMessage() {
+        final MutableLogEvent evt = new MutableLogEvent();
+        final MutableMessage msg = new MutableMessage();
+        msg.set("Hello {} {} {}", 1, 2, 3);
+        evt.setMessage(msg);
+        evt.clear();
+
+        msg.set("Hello {}", new Object[]{1});
+        evt.setMessage(msg);
+        evt.clear();
+
+        msg.set("Hello {}", 1);
+        evt.setMessage(msg);
+        evt.clear();
+
+        // Uncomment out this log event and the params gets reset correctly (No exception occurs)
+        //        msg.set("Hello {}", 1);
+        //        evt.setMessage(msg);
+        //        evt.clear();
+
+        // Exception at this log event - as the params is set to 1!
+        msg.set("Hello {} {} {}", 1, 2, 3);
+        evt.setMessage(msg);
+        evt.clear();
+
+        Message mementoMessage = evt.memento();
+        Message mementoMessageSecondInvocation = evt.memento();
+        // MutableLogEvent.memento should be cached
+        assertThat(mementoMessage, sameInstance(mementoMessageSecondInvocation));
+    }
+
+    private static class MutableMessage extends ReusableParameterizedMessage {
+        private static final long serialVersionUID = 1153384568858161030L;
+
+        public ReusableParameterizedMessage set(final String messagePattern, final Object p0) {
+            return super.set(messagePattern, p0);
+        }
+        public ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1,
+                final Object p2) {
+            return super.set(messagePattern, p0, p1, p2);
+        }
+    }
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketMessageLossTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketMessageLossTest.java
index 27b4754..2d92364 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketMessageLossTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketMessageLossTest.java
@@ -30,7 +30,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketTest.java
index a50334a..21a20b9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/SocketTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/CallerInformationTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/CallerInformationTest.java
index a4e4b32..5097d3d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/CallerInformationTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/CallerInformationTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/DisableAnsiTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/DisableAnsiTest.java
index 683f9fa..ce5033c 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/DisableAnsiTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/DisableAnsiTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowableTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowableTest.java
index bcb2919..4aba699 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowableTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ExtendedThrowableTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/LiteralPatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/LiteralPatternConverterTest.java
index ff32807..4634bb9 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/LiteralPatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/LiteralPatternConverterTest.java
@@ -1,43 +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.log4j.core.pattern;

-

-import org.junit.jupiter.api.Test;

-

-import static org.junit.jupiter.api.Assertions.*;

-

-/**

- * Tests the LiteralPatternConverter.

- */

-public class LiteralPatternConverterTest {

-

-    @Test

-    public void testConvertBackslashes() {

-        final String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x";

-        final LiteralPatternConverter converter = new LiteralPatternConverter(null, literal, true);

-        assertEquals("ABC\tDEF\nGHI\rJKL\'MNO\f \b \\DROPPED:x", converter.getLiteral());

-    }

-

-    @Test

-    public void testDontConvertBackslashes() {

-        final String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x";

-        final LiteralPatternConverter converter = new LiteralPatternConverter(null, literal, false);

-        assertEquals(literal, converter.getLiteral());

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.pattern;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * Tests the LiteralPatternConverter.
+ */
+public class LiteralPatternConverterTest {
+
+    @Test
+    public void testConvertBackslashes() {
+        final String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x";
+        final LiteralPatternConverter converter = new LiteralPatternConverter(null, literal, true);
+        assertEquals("ABC\tDEF\nGHI\rJKL\'MNO\f \b \\DROPPED:x", converter.getLiteral());
+    }
+
+    @Test
+    public void testDontConvertBackslashes() {
+        final String literal = "ABC\\tDEF\\nGHI\\rJKL\\'MNO\\f \\b \\\\DROPPED:\\x";
+        final LiteralPatternConverter converter = new LiteralPatternConverter(null, literal, false);
+        assertEquals(literal, converter.getLiteral());
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.java
index 2a94e47..fd87a7f 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MdcPatternConverterTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
index 56bdd48..c9b922e 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
index b0ec9c8..82488af 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NdcPatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NdcPatternConverterTest.java
index 7ed39b7..1218bb0 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NdcPatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NdcPatternConverterTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.UsingThreadContextStack;
+import org.apache.logging.log4j.test.junit.UsingThreadContextStack;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NoConsoleNoAnsiTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NoConsoleNoAnsiTest.java
index 0ed1fb5..60c2b90 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NoConsoleNoAnsiTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/NoConsoleNoAnsiTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RegexReplacementTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RegexReplacementTest.java
index 541ae19..152f984 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RegexReplacementTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RegexReplacementTest.java
@@ -18,9 +18,9 @@
 
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
-import org.apache.logging.log4j.junit.UsingThreadContextMap;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
+import org.apache.logging.log4j.test.junit.UsingThreadContextMap;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowableTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowableTest.java
index 04ec850..637d75b 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowableTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/RootThrowableTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterTest.java
index d25df96..2c2c374 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterZeroPaddedTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterZeroPaddedTest.java
index a7dc8b0..2da2996 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterZeroPaddedTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/SequenceNumberPatternConverterZeroPaddedTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
index f82be20..bf65c23 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
index 8e6847d..882b458 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/ThrowableTest.java
@@ -20,8 +20,8 @@
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java
index 1707bbd..5cd9080 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java
@@ -37,9 +37,9 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.TestLogger;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
+import org.apache.logging.log4j.test.TestLogger;
 import org.apache.logging.log4j.util.MessageSupplier;
 import org.apache.logging.log4j.util.Supplier;
 import org.junit.jupiter.api.BeforeAll;
@@ -53,7 +53,7 @@
     
     @BeforeAll
     public static void beforeClass() {
-        System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.TestLoggerContextFactory");
+        System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.test.TestLoggerContextFactory");
     }
 
     @Test
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java
index 127b889..e9c604d 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java
@@ -37,10 +37,10 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Marker;
-import org.apache.logging.log4j.TestLogger;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.ExtendedLogger;
+import org.apache.logging.log4j.test.TestLogger;
 import org.apache.logging.log4j.util.MessageSupplier;
 import org.apache.logging.log4j.util.Supplier;
 import org.junit.jupiter.api.BeforeAll;
@@ -54,7 +54,7 @@
     
     @BeforeAll
     public static void beforeClass() {
-        System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.TestLoggerContextFactory");
+        System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.test.TestLoggerContextFactory");
     }
 
     @Test
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
index a1cf6ab..c7cddc6 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/NetUtilsTest.java
@@ -1,60 +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.log4j.core.util;

-

-import org.junit.jupiter.api.Test;

-import org.junit.jupiter.api.condition.EnabledOnOs;

-import org.junit.jupiter.api.condition.OS;

-

-import java.net.URI;

-

-import static org.junit.jupiter.api.Assertions.assertEquals;

-import static org.junit.jupiter.api.Assertions.assertNotNull;

-

-public class NetUtilsTest {

-

-    @Test

-    public void testToUriWithoutBackslashes() {

-        final String config = "file:///path/to/something/on/unix";

-        final URI uri = NetUtils.toURI(config);

-

-        assertNotNull(uri, "The URI should not be null.");

-        assertEquals("file:///path/to/something/on/unix", uri.toString(), "The URI is not correct.");

-    }

-

-    @Test

-    @EnabledOnOs(OS.WINDOWS)

-    public void testToUriWindowsWithBackslashes() {

-        final String config = "file:///D:\\path\\to\\something/on/windows";

-        final URI uri = NetUtils.toURI(config);

-

-        assertNotNull(uri, "The URI should not be null.");

-        assertEquals("file:///D:/path/to/something/on/windows", uri.toString(), "The URI is not correct.");

-    }

-

-    @Test

-    @EnabledOnOs(OS.WINDOWS)

-    public void testToUriWindowsAbsolutePath() {

-        final String config = "D:\\path\\to\\something\\on\\windows";

-        final URI uri = NetUtils.toURI(config);

-

-        assertNotNull(uri, "The URI should not be null.");

-        assertEquals("file:/D:/path/to/something/on/windows", uri.toString(), "The URI is not correct.");

-    }

-

-}

+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.core.util;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import java.net.URI;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class NetUtilsTest {
+
+    @Test
+    public void testToUriWithoutBackslashes() {
+        final String config = "file:///path/to/something/on/unix";
+        final URI uri = NetUtils.toURI(config);
+
+        assertNotNull(uri, "The URI should not be null.");
+        assertEquals("file:///path/to/something/on/unix", uri.toString(), "The URI is not correct.");
+    }
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void testToUriWindowsWithBackslashes() {
+        final String config = "file:///D:\\path\\to\\something/on/windows";
+        final URI uri = NetUtils.toURI(config);
+
+        assertNotNull(uri, "The URI should not be null.");
+        assertEquals("file:///D:/path/to/something/on/windows", uri.toString(), "The URI is not correct.");
+    }
+
+    @Test
+    @EnabledOnOs(OS.WINDOWS)
+    public void testToUriWindowsAbsolutePath() {
+        final String config = "D:\\path\\to\\something\\on\\windows";
+        final URI uri = NetUtils.toURI(config);
+
+        assertNotNull(uri, "The URI should not be null.");
+        assertEquals("file:/D:/path/to/something/on/windows", uri.toString(), "The URI is not correct.");
+    }
+
+}
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/ShutdownCallbackRegistryTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/ShutdownCallbackRegistryTest.java
index 48e4a9e..1c39a36 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/util/ShutdownCallbackRegistryTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/util/ShutdownCallbackRegistryTest.java
@@ -24,7 +24,7 @@
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.impl.Log4jContextFactory;
 import org.apache.logging.log4j.core.selector.ContextSelector;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
index 73a994a..5707e21 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java
@@ -30,6 +30,8 @@
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
+import org.apache.logging.log4j.test.junit.CleanFiles;
+import org.apache.logging.log4j.test.junit.CleanFolders;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
index 1f9ec2d..939e66a 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/test/appender/ListAppender.java
@@ -25,6 +25,7 @@
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.impl.MutableLogEvent;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.plugins.PluginElement;
@@ -46,7 +47,7 @@
  *
  * This appender will use {@link Layout#toByteArray(LogEvent)}.
  *
- * @see org.apache.logging.log4j.junit.LoggerContextRule#getListAppender(String) ILC.getListAppender
+ * @see LoggerContextRule#getListAppender(String) ILC.getListAppender
  */
 @Plugin(name = "List", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
 public class ListAppender extends AbstractAppender {
@@ -279,7 +280,7 @@
      * @param name
      *            the name of the ListAppender
      * @return the named ListAppender or {@code null} if it does not exist
-     * @see org.apache.logging.log4j.junit.LoggerContextRule#getListAppender(String)
+     * @see LoggerContextRule#getListAppender(String)
      */
     public static ListAppender getListAppender(final String name) {
         return ((ListAppender) (LoggerContext.getContext(false)).getConfiguration().getAppender(name));
diff --git a/log4j-csv/pom.xml b/log4j-csv/pom.xml
index 25bb2a8..db61709 100644
--- a/log4j-csv/pom.xml
+++ b/log4j-csv/pom.xml
@@ -48,6 +48,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/appender/CsvJsonParameterLayoutFileAppenderTest.java b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/appender/CsvJsonParameterLayoutFileAppenderTest.java
index 8b9e769..43487e6 100644
--- a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/appender/CsvJsonParameterLayoutFileAppenderTest.java
+++ b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/appender/CsvJsonParameterLayoutFileAppenderTest.java
@@ -23,10 +23,10 @@
 import java.util.List;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvLogEventLayoutTest.java b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvLogEventLayoutTest.java
index 2776b7b..a4e06ad 100644
--- a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvLogEventLayoutTest.java
+++ b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvLogEventLayoutTest.java
@@ -24,15 +24,13 @@
 
 import org.apache.commons.csv.CSVFormat;
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.BasicConfigurationFactory;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
-import org.apache.logging.log4j.csv.layout.AbstractCsvLayout;
-import org.apache.logging.log4j.csv.layout.CsvLogEventLayout;
-import org.apache.logging.log4j.junit.ThreadContextRule;
+import org.apache.logging.log4j.test.junit.ThreadContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.AfterClass;
 import org.junit.Assert;
diff --git a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutAllAsyncTest.java b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutAllAsyncTest.java
index 4b3d8ae..d8ffdad 100644
--- a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutAllAsyncTest.java
+++ b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutAllAsyncTest.java
@@ -18,13 +18,11 @@
 
 import org.apache.commons.csv.CSVFormat;
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
-import org.apache.logging.log4j.csv.layout.AbstractCsvLayout;
-import org.apache.logging.log4j.csv.layout.CsvParameterLayout;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
diff --git a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutTest.java b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutTest.java
index 568a833..cb600a5 100644
--- a/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutTest.java
+++ b/log4j-csv/src/test/java/org/apache/logging/log4j/csv/layout/CsvParameterLayoutTest.java
@@ -29,13 +29,11 @@
 import org.apache.commons.csv.CSVFormat;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.csv.layout.AbstractCsvLayout;
-import org.apache.logging.log4j.csv.layout.CsvParameterLayout;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.apache.logging.log4j.junit.ThreadContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
+import org.apache.logging.log4j.test.junit.ThreadContextRule;
 import org.apache.logging.log4j.message.ObjectArrayMessage;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Assert;
diff --git a/log4j-docker/pom.xml b/log4j-docker/pom.xml
index fc71cfe..b198475 100644
--- a/log4j-docker/pom.xml
+++ b/log4j-docker/pom.xml
@@ -66,25 +66,6 @@
   </dependencies>
   <build>
     <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[8, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
       <!-- Include the standard NOTICE and LICENSE -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
diff --git a/log4j-flume-ng/pom.xml b/log4j-flume-ng/pom.xml
index 655c23b..184200b 100644
--- a/log4j-flume-ng/pom.xml
+++ b/log4j-flume-ng/pom.xml
@@ -77,6 +77,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.flume</groupId>
       <artifactId>flume-ng-sdk</artifactId>
     </dependency>
diff --git a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
index d73fd02..05044ce 100644
--- a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
+++ b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/AbstractStreamTest.java
@@ -20,7 +20,7 @@
 import java.util.List;

 

 import org.apache.logging.log4j.Level;

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.spi.ExtendedLogger;

 import org.junit.Before;

 import org.junit.ClassRule;

diff --git a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
index d81e173..8602d0e 100644
--- a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
+++ b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderCallerInfoTesting.java
@@ -18,7 +18,7 @@
 

 import org.apache.logging.log4j.Level;

 import org.apache.logging.log4j.core.Logger;

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.Before;

 import org.junit.ClassRule;

diff --git a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
index d8b72fd..64e1937 100644
--- a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
+++ b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/IoBuilderTest.java
@@ -25,7 +25,7 @@
 import java.io.PrintStream;

 import java.util.List;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.ClassRule;

 import org.junit.Test;

diff --git a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
index 712ec62..4495b4d 100644
--- a/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
+++ b/log4j-iostreams/src/test/java/org/apache/logging/log4j/io/LoggerPrintWriterJdbcH2Test.java
@@ -22,7 +22,7 @@
 import java.sql.SQLException;

 

 import org.apache.logging.log4j.Level;

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.apache.logging.log4j.util.Strings;

 import org.h2.jdbcx.JdbcDataSource;

diff --git a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
index 31fe14d..9692990 100644
--- a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
+++ b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/CallerInformationTest.java
@@ -22,7 +22,7 @@
 

 import org.apache.commons.logging.Log;

 import org.apache.commons.logging.LogFactory;

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.ClassRule;

 import org.junit.Test;

diff --git a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java
index 6cd8dd6..9b628e1 100644
--- a/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java
+++ b/log4j-jcl/src/test/java/org/apache/logging/log4j/jcl/LoggerTest.java
@@ -20,7 +20,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.ClassRule;
diff --git a/log4j-jdbc-dbcp2/pom.xml b/log4j-jdbc-dbcp2/pom.xml
index 6bd9884..462f407 100644
--- a/log4j-jdbc-dbcp2/pom.xml
+++ b/log4j-jdbc-dbcp2/pom.xml
@@ -54,6 +54,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/dbcp2/appender/PoolableConnectionFactoryTest.java b/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/dbcp2/appender/PoolableConnectionFactoryTest.java
index 1bb333d..942b76a 100644
--- a/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/dbcp2/appender/PoolableConnectionFactoryTest.java
+++ b/log4j-jdbc-dbcp2/src/test/java/org/apache/logging/log4j/dbcp2/appender/PoolableConnectionFactoryTest.java
@@ -18,7 +18,7 @@
 package org.apache.logging.log4j.dbcp2.appender;
 
 import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-jdbc/pom.xml b/log4j-jdbc/pom.xml
index b2b08ff..56a58f7 100644
--- a/log4j-jdbc/pom.xml
+++ b/log4j-jdbc/pom.xml
@@ -44,6 +44,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderDataSourceTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderDataSourceTest.java
index 4773a3d..f3e2035 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderDataSourceTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderDataSourceTest.java
@@ -27,8 +27,8 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.util.Throwables;
-import org.apache.logging.log4j.junit.JndiRule;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.h2.util.IOUtils;
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderFactoryMethodTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderFactoryMethodTest.java
index c176419..427fead 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderFactoryMethodTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/AbstractJdbcAppenderFactoryMethodTest.java
@@ -31,7 +31,7 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.util.Strings;
 import org.h2.util.IOUtils;
 import org.junit.Rule;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/DataSourceConnectionSourceTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/DataSourceConnectionSourceTest.java
index 94fc808..d55d115 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/DataSourceConnectionSourceTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/DataSourceConnectionSourceTest.java
@@ -28,9 +28,8 @@
 
 import javax.sql.DataSource;
 
-import org.apache.logging.log4j.jdbc.appender.DataSourceConnectionSource;
-import org.apache.logging.log4j.junit.JndiRule;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/FactoryMethodConnectionSourceTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/FactoryMethodConnectionSourceTest.java
index 8371d35..f288c42 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/FactoryMethodConnectionSourceTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/FactoryMethodConnectionSourceTest.java
@@ -20,8 +20,7 @@
 import java.sql.SQLException;
 import javax.sql.DataSource;
 
-import org.apache.logging.log4j.jdbc.appender.FactoryMethodConnectionSource;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.After;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingLiteralTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingLiteralTest.java
index 91f44ae..d209478 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingLiteralTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingLiteralTest.java
@@ -28,7 +28,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
 import org.h2.util.IOUtils;
 import org.junit.Rule;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingPatternTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingPatternTest.java
index aee9b93..be93d2a 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingPatternTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderColumnMappingPatternTest.java
@@ -28,7 +28,7 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
 import org.h2.util.IOUtils;
 import org.junit.Rule;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderMapMessageDataSourceTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderMapMessageDataSourceTest.java
index 3769bbb..6113e17 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderMapMessageDataSourceTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderMapMessageDataSourceTest.java
@@ -34,8 +34,8 @@
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.util.Throwables;
-import org.apache.logging.log4j.junit.JndiRule;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.MapMessage;
 import org.junit.Assert;
 import org.junit.Rule;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderStringSubstitutionTest.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderStringSubstitutionTest.java
index 3b137cb..a3011db 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderStringSubstitutionTest.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcAppenderStringSubstitutionTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.jdbc.appender;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Rule;
diff --git a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcRule.java b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcRule.java
index cc5866a..2b6f061 100644
--- a/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcRule.java
+++ b/log4j-jdbc/src/test/java/org/apache/logging/log4j/jdbc/appender/JdbcRule.java
@@ -22,7 +22,7 @@
 import java.util.Objects;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 
diff --git a/log4j-jeromq/pom.xml b/log4j-jeromq/pom.xml
index 6cb0186..33d3832 100644
--- a/log4j-jeromq/pom.xml
+++ b/log4j-jeromq/pom.xml
@@ -49,6 +49,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java b/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java
index fa8be86..93f5a1d 100644
--- a/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java
+++ b/log4j-jeromq/src/test/java/org/apache/logging/log4j/jeromq/appender/JeroMqAppenderTest.java
@@ -24,12 +24,10 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.util.ExecutorServices;
-import org.apache.logging.log4j.jeromq.appender.JeroMqAppender;
-import org.apache.logging.log4j.jeromq.appender.JeroMqManager;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Assert;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-jms/pom.xml b/log4j-jms/pom.xml
index b057e1f..33fa977 100644
--- a/log4j-jms/pom.xml
+++ b/log4j-jms/pom.xml
@@ -51,6 +51,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-jms/src/test/java/org/apache/logging/log4j/jms/appender/JmsAppenderTest.java b/log4j-jms/src/test/java/org/apache/logging/log4j/jms/appender/JmsAppenderTest.java
index dce981b..33ff521 100644
--- a/log4j-jms/src/test/java/org/apache/logging/log4j/jms/appender/JmsAppenderTest.java
+++ b/log4j-jms/src/test/java/org/apache/logging/log4j/jms/appender/JmsAppenderTest.java
@@ -40,11 +40,11 @@
 import javax.jms.TextMessage;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.JndiRule;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.JndiRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.message.StringMapMessage;
diff --git a/log4j-jmx-gui/pom.xml b/log4j-jmx-gui/pom.xml
index 8e6dcb6..06e651b 100644
--- a/log4j-jmx-gui/pom.xml
+++ b/log4j-jmx-gui/pom.xml
@@ -175,67 +175,5 @@
       </plugin>
     </plugins>
   </reporting>
-  <profiles>
-    <profile>
-      <id>default-jmx-profile</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-        <file>
-          <exists>${java.home}/../lib/jconsole.jar</exists>
-        </file>
-      </activation>
-      <properties>
-        <toolsjar>${java.home}/../lib/jconsole.jar</toolsjar>
-      </properties>
-      <dependencies>
-        <dependency>
-          <groupId>com.sun</groupId>
-          <artifactId>jconsole</artifactId>
-          <version>1.7.0</version>
-          <scope>system</scope>
-          <systemPath>${java.home}/../lib/jconsole.jar</systemPath>
-          <optional>true</optional>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>mac-profile</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-        <file>
-          <exists>${java.home}/../Classes/jconsole.jar</exists>
-        </file>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>com.sun</groupId>
-          <artifactId>jconsole</artifactId>
-          <version>1.7.0</version>
-          <scope>system</scope>
-          <systemPath>${java.home}/../Classes/jconsole.jar</systemPath>
-          <optional>true</optional>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>jenkins-profile</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-        <property>
-          <name>jenkins</name>
-        </property>
-      </activation>
-      <dependencies>
-        <dependency>
-          <groupId>com.sun</groupId>
-          <artifactId>jconsole</artifactId>
-          <version>1.7.0</version>
-          <scope>system</scope>
-          <systemPath>${jenkins.java.home}/lib/jconsole.jar</systemPath>
-          <optional>true</optional>
-        </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
 </project>
 
diff --git a/log4j-jpa/pom.xml b/log4j-jpa/pom.xml
index f53ddf7..d8c5885 100644
--- a/log4j-jpa/pom.xml
+++ b/log4j-jpa/pom.xml
@@ -58,6 +58,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/AbstractJpaAppenderTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/AbstractJpaAppenderTest.java
index 1d451e0..10be794 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/AbstractJpaAppenderTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/AbstractJpaAppenderTest.java
@@ -25,12 +25,11 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
-import org.apache.logging.log4j.jpa.appender.JpaAppender;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.PropertiesUtil;
 import org.junit.Test;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaH2AppenderTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaH2AppenderTest.java
index f6bf26b..0efb4ba 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaH2AppenderTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaH2AppenderTest.java
@@ -21,7 +21,7 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaHsqldbAppenderTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaHsqldbAppenderTest.java
index 24b5862..5d269a5 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaHsqldbAppenderTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/appender/JpaHsqldbAppenderTest.java
@@ -21,9 +21,8 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.jpa.appender.JpaAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataAttributeConverterTest.java
index 5c8a12b..c727d6a 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataAttributeConverterTest.java
@@ -16,8 +16,7 @@
  */
 package org.apache.logging.log4j.jpa.converter;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextDataAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
 import org.apache.logging.log4j.util.StringMap;
 import org.junit.Before;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataJsonAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataJsonAttributeConverterTest.java
index fc0a588..7256f04 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataJsonAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextDataJsonAttributeConverterTest.java
@@ -16,8 +16,7 @@
  */
 package org.apache.logging.log4j.jpa.converter;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextDataJsonAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.util.ReadOnlyStringMap;
 import org.apache.logging.log4j.util.SortedArrayStringMap;
 import org.apache.logging.log4j.util.StringMap;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapAttributeConverterTest.java
index 2f2d6ea..ffbf7ee 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapAttributeConverterTest.java
@@ -19,8 +19,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextMapAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapJsonAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapJsonAttributeConverterTest.java
index 8b9571e..04696d2 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapJsonAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextMapJsonAttributeConverterTest.java
@@ -19,8 +19,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextMapJsonAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackAttributeConverterTest.java
index 452eaf2..64dad70 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackAttributeConverterTest.java
@@ -19,8 +19,7 @@
 import java.util.Arrays;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextStackAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.spi.MutableThreadContextStack;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackJsonAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackJsonAttributeConverterTest.java
index de8700e..52f9018 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackJsonAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ContextStackJsonAttributeConverterTest.java
@@ -23,9 +23,8 @@
 import java.util.Arrays;
 
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ContextStackJsonAttributeConverter;
-import org.apache.logging.log4j.junit.ThreadContextStackRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.test.junit.ThreadContextStackRule;
 import org.apache.logging.log4j.spi.MutableThreadContextStack;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/InstantAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/InstantAttributeConverterTest.java
index e7a495e..9ad6e61 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/InstantAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/InstantAttributeConverterTest.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.time.Instant;
 import org.apache.logging.log4j.core.time.MutableInstant;
 import org.junit.Before;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MarkerAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MarkerAttributeConverterTest.java
index cacf59c..d38aaf9 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MarkerAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MarkerAttributeConverterTest.java
@@ -18,8 +18,7 @@
 
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.MarkerAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MessageAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MessageAttributeConverterTest.java
index 9b16dbd..e6e444f 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MessageAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/MessageAttributeConverterTest.java
@@ -16,8 +16,7 @@
  */
 package org.apache.logging.log4j.jpa.converter;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.MessageAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.junit.Before;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/StackTraceElementAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/StackTraceElementAttributeConverterTest.java
index d0e6d09..02b2007 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/StackTraceElementAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/StackTraceElementAttributeConverterTest.java
@@ -16,8 +16,7 @@
  */
 package org.apache.logging.log4j.jpa.converter;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.StackTraceElementAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ThrowableAttributeConverterTest.java b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ThrowableAttributeConverterTest.java
index f06eee9..3c02d3f 100644
--- a/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ThrowableAttributeConverterTest.java
+++ b/log4j-jpa/src/test/java/org/apache/logging/log4j/jpa/converter/ThrowableAttributeConverterTest.java
@@ -18,8 +18,7 @@
 
 import java.sql.SQLException;
 
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.jpa.converter.ThrowableAttributeConverter;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-jpl/pom.xml b/log4j-jpl/pom.xml
index 36e41bf..5e67974 100644
--- a/log4j-jpl/pom.xml
+++ b/log4j-jpl/pom.xml
@@ -52,6 +52,11 @@
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest-all</artifactId>
       <scope>test</scope>
@@ -95,25 +100,6 @@
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[11, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <executions>
           <execution>
diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
index 3ca72e6..7eb3be6 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
+++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/AsyncLoggerThreadsTest.java
@@ -17,19 +17,14 @@
 package org.apache.logging.log4j.jul;
 
 import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.categories.AsyncLoggers;
-import org.apache.logging.log4j.core.CoreLoggerContexts;
+import org.apache.logging.log4j.core.categories.AsyncLoggers;
 import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
-import org.apache.logging.log4j.core.config.ConfigurationFactory;
 import org.apache.logging.log4j.core.util.Constants;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
 import java.util.List;
 import java.util.stream.Collectors;
 
diff --git a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
index dedaa4e..4a1844c 100644
--- a/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
+++ b/log4j-jul/src/test/java/org/apache/logging/log4j/jul/CallerInformationTest.java
@@ -19,7 +19,7 @@
 import java.util.List;

 import java.util.logging.Logger;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.AfterClass;

 import org.junit.BeforeClass;

diff --git a/log4j-kafka/pom.xml b/log4j-kafka/pom.xml
index ae274e3..6b41781 100644
--- a/log4j-kafka/pom.xml
+++ b/log4j-kafka/pom.xml
@@ -49,6 +49,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderCloseTimeoutTest.java b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderCloseTimeoutTest.java
index 77966fc..e2318ba 100644
--- a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderCloseTimeoutTest.java
+++ b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderCloseTimeoutTest.java
@@ -22,11 +22,9 @@
 
 import org.apache.kafka.clients.producer.MockProducer;
 import org.apache.kafka.clients.producer.Producer;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.apache.logging.log4j.kafka.appender.KafkaManager;
-import org.apache.logging.log4j.kafka.appender.KafkaProducerFactory;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
diff --git a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderTest.java b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderTest.java
index f726fd4..18c9177 100644
--- a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderTest.java
+++ b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaAppenderTest.java
@@ -31,13 +31,11 @@
 import org.apache.kafka.clients.producer.Producer;
 import org.apache.kafka.clients.producer.ProducerRecord;
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.junit.LoggerContextRule;
-import org.apache.logging.log4j.kafka.appender.KafkaManager;
-import org.apache.logging.log4j.kafka.appender.KafkaProducerFactory;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.util.FilteredObjectInputStream;
 import org.junit.Before;
diff --git a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaManagerProducerThreadLeakTest.java b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaManagerProducerThreadLeakTest.java
index 73fcf62..620f3b6 100644
--- a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaManagerProducerThreadLeakTest.java
+++ b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/appender/KafkaManagerProducerThreadLeakTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.logging.log4j.kafka.appender;
 
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
 import org.junit.experimental.categories.Category;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/builder/ConfigurationBuilderTest.java b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/builder/ConfigurationBuilderTest.java
index 0d263fe..ac32df0 100644
--- a/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/builder/ConfigurationBuilderTest.java
+++ b/log4j-kafka/src/test/java/org/apache/logging/log4j/kafka/builder/ConfigurationBuilderTest.java
@@ -69,7 +69,7 @@
     }
 
     private final static String expectedXml =
-            "<?xml version=\"1.0\" ?>" + EOL +
+            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
             "<Configuration name=\"config name\" status=\"ERROR\" packages=\"foo,bar\" shutdownTimeout=\"5000\">" + EOL +
                 INDENT + "<Properties>" + EOL +
                 INDENT + INDENT + "<Property name=\"MyKey\">MyValue</Property>" + EOL +
diff --git a/log4j-kubernetes/pom.xml b/log4j-kubernetes/pom.xml
index f02897e..6e6c2b6 100644
--- a/log4j-kubernetes/pom.xml
+++ b/log4j-kubernetes/pom.xml
@@ -31,8 +31,6 @@
     <log4jParentDir>${basedir}/..</log4jParentDir>
     <docLabel>Log4j Kubernetes Library Documentation</docLabel>
     <projectDir>/kubernetes</projectDir>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
     <module.name>org.apache.logging.log4j.kubernetes</module.name>
     <maven.doap.skip>true</maven.doap.skip>
   </properties>
@@ -58,28 +56,14 @@
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[8, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
       <!-- Include the standard NOTICE and LICENSE -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
diff --git a/log4j-layout-jackson-json/pom.xml b/log4j-layout-jackson-json/pom.xml
index d3dbfa1..29bbbe4 100644
--- a/log4j-layout-jackson-json/pom.xml
+++ b/log4j-layout-jackson-json/pom.xml
@@ -61,6 +61,11 @@
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>com.lmax</groupId>
       <artifactId>disruptor</artifactId>
       <scope>test</scope>
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429MyNamesTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429MyNamesTest.java
index acc15c2..4718373 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429MyNamesTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429MyNamesTest.java
@@ -18,7 +18,7 @@
 
 import java.io.IOException;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429Test.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429Test.java
index 93d1d53..c784bd4 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429Test.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/JacksonIssue429Test.java
@@ -18,7 +18,7 @@
 
 import java.io.IOException;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.junit.Assert;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/LevelMixInJsonTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/LevelMixInJsonTest.java
index 7f75148..25e869b 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/LevelMixInJsonTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/LevelMixInJsonTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.json;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.LevelMixInTest;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/MarkerMixInJsonTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/MarkerMixInJsonTest.java
index db9588b..60742fc 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/MarkerMixInJsonTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/MarkerMixInJsonTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.json;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.AbstractMarkerMixInTest;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/StackTraceElementJsonMixInTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/StackTraceElementJsonMixInTest.java
index fc0b459..69a4cd3 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/StackTraceElementJsonMixInTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/StackTraceElementJsonMixInTest.java
@@ -18,7 +18,7 @@
 
 import java.io.IOException;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.Log4jStackTraceElementDeserializer;
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/ConcurrentLoggingWithJsonLayoutTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/ConcurrentLoggingWithJsonLayoutTest.java
index bad6b2e..8b24953 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/ConcurrentLoggingWithJsonLayoutTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/ConcurrentLoggingWithJsonLayoutTest.java
@@ -29,7 +29,7 @@
 import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutMillisTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutMillisTest.java
index 2ec062d..0956ee7 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutMillisTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutMillisTest.java
@@ -16,10 +16,10 @@
  */
 package org.apache.logging.log4j.jackson.json.layout;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.Rule;
diff --git a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutTest.java b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutTest.java
index 2b08e13..b3d6324 100644
--- a/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutTest.java
+++ b/log4j-layout-jackson-json/src/test/java/org/apache/logging/log4j/jackson/json/layout/JsonLayoutTest.java
@@ -30,7 +30,7 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.BasicConfigurationFactory;
 import org.apache.logging.log4j.core.Logger;
diff --git a/log4j-layout-jackson-xml/pom.xml b/log4j-layout-jackson-xml/pom.xml
index 0b6641d..65f3cda 100644
--- a/log4j-layout-jackson-xml/pom.xml
+++ b/log4j-layout-jackson-xml/pom.xml
@@ -54,6 +54,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
index 224ef40..026b568 100644
--- a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
+++ b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/ExtendedStackTraceElementXmlMixIn.java
@@ -15,6 +15,9 @@
     @JsonCreator
     public ExtendedStackTraceElementXmlMixIn(
     // @formatter:off
+            @JsonProperty(ATTR_CLASS_LOADER_NAME) final String classLoaderName,
+            @JsonProperty(ATTR_MODULE) final String moduleName,
+            @JsonProperty(ATTR_MODULE_VERSION) final String moduleVersion,
             @JsonProperty(ATTR_CLASS) final String declaringClass,
             @JsonProperty(ATTR_METHOD) final String methodName,
             @JsonProperty(ATTR_FILE) final String fileName,
@@ -24,10 +27,23 @@
             @JsonProperty(ATTR_VERSION) final String version
    // @formatter:on
     ) {
-        super(declaringClass, methodName, fileName, lineNumber, exact, location, version);
+        super(classLoaderName, moduleName, moduleVersion, declaringClass, methodName, fileName, lineNumber, exact,
+                location, version);
     }
 
     @Override
+    @JacksonXmlProperty(localName = ATTR_CLASS_LOADER_NAME, isAttribute = true)
+    public abstract String getClassLoaderName();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_MODULE, isAttribute = true)
+    public abstract String getModuleName();
+
+    @Override
+    @JacksonXmlProperty(localName = ATTR_MODULE_VERSION, isAttribute = true)
+    public abstract String getModuleVersion();
+
+    @Override
     @JacksonXmlProperty(localName = ATTR_CLASS, isAttribute = true)
     public abstract String getClassName();
 
diff --git a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
index 93a3a45..546bdc9 100644
--- a/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
+++ b/log4j-layout-jackson-xml/src/main/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixIn.java
@@ -12,16 +12,31 @@
     @JsonCreator
     protected StackTraceElementXmlMixIn(
     // @formatter:off
+            @JsonProperty(StackTraceElementConstants.ATTR_CLASS_LOADER_NAME) final String classLoaderName,
+            @JsonProperty(StackTraceElementConstants.ATTR_MODULE) final String moduleName,
+            @JsonProperty(StackTraceElementConstants.ATTR_MODULE_VERSION) final String moduleVersion,
             @JsonProperty(StackTraceElementConstants.ATTR_CLASS) final String declaringClass,
             @JsonProperty(StackTraceElementConstants.ATTR_METHOD) final String methodName,
             @JsonProperty(StackTraceElementConstants.ATTR_FILE) final String fileName,
             @JsonProperty(StackTraceElementConstants.ATTR_LINE) final int lineNumber)
     // @formatter:on
     {
-        super(declaringClass, methodName, fileName, lineNumber);
+        super(classLoaderName, moduleName, moduleVersion, declaringClass, methodName, fileName, lineNumber);
     }
 
     @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_CLASS_LOADER_NAME, isAttribute = true)
+    protected abstract String getClassLoaderName();
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_MODULE, isAttribute = true)
+    protected abstract String getModuleName();
+
+    @Override
+    @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_MODULE_VERSION, isAttribute = true)
+    protected abstract String getModuleVersion();
+
+    @Override
     @JacksonXmlProperty(localName = StackTraceElementConstants.ATTR_CLASS, isAttribute = true)
     protected abstract String getClassName();
 
diff --git a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/LevelMixInXmlTest.java b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/LevelMixInXmlTest.java
index 36e8532..ac0f70c 100644
--- a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/LevelMixInXmlTest.java
+++ b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/LevelMixInXmlTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.xml;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.LevelMixInTest;
 import org.junit.Ignore;
 import org.junit.experimental.categories.Category;
diff --git a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/MarkerMixInXmlTest.java b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/MarkerMixInXmlTest.java
index b909453..6ea3ee2 100644
--- a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/MarkerMixInXmlTest.java
+++ b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/MarkerMixInXmlTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.xml;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.AbstractMarkerMixInTest;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixInTest.java b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixInTest.java
index 1d45672..3e876f5 100644
--- a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixInTest.java
+++ b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/StackTraceElementXmlMixInTest.java
@@ -18,7 +18,7 @@
 
 import java.io.IOException;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.Log4jStackTraceElementDeserializer;
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/ConcurrentLoggingWithXmlLayoutTest.java b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/ConcurrentLoggingWithXmlLayoutTest.java
index afbff8a..2dc9a03 100644
--- a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/ConcurrentLoggingWithXmlLayoutTest.java
+++ b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/ConcurrentLoggingWithXmlLayoutTest.java
@@ -30,7 +30,7 @@
 import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayoutTest.java b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayoutTest.java
index 6aae517..0689d71 100644
--- a/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayoutTest.java
+++ b/log4j-layout-jackson-xml/src/test/java/org/apache/logging/log4j/jackson/xml/layout/XmlLayoutTest.java
@@ -30,7 +30,7 @@
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.MarkerManager;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.BasicConfigurationFactory;
 import org.apache.logging.log4j.core.Logger;
@@ -45,7 +45,7 @@
 import org.apache.logging.log4j.jackson.XmlConstants;
 import org.apache.logging.log4j.jackson.xml.AbstractLogEventXmlMixIn;
 import org.apache.logging.log4j.jackson.xml.Log4jXmlObjectMapper;
-import org.apache.logging.log4j.junit.ThreadContextRule;
+import org.apache.logging.log4j.test.junit.ThreadContextRule;
 import org.apache.logging.log4j.message.SimpleMessage;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.test.appender.ListAppender;
diff --git a/log4j-layout-jackson-yaml/pom.xml b/log4j-layout-jackson-yaml/pom.xml
index f583b94..1893c9d 100644
--- a/log4j-layout-jackson-yaml/pom.xml
+++ b/log4j-layout-jackson-yaml/pom.xml
@@ -49,6 +49,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/LevelMixInYamlTest.java b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/LevelMixInYamlTest.java
index 86b9984..7401b70 100644
--- a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/LevelMixInYamlTest.java
+++ b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/LevelMixInYamlTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.yaml;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.LevelMixInTest;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/MarkerMixInYamlTest.java b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/MarkerMixInYamlTest.java
index 98132cd..f5a5661 100644
--- a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/MarkerMixInYamlTest.java
+++ b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/MarkerMixInYamlTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.jackson.yaml;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.AbstractMarkerMixInTest;
 import org.junit.experimental.categories.Category;
 
diff --git a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/StackTraceElementYamlMixInTest.java b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/StackTraceElementYamlMixInTest.java
index 9746655..d557f3d 100644
--- a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/StackTraceElementYamlMixInTest.java
+++ b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/StackTraceElementYamlMixInTest.java
@@ -18,7 +18,7 @@
 
 import java.io.IOException;
 
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.jackson.Log4jStackTraceElementDeserializer;
 import org.junit.Assert;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/ConcurrentLoggingWithYamlLayoutTest.java b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/ConcurrentLoggingWithYamlLayoutTest.java
index a0e821c..17a05e8 100644
--- a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/ConcurrentLoggingWithYamlLayoutTest.java
+++ b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/ConcurrentLoggingWithYamlLayoutTest.java
@@ -29,7 +29,7 @@
 import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.AfterClass;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/YamlLayoutTest.java b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/YamlLayoutTest.java
index 33f187c..6ae28b1 100644
--- a/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/YamlLayoutTest.java
+++ b/log4j-layout-jackson-yaml/src/test/java/org/apache/logging/log4j/jackson/yaml/layout/YamlLayoutTest.java
@@ -22,7 +22,7 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.BasicConfigurationFactory;
 import org.apache.logging.log4j.core.Logger;
diff --git a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ExtendedStackTraceElementMixIn.java b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ExtendedStackTraceElementMixIn.java
index 2642e42..ea1dabe 100644
--- a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ExtendedStackTraceElementMixIn.java
+++ b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/ExtendedStackTraceElementMixIn.java
@@ -23,6 +23,7 @@
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 
@@ -31,6 +32,9 @@
  */
 @JsonPropertyOrder({
     //@formatter:off
+    ExtendedStackTraceElementMixIn.ATTR_CLASS_LOADER_NAME,
+    ExtendedStackTraceElementMixIn.ATTR_MODULE,
+    ExtendedStackTraceElementMixIn.ATTR_MODULE_VERSION,
     ExtendedStackTraceElementMixIn.ATTR_CLASS,
     ExtendedStackTraceElementMixIn.ATTR_METHOD,
     ExtendedStackTraceElementMixIn.ATTR_FILE,
@@ -42,6 +46,9 @@
 })
 public abstract class ExtendedStackTraceElementMixIn implements Serializable {
 
+    protected static final String ATTR_CLASS_LOADER_NAME = StackTraceElementConstants.ATTR_CLASS_LOADER_NAME;
+    protected static final String ATTR_MODULE = StackTraceElementConstants.ATTR_MODULE;
+    protected static final String ATTR_MODULE_VERSION = StackTraceElementConstants.ATTR_MODULE_VERSION;
     protected static final String ATTR_CLASS = StackTraceElementConstants.ATTR_CLASS;
     protected static final String ATTR_METHOD = StackTraceElementConstants.ATTR_METHOD;
     protected static final String ATTR_FILE = StackTraceElementConstants.ATTR_FILE;
@@ -55,6 +62,9 @@
     @JsonCreator
     public ExtendedStackTraceElementMixIn(
     // @formatter:off
+            @JsonProperty(ATTR_CLASS_LOADER_NAME) final String classLoaderName,
+            @JsonProperty(ATTR_MODULE) final String moduleName,
+            @JsonProperty(ATTR_MODULE_VERSION) final String moduleVersion,
             @JsonProperty(ATTR_CLASS) final String declaringClass,
             @JsonProperty(ATTR_METHOD) final String methodName,
             @JsonProperty(ATTR_FILE) final String fileName,
@@ -67,6 +77,15 @@
         // empty
     }
 
+    @JsonProperty(ATTR_CLASS_LOADER_NAME)
+    public abstract String getClassLoaderName();
+
+    @JsonProperty(ATTR_MODULE)
+    public abstract String getModuleName();
+
+    @JsonProperty(ATTR_MODULE_VERSION)
+    public abstract String getModuleVersion();
+
     @JsonProperty(ATTR_CLASS)
     public abstract String getClassName();
 
diff --git a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
index f155a49..004675c 100644
--- a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
+++ b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/Log4jStackTraceElementDeserializer.java
@@ -47,35 +47,61 @@
         JsonToken t = jp.getCurrentToken();
         // Must get an Object
         if (t == JsonToken.START_OBJECT) {
-            String className = null, methodName = null, fileName = null;
+            String classLoaderName = null, moduleName = null, moduleVersion = null, className = null, methodName = null,
+                    fileName = null;
             int lineNumber = -1;
 
             while ((t = jp.nextValue()) != JsonToken.END_OBJECT) {
                 final String propName = jp.getCurrentName();
-                if ("class".equals(propName)) {
-                    className = jp.getText();
-                } else if ("file".equals(propName)) {
-                    fileName = jp.getText();
-                } else if ("line".equals(propName)) {
-                    if (t.isNumeric()) {
-                        lineNumber = jp.getIntValue();
-                    } else {
-                        // An XML number always comes in a string since there is no syntax help as with JSON.
-                        try {
-                            lineNumber = Integer.parseInt(jp.getText().trim());
-                        } catch (final NumberFormatException e) {
-                            throw JsonMappingException.from(jp, "Non-numeric token (" + t + ") for property 'line'", e);
-                        }
+                switch(propName) {
+                    case "class": {
+                        className = jp.getText();
+                        break;
                     }
-                } else if ("method".equals(propName)) {
-                    methodName = jp.getText();
-                } else if ("nativeMethod".equals(propName)) {
-                    // no setter, not passed via constructor: ignore
-                } else {
-                    this.handleUnknownProperty(jp, ctxt, this._valueClass, propName);
+                    case "file": {
+                        fileName = jp.getText();
+                        break;
+                    }
+                    case "line": {
+                        if (t.isNumeric()) {
+                            lineNumber = jp.getIntValue();
+                        } else {
+                            // An XML number always comes in a string since there is no syntax help as with JSON.
+                            try {
+                                lineNumber = Integer.parseInt(jp.getText().trim());
+                            } catch (final NumberFormatException e) {
+                                throw JsonMappingException.from(jp, "Non-numeric token (" + t + ") for property 'line'", e);
+                            }
+                        }
+                        break;
+                    }
+                    case "method": {
+                        methodName = jp.getText();
+                        break;
+                    }
+                    case "nativeMethod": {
+                        // no setter, not passed via constructor: ignore
+                        break;
+                    }
+                    case "classLoaderName": {
+                        classLoaderName = jp.getText();
+                        break;
+                    }
+                    case "moduleName": {
+                        moduleName = jp.getText();
+                        break;
+                    }
+                    case "moduleVersion": {
+                        moduleVersion = jp.getText();
+                        break;
+                    }
+                    default: {
+                        this.handleUnknownProperty(jp, ctxt, this._valueClass, propName);
+                    }
                 }
             }
-            return new StackTraceElement(className, methodName, fileName, lineNumber);
+            return new StackTraceElement(classLoaderName, moduleName, moduleVersion, className, methodName, fileName,
+                    lineNumber);
         }
         throw ctxt.mappingException(this._valueClass, t);
     }
diff --git a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
index 0f0f025..5a4ad56 100644
--- a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
+++ b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementConstants.java
@@ -22,6 +22,9 @@
  */
 public class StackTraceElementConstants {
 
+    public static final String ATTR_CLASS_LOADER_NAME = "classLoaderName";
+    public static final String ATTR_MODULE = "module";
+    public static final String ATTR_MODULE_VERSION = "moduleVersion";
     public static final String ATTR_CLASS = "class";
     public static final String ATTR_FILE = "file";
     public static final String ATTR_LINE = "line";
diff --git a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
index b3bff92..789810c 100644
--- a/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
+++ b/log4j-layout-jackson/src/main/java/org/apache/logging/log4j/jackson/StackTraceElementMixIn.java
@@ -35,6 +35,9 @@
     @JsonCreator
     protected StackTraceElementMixIn(
     // @formatter:off
+            @JsonProperty(StackTraceElementConstants.ATTR_CLASS_LOADER_NAME) final String classLoaderName,
+            @JsonProperty(StackTraceElementConstants.ATTR_MODULE) final String moduleName,
+            @JsonProperty(StackTraceElementConstants.ATTR_MODULE_VERSION) final String moduleVersion,
             @JsonProperty(StackTraceElementConstants.ATTR_CLASS) final String declaringClass,
             @JsonProperty(StackTraceElementConstants.ATTR_METHOD) final String methodName,
             @JsonProperty(StackTraceElementConstants.ATTR_FILE) final String fileName,
@@ -44,6 +47,15 @@
         // empty
     }
 
+    @JsonProperty(StackTraceElementConstants.ATTR_CLASS_LOADER_NAME)
+    protected abstract String getClassLoaderName();
+
+    @JsonProperty(StackTraceElementConstants.ATTR_MODULE)
+    protected abstract String getModuleName();
+
+    @JsonProperty(StackTraceElementConstants.ATTR_MODULE_VERSION)
+    protected abstract String getModuleVersion();
+
     @JsonProperty(StackTraceElementConstants.ATTR_CLASS)
     protected abstract String getClassName();
 
diff --git a/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/LevelMixInTest.java b/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/LevelMixInTest.java
index 0cdcb36..8432f47 100644
--- a/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/LevelMixInTest.java
+++ b/log4j-layout-jackson/src/test/java/org/apache/logging/log4j/jackson/LevelMixInTest.java
@@ -19,7 +19,7 @@
 import java.io.IOException;
 
 import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.categories.Layouts;
+import org.apache.logging.log4j.core.categories.Layouts;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldJsonTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldJsonTest.java
index 41fd023..1694c56 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldJsonTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldJsonTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.layout.template.json;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldPropertiesTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldPropertiesTest.java
index 735a55d..2c55fe7 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldPropertiesTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldPropertiesTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.layout.template.json;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldXmlTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldXmlTest.java
index f9194ee..bb08322 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldXmlTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldXmlTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.layout.template.json;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldYamlTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldYamlTest.java
index feecefb..25a0954 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldYamlTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/JsonTemplateLayoutAdditionalFieldYamlTest.java
@@ -17,8 +17,8 @@
 package org.apache.logging.log4j.layout.template.json;
 
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.jupiter.api.Test;
 
diff --git a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/util/RecyclerFactoriesTest.java b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/util/RecyclerFactoriesTest.java
index 1ecc53e..d2347e5 100644
--- a/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/util/RecyclerFactoriesTest.java
+++ b/log4j-layout-template-json/src/test/java/org/apache/logging/log4j/layout/template/json/util/RecyclerFactoriesTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.plugins.convert.TypeConverter;
 import org.apache.logging.log4j.plugins.convert.TypeConverterRegistry;
-import org.apache.logging.log4j.junit.LoggerContextSource;
-import org.apache.logging.log4j.junit.Named;
+import org.apache.logging.log4j.core.junit.LoggerContextSource;
+import org.apache.logging.log4j.core.junit.Named;
 import org.apache.logging.log4j.layout.template.json.JsonTemplateLayout;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.assertj.core.api.Assertions;
diff --git a/log4j-liquibase/pom.xml b/log4j-liquibase/pom.xml
index b0e48c0..f648761 100644
--- a/log4j-liquibase/pom.xml
+++ b/log4j-liquibase/pom.xml
@@ -72,6 +72,11 @@
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git a/log4j-mongodb3/pom.xml b/log4j-mongodb3/pom.xml
index 43da8f8..2d4e877 100644
--- a/log4j-mongodb3/pom.xml
+++ b/log4j-mongodb3/pom.xml
@@ -62,6 +62,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
diff --git a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3AuthFailureTest.java b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3AuthFailureTest.java
index 540be57..10e2dae 100644
--- a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3AuthFailureTest.java
+++ b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3AuthFailureTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb3.MongoDb3TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3CappedTest.java b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3CappedTest.java
index f03af5f..f6aeafc 100644
--- a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3CappedTest.java
+++ b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3CappedTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb3.MongoDb3TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3MapMessageTest.java b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3MapMessageTest.java
index 9a45ede..a971d89 100644
--- a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3MapMessageTest.java
+++ b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3MapMessageTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.MapMessage;
 import org.apache.logging.log4j.mongodb3.MongoDb3TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
diff --git a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3Test.java b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3Test.java
index dd0bcd2..d173c48 100644
--- a/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3Test.java
+++ b/log4j-mongodb3/src/test/java/org/apache/logging/log4j/mongodb3/MongoDb3Test.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb3.MongoDb3TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-mongodb4/pom.xml b/log4j-mongodb4/pom.xml
index 91a0882..e6d40d2 100644
--- a/log4j-mongodb4/pom.xml
+++ b/log4j-mongodb4/pom.xml
@@ -62,6 +62,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
       <scope>test</scope>
diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4AuthFailureTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4AuthFailureTest.java
index c84d108..26a9b04 100644
--- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4AuthFailureTest.java
+++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4AuthFailureTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb4.MongoDb4TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CappedTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CappedTest.java
index fcd7cd7..b9bb477 100644
--- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CappedTest.java
+++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4CappedTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb4.MongoDb4TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4MapMessageTest.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4MapMessageTest.java
index 70ab9a7..602d40f 100644
--- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4MapMessageTest.java
+++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4MapMessageTest.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.message.MapMessage;
 import org.apache.logging.log4j.mongodb4.MongoDb4TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
diff --git a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Test.java b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Test.java
index e814f1f..fdf42d7 100644
--- a/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Test.java
+++ b/log4j-mongodb4/src/test/java/org/apache/logging/log4j/mongodb4/MongoDb4Test.java
@@ -18,8 +18,8 @@
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.categories.Appenders;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.categories.Appenders;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.mongodb4.MongoDb4TestRule.LoggingTarget;
 import org.apache.logging.log4j.test.AvailablePortSystemPropertyTestRule;
 import org.apache.logging.log4j.test.RuleChainFactory;
diff --git a/log4j-osgi/pom.xml b/log4j-osgi/pom.xml
index c759422..b4a87b3 100644
--- a/log4j-osgi/pom.xml
+++ b/log4j-osgi/pom.xml
@@ -55,6 +55,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.eclipse.tycho</groupId>
       <artifactId>org.eclipse.osgi</artifactId>
       <scope>test</scope>
@@ -73,6 +78,13 @@
   <build>
     <plugins>
       <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <!-- Skipping tests as I don't know why they are failing -->
+          <skip>false</skip>
+        </configuration>
+      </plugin>
+      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-jar-plugin</artifactId>
         <executions>
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ParameterizedMessageInliningBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ParameterizedMessageInliningBenchmark.java
index 931dc1b..4c698fc 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ParameterizedMessageInliningBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ParameterizedMessageInliningBenchmark.java
@@ -17,6 +17,7 @@
 
 package org.apache.logging.log4j.perf.jmh;
 
+import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.logging.log4j.message.ParameterizedMessage;
@@ -185,7 +186,7 @@
                 result[pos++] = curChar;
             }
         }
-        return result.toString();
+        return Arrays.toString(result);
     }
 
     // 33 bytes
diff --git a/log4j-plugins-java9/pom.xml b/log4j-plugins-java9/pom.xml
deleted file mode 100644
index 1f06881..0000000
--- a/log4j-plugins-java9/pom.xml
+++ /dev/null
@@ -1,173 +0,0 @@
-<?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/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.logging.log4j</groupId>
-    <artifactId>log4j</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-  <artifactId>log4j-plugins-java9</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Log4j Plugins Module support</name>
-  <description>Apache Log4j Plugin Modules Support</description>
-  <properties>
-    <log4jParentDir>${basedir}/..</log4jParentDir>
-    <docLabel>Log4j Plugins Documentation</docLabel>
-    <projectDir>/plugins</projectDir>
-  </properties>
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[11, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <phase>compile</phase>
-            <goals>
-              <goal>compile</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>default-test-compile</id>
-            <phase>test-compile</phase>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <source>9</source>
-          <target>9</target>
-          <release>9</release>
-          <proc>none</proc>
-          <!-- disable errorprone -->
-          <compilerId>javac</compilerId>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <!-- Do not upgrade until https://issues.apache.org/jira/browse/SUREFIRE-720 is fixed -->
-        <version>2.13</version>
-        <executions>
-          <execution>
-            <id>test</id>
-            <phase>test</phase>
-            <goals>
-              <goal>test</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <systemPropertyVariables>
-            <java.awt.headless>true</java.awt.headless>
-          </systemPropertyVariables>
-          <includes>
-            <include>**/Test*.java</include>
-            <include>**/*Test.java</include>
-          </includes>
-          <excludes>
-            <exclude>**/*FuncTest.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>zip</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-            <configuration>
-              <finalName>log4j-plugins-java9-${project.version}</finalName>
-              <appendAssemblyId>false</appendAssemblyId>
-              <descriptors>
-                <descriptor>src/assembly/java9.xml</descriptor>
-              </descriptors>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <version>${deploy.plugin.version}</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-site-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-          <skipDeploy>true</skipDeploy>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-doap-plugin</artifactId>
-        <version>1.2</version>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-</project>
-
diff --git a/log4j-plugins-java9/src/assembly/java9.xml b/log4j-plugins-java9/src/assembly/java9.xml
deleted file mode 100644
index 249fa86..0000000
--- a/log4j-plugins-java9/src/assembly/java9.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?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.
--->
-
-<assembly>
-  <id>src</id>
-  <formats>
-    <format>zip</format>
-  </formats>
-  <baseDirectory>/</baseDirectory>
-  <fileSets>
-    <fileSet>
-      <directory>${project.build.outputDirectory}</directory>
-      <outputDirectory>/classes/META-INF/versions/9</outputDirectory>
-      <includes>
-        <include>module-info.class</include>
-      </includes>
-      <excludes>
-        <exclude>**/Dummy.class</exclude>
-        <exclude>**/PluginService.class</exclude>
-        <exclude>**/Log4jPlugins.class</exclude>
-      </excludes>
-    </fileSet>
-  </fileSets>
-</assembly>
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/Dummy.java
deleted file mode 100644
index 14a90ed..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/bind/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/bind/Dummy.java
deleted file mode 100644
index 98f00c7..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/bind/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.bind;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-plugins module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/Dummy.java
deleted file mode 100644
index 10923e8..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.convert;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/plugins/Log4jPlugins.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/plugins/Log4jPlugins.java
deleted file mode 100644
index 6cdd225..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/convert/plugins/Log4jPlugins.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.convert.plugins;
-
-import org.apache.logging.log4j.plugins.processor.PluginService;
-
-/**
- * Class Description goes here.
- */
-public class Log4jPlugins extends PluginService {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java
deleted file mode 100644
index 68f4aa2..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.inject;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-plugins module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/name/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/name/Dummy.java
deleted file mode 100644
index 853dc00..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/name/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.name;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-plugins module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/processor/PluginService.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/processor/PluginService.java
deleted file mode 100644
index b93ef59..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/processor/PluginService.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.processor;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class PluginService {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/util/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/util/Dummy.java
deleted file mode 100644
index 5940b03..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/util/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.util;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/Dummy.java
deleted file mode 100644
index 14882b5..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.validation;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/Dummy.java
deleted file mode 100644
index 9810d5e..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/constraints/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.validation.constraints;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/validators/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/validators/Dummy.java
deleted file mode 100644
index da73052..0000000
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/validation/validators/Dummy.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.plugins.validation.validators;
-
-/**
- * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
- */
-public class Dummy {
-}
diff --git a/log4j-plugins/pom.xml b/log4j-plugins/pom.xml
index 8bf406d..9fd7229 100644
--- a/log4j-plugins/pom.xml
+++ b/log4j-plugins/pom.xml
@@ -38,13 +38,6 @@
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
     </dependency>
-    <!-- Classes and resources to be shaded into the core jar -->
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-plugins-java9</artifactId>
-      <scope>provided</scope>
-      <type>zip</type>
-    </dependency>
     <!-- Used for OSGi bundle support -->
     <dependency>
       <groupId>org.osgi</groupId>
@@ -64,10 +57,12 @@
     <dependency>
       <groupId>org.junit.vintage</groupId>
       <artifactId>junit-vintage-engine</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
+      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.hamcrest</groupId>
@@ -78,49 +73,17 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-dependency-plugin</artifactId>
-        <version>3.0.2</version>
-        <executions>
-          <execution>
-            <id>unpack-classes</id>
-            <phase>prepare-package</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.apache.logging.log4j</groupId>
-                  <artifactId>log4j-plugins-java9</artifactId>
-                  <version>${project.version}</version>
-                  <type>zip</type>
-                  <overWrite>false</overWrite>
-                </artifactItem>
-              </artifactItems>
-              <includes>**/*.class</includes>
-              <excludes>**/*.java</excludes>
-              <outputDirectory>${project.build.directory}</outputDirectory>
-              <overWriteReleases>false</overWriteReleases>
-              <overWriteSnapshots>true</overWriteSnapshots>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <executions>
           <execution>
-            <!-- disable annotation processing for first pass -->
-            <id>generate-plugins</id>
-            <phase>process-classes</phase>
+            <!-- build the plugin processor -->
+            <id>compile-processor</id>
+            <phase>generate-sources</phase>
             <goals>
               <goal>compile</goal>
             </goals>
-            <configuration>
-              <excludes>
-                <exclude>module-info.java</exclude>
-              </excludes>
+            <configuration combine.self="override">
+              <proc>none</proc>
             </configuration>
           </execution>
           <execution>
@@ -129,36 +92,134 @@
             <goals>
               <goal>compile</goal>
             </goals>
-            <phase>process-classes</phase>
-            <configuration>
-              <excludes>
-                <exclude>module-info.java</exclude>
-              </excludes>
+            <phase>generate-sources</phase>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
               <proc>only</proc>
+              <compilerArguments>
+                <processor>org.apache.logging.log4j.plugins.processor.PluginProcessor</processor>
+              </compilerArguments>
             </configuration>
           </execution>
           <execution>
-            <!-- disable annotation processing for first pass -->
-            <id>generate-test-plugins</id>
-            <phase>generate-test-sources</phase>
+            <!-- then compile the test plugins -->
+            <id>process-test-plugins</id>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+            <phase>generate-sources</phase>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <annotationProcessors>
+                <annotationProcessor>org.apache.logging.log4j.plugins.processor.PluginProcessor</annotationProcessor>
+              </annotationProcessors>
+              <compileSourceRoots>
+                <compileSourceRoot>${project.basedir}/src/test/java-test</compileSourceRoot>
+              </compileSourceRoots>
+              <parameters>true</parameters>
+            </configuration>
+          </execution>
+          <execution>
+            <!-- compile the source -->
+            <id>default-compile</id>
             <goals>
               <goal>compile</goal>
             </goals>
-            <configuration>
-              <excludes>
-                <exclude>module-info.java</exclude>
-              </excludes>
-              <proc>only</proc>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <release>${maven.compiler.release}</release>
+              <showDeprecation>true</showDeprecation>
+              <showWarnings>true</showWarnings>
+              <encoding>UTF-8</encoding>
+              <fork>true</fork>
+              <meminitial>256</meminitial>
+              <maxmem>1024</maxmem>
+              <compilerArgs>
+                <arg>-XDcompilePolicy=simple</arg>
+                <arg>-Xplugin:ErrorProne</arg>
+              </compilerArgs>
+              <compilerArguments>
+                <Xmaxwarns>10000</Xmaxwarns>
+                <Xlint />
+              </compilerArguments>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>com.google.errorprone</groupId>
+                  <artifactId>error_prone_core</artifactId>
+                  <version>${errorprone.version}</version>
+                </path>
+              </annotationProcessorPaths>
+              <forceJavacCompilerUse>true</forceJavacCompilerUse>
+              <parameters>true</parameters>
             </configuration>
           </execution>
           <execution>
-            <!-- disable annotation processing for first pass -->
-            <id>default-compile</id>
+            <!-- compile the test source -->
+            <id>default-test-compile</id>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+            <configuration combine.self="override">
+              <source>${maven.compiler.source}</source>
+              <target>${maven.compiler.target}</target>
+              <release>${maven.compiler.release}</release>
+              <showDeprecation>true</showDeprecation>
+              <showWarnings>true</showWarnings>
+              <encoding>UTF-8</encoding>
+              <fork>true</fork>
+              <meminitial>256</meminitial>
+              <maxmem>1024</maxmem>
+              <compilerArgs>
+                <arg>-XDcompilePolicy=simple</arg>
+                <arg>-Xplugin:ErrorProne</arg>
+              </compilerArgs>
+              <compilerArguments>
+                <Xmaxwarns>10000</Xmaxwarns>
+                <Xlint />
+              </compilerArguments>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>com.google.errorprone</groupId>
+                  <artifactId>error_prone_core</artifactId>
+                  <version>${errorprone.version}</version>
+                </path>
+              </annotationProcessorPaths>
+              <forceJavacCompilerUse>true</forceJavacCompilerUse>
+              <parameters>true</parameters>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>3.2.0</version>
+        <executions>
+          <execution>
+            <id>add-module</id>
+            <phase>process-sources</phase>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
             <configuration>
-              <excludes>
-                <exclude>module-info.java</exclude>
-              </excludes>
-              <proc>none</proc>
+              <sources>
+                <source>src/main/java9</source>
+              </sources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>add-test-module</id>
+            <phase>process-test-sources</phase>
+            <goals>
+              <goal>add-test-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>src/test/java9</source>
+              </sources>
             </configuration>
           </execution>
         </executions>
@@ -166,6 +227,7 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
+          <useModulePath>false</useModulePath>
           <excludedGroups>
             org.apache.logging.log4j.categories.PerformanceTests
           </excludedGroups>
@@ -203,20 +265,19 @@
                   <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
                   <X-Compile-Source-JDK>${maven.compiler.source}</X-Compile-Source-JDK>
                   <X-Compile-Target-JDK>${maven.compiler.target}</X-Compile-Target-JDK>
-                  <Automatic-Module-Name>org.apache.logging.log4j.plugins</Automatic-Module-Name>
-                  <Multi-Release>true</Multi-Release>
                 </manifestEntries>
               </archive>
             </configuration>
           </execution>
           <execution>
-            <id>default</id>
+            <id>test-jar</id>
             <goals>
               <goal>test-jar</goal>
             </goals>
+            <phase>process-resources</phase>
             <configuration>
               <archive>
-                <manifestFile>${manifestfile}</manifestFile>
+                <!--<manifestFile>${manifestfile}</manifestFile>-->
                 <manifestEntries>
                   <Specification-Title>${project.name}</Specification-Title>
                   <Specification-Version>${project.version}</Specification-Version>
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/BeanUtils.java
similarity index 60%
copy from log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java
copy to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/BeanUtils.java
index b51c0b9..2b98f3b 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/junit/ThreadContextStackRule.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/internal/util/BeanUtils.java
@@ -14,26 +14,24 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.junit;
+package org.apache.logging.log4j.plugins.internal.util;
 
 /**
- * Restores the ThreadContext to it's initial stack values after a JUnit test.
- * 
- * Usage:
- * 
- * <pre>
- * &#64;Rule
- * public final ThreadContextStackRule threadContextRule = new ThreadContextStackRule();
- * </pre>
- * @deprecated use {@link UsingThreadContextStack} with JUnit 5
+ * Utility methods.
  */
-@Deprecated
-public class ThreadContextStackRule extends ThreadContextRule {
+public final class BeanUtils {
+    private BeanUtils() {
+    }
 
-    /**
-     * Constructs an initialized instance.
-     */
-    public ThreadContextStackRule() {
-        super(false, true);
+    public static String decapitalize(String string) {
+        if (string.isEmpty()) {
+            return string;
+        }
+        char[] chars = string.toCharArray();
+        if (chars.length >= 2 && Character.isUpperCase(chars[0]) && Character.isUpperCase(chars[1])) {
+            return string;
+        }
+        chars[0] = Character.toLowerCase(chars[0]);
+        return new String(chars);
     }
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AnnotatedElementNameProvider.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AnnotatedElementNameProvider.java
index 34349d6..5c3a039 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AnnotatedElementNameProvider.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/name/AnnotatedElementNameProvider.java
@@ -17,9 +17,9 @@
 
 package org.apache.logging.log4j.plugins.name;
 
+import org.apache.logging.log4j.plugins.internal.util.BeanUtils;
 import org.apache.logging.log4j.util.ReflectionUtil;
 
-import java.beans.Introspector;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Field;
@@ -51,10 +51,10 @@
             final Method method = (Method) element;
             final String methodName = method.getName();
             if (methodName.startsWith("set")) {
-                return Introspector.decapitalize(methodName.substring(3));
+                return BeanUtils.decapitalize(methodName.substring(3));
             }
             if (methodName.startsWith("with")) {
-                return Introspector.decapitalize(methodName.substring(4));
+                return BeanUtils.decapitalize(methodName.substring(4));
             }
             return methodName;
         }
diff --git a/log4j-plugins-java9/src/main/java/module-info.java b/log4j-plugins/src/main/java9/module-info.java
similarity index 89%
rename from log4j-plugins-java9/src/main/java/module-info.java
rename to log4j-plugins/src/main/java9/module-info.java
index 896d3e1..2de0ae8 100644
--- a/log4j-plugins-java9/src/main/java/module-info.java
+++ b/log4j-plugins/src/main/java9/module-info.java
@@ -26,9 +26,12 @@
     exports org.apache.logging.log4j.plugins.inject;
     exports org.apache.logging.log4j.plugins.name;
 
+    requires java.compiler;
     requires org.apache.logging.log4j;
+    requires transitive org.osgi.core;
 
     provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.plugins.convert.plugins.Log4jPlugins;
+    provides javax.annotation.processing.Processor with org.apache.logging.log4j.plugins.processor.PluginProcessor;
 
     uses org.apache.logging.log4j.plugins.processor.PluginService;
 }
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/processor/FakePlugin.java
similarity index 94%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/processor/FakePlugin.java
index 48ea7dc..979fdf4 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/FakePlugin.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/processor/FakePlugin.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.processor;
+package org.apache.logging.log4j.plugins.test.processor;
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAliases;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/AbstractPluginWithGenericBuilder.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/AbstractPluginWithGenericBuilder.java
similarity index 96%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/AbstractPluginWithGenericBuilder.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/AbstractPluginWithGenericBuilder.java
index 0e243f2..07c9e07 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/AbstractPluginWithGenericBuilder.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/AbstractPluginWithGenericBuilder.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.plugins.validation.constraints.Required;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/HostAndPort.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/HostAndPort.java
similarity index 96%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/HostAndPort.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/HostAndPort.java
index 335ea49..000a387 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/HostAndPort.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/HostAndPort.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.plugins.PluginFactory;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/PluginWithGenericSubclassFoo1Builder.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/PluginWithGenericSubclassFoo1Builder.java
similarity index 97%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/PluginWithGenericSubclassFoo1Builder.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/PluginWithGenericSubclassFoo1Builder.java
index 0ae991a..eeeb8fa 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/PluginWithGenericSubclassFoo1Builder.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/PluginWithGenericSubclassFoo1Builder.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAttribute;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPlugin.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPlugin.java
similarity index 97%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPlugin.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPlugin.java
index eda7145..a3f4c73 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPlugin.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPlugin.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithGenericBuilder.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithGenericBuilder.java
similarity index 97%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithGenericBuilder.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithGenericBuilder.java
index eb9db3f..843878f 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithGenericBuilder.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithGenericBuilder.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAttribute;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithTypedBuilder.java b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithTypedBuilder.java
similarity index 97%
rename from log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithTypedBuilder.java
rename to log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithTypedBuilder.java
index fc736b3..5d9dcea 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/validation/ValidatingPluginWithTypedBuilder.java
+++ b/log4j-plugins/src/test/java-test/org/apache/logging/log4j/plugins/test/validation/ValidatingPluginWithTypedBuilder.java
@@ -14,7 +14,7 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.validation;
+package org.apache.logging.log4j.plugins.test.validation;
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/PluginProcessorTest.java b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/PluginProcessorTest.java
index b3bd425..b43c95a 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/PluginProcessorTest.java
+++ b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/processor/PluginProcessorTest.java
@@ -19,17 +19,14 @@
 
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.plugins.PluginAliases;
+import org.apache.logging.log4j.plugins.test.processor.FakePlugin;
 import org.apache.logging.log4j.plugins.util.PluginType;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.List;
-import java.util.Map;
 
 import static org.junit.Assert.*;
 
@@ -42,7 +39,7 @@
 
     @BeforeClass
     public static void setUpClass() throws Exception {
-        Class<?> clazz = PluginProcessor.class.getClassLoader().loadClass("org.apache.logging.log4j.plugins.plugins.Log4jPlugins");
+        Class<?> clazz = PluginProcessor.class.getClassLoader().loadClass("org.apache.logging.log4j.plugins.test.plugins.Log4jPlugins");
         assertNotNull("Could not locate plugins class", clazz);
         pluginService = (PluginService) clazz.getDeclaredConstructor().newInstance();;
     }
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
index d0b35d1..6852711 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
+++ b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
@@ -17,8 +17,8 @@
 
 package org.apache.logging.log4j.plugins.util;
 
-import org.apache.logging.log4j.junit.CleanFolders;
-import org.apache.logging.log4j.junit.URLStreamHandlerFactoryRule;
+import org.apache.logging.log4j.test.junit.CleanFolders;
+import org.apache.logging.log4j.test.junit.URLStreamHandlerFactoryRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
index 361fe7b..10b3cc3 100644
--- a/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
+++ b/log4j-plugins/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.plugins.util;
 
-import org.apache.logging.log4j.junit.CleanFolders;
+import org.apache.logging.log4j.test.junit.CleanFolders;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
@@ -233,6 +233,9 @@
                 }
             }
         }
+        if (!errors.isEmpty()) {
+            System.err.println("Compilatoin of " + f.getAbsolutePath() + " failed");
+        }
         assertTrue(errors.toString(), errors.isEmpty());
     }
 
diff --git a/log4j-plugins/src/test/java9/module-info.java b/log4j-plugins/src/test/java9/module-info.java
new file mode 100644
index 0000000..d96dd94
--- /dev/null
+++ b/log4j-plugins/src/test/java9/module-info.java
@@ -0,0 +1,16 @@
+open module org.apache.logging.log4j.plugins {
+    exports org.apache.logging.log4j.plugins;
+
+    requires java.compiler;
+    requires org.apache.logging.log4j;
+    requires org.junit.jupiter.api;
+    requires org.junit.jupiter.engine;
+    requires org.junit.platform.commons;
+    requires org.junit.platform.engine;
+    requires junit;
+
+    provides org.apache.logging.log4j.plugins.processor.PluginService with org.apache.logging.log4j.plugins.convert.plugins.Log4jPlugins;
+    provides javax.annotation.processing.Processor with org.apache.logging.log4j.plugins.processor.PluginProcessor;
+
+    uses org.apache.logging.log4j.plugins.processor.PluginService;
+}
\ No newline at end of file
diff --git a/log4j-redis/pom.xml b/log4j-redis/pom.xml
index 470af07..e5b1fce 100644
--- a/log4j-redis/pom.xml
+++ b/log4j-redis/pom.xml
@@ -50,6 +50,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-slf4j-impl/pom.xml b/log4j-slf4j-impl/pom.xml
index 37665b5..234d1f2 100644
--- a/log4j-slf4j-impl/pom.xml
+++ b/log4j-slf4j-impl/pom.xml
@@ -92,6 +92,11 @@
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
index c982440..0f7e092 100644
--- a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
+++ b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
@@ -20,7 +20,7 @@
 

 import java.util.List;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.junit.LoggerContextRule;

 import org.apache.logging.log4j.test.appender.ListAppender;

 import org.junit.ClassRule;

 import org.junit.Test;

diff --git a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
index 0524074..6d04e7a 100644
--- a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
+++ b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
@@ -23,7 +23,7 @@
 import java.util.List;
 import java.util.Locale;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.After;
diff --git a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/OptionalTest.java b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/OptionalTest.java
index a6e9fd5..a3faeff 100644
--- a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/OptionalTest.java
+++ b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/OptionalTest.java
@@ -18,7 +18,7 @@
 
 import java.util.List;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.Before;
diff --git a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
index 746731b..61fb01a 100644
--- a/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
+++ b/log4j-slf4j-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
@@ -18,13 +18,13 @@
 

 import java.io.Serializable;

 

-import org.apache.logging.log4j.junit.LoggerContextRule;

+import org.apache.logging.log4j.core.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.apache.logging.log4j.test.SerializableMatchers.serializesRoundTrip;

 import static org.junit.Assert.*;

 

 /**

diff --git a/log4j-slf4j18-impl/pom.xml b/log4j-slf4j18-impl/pom.xml
index 1ee7bf2..87564a4 100644
--- a/log4j-slf4j18-impl/pom.xml
+++ b/log4j-slf4j18-impl/pom.xml
@@ -92,6 +92,11 @@
       <groupId>org.junit.jupiter</groupId>
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
index 7efc0e5..762b6ab 100644
--- a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
+++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/CallerInformationTest.java
@@ -20,7 +20,7 @@
 
 import java.util.List;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
index c60f1ad..7d1ac7b 100644
--- a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
+++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/LoggerTest.java
@@ -22,7 +22,7 @@
 
 import java.util.List;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.apache.logging.log4j.util.Strings;
 import org.junit.After;
diff --git a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
index d3d3db6..a47aa65 100644
--- a/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
+++ b/log4j-slf4j18-impl/src/test/java/org/apache/logging/slf4j/SerializeTest.java
@@ -18,13 +18,13 @@
 
 import java.io.Serializable;
 
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.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.apache.logging.log4j.test.SerializableMatchers.serializesRoundTrip;
 import static org.junit.Assert.*;
 
 /**
diff --git a/log4j-smtp/pom.xml b/log4j-smtp/pom.xml
index 683d7f6..52a6e45 100644
--- a/log4j-smtp/pom.xml
+++ b/log4j-smtp/pom.xml
@@ -49,6 +49,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <type>test-jar</type>
diff --git a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java
index d086c73..11e1361 100644
--- a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java
+++ b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderAsyncTest.java
@@ -20,7 +20,7 @@
 import org.apache.logging.dumbster.smtp.SmtpMessage;
 import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.core.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.AvailablePortFinder;
 import org.junit.After;
 import org.junit.AfterClass;
diff --git a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java
index 90f08c5..44d7708 100644
--- a/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java
+++ b/log4j-smtp/src/test/java/org/apache/logging/log4j/smtp/appender/SmtpAppenderTest.java
@@ -26,7 +26,7 @@
 import org.apache.logging.dumbster.smtp.SmtpMessage;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.ThreadContext;
-import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.categories.Appenders;
 import org.apache.logging.log4j.core.Logger;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.smtp.MimeMessageBuilder;
diff --git a/log4j-spring-boot/pom.xml b/log4j-spring-boot/pom.xml
index 1a4680d..575dc15 100644
--- a/log4j-spring-boot/pom.xml
+++ b/log4j-spring-boot/pom.xml
@@ -131,49 +131,6 @@
           </instructions>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <phase>compile</phase>
-            <goals>
-              <goal>compile</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>default-test-compile</id>
-            <phase>test-compile</phase>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>[8, )</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
     </plugins>
   </build>
   <reporting>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2EventListenerTest.java b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2EventListenerTest.java
index 1a14755..9a2dd3e 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2EventListenerTest.java
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-client/src/test/java/org/apache/logging/log4j/spring/cloud/config/client/Log4j2EventListenerTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.core.config.Reconfigurable;
 import org.apache.logging.log4j.core.util.Source;
 import org.apache.logging.log4j.core.util.Watcher;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-application/pom.xml b/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-application/pom.xml
index a988c0a..435cdf8 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-application/pom.xml
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-application/pom.xml
@@ -17,8 +17,6 @@
   <url>http://maven.apache.org</url>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
     <!--<manifestfile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestfile>-->
   </properties>
 
@@ -164,50 +162,6 @@
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-toolchains-plugin</artifactId>
-        <version>1.1</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>toolchain</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <toolchains>
-            <jdk>
-              <version>1.8</version>
-            </jdk>
-          </toolchains>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>default-compile</id>
-            <phase>compile</phase>
-            <goals>
-              <goal>compile</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>default-test-compile</id>
-            <phase>test-compile</phase>
-            <goals>
-              <goal>testCompile</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <source>1.8</source>
-          <target>1.8</target>
-          <proc>none</proc>
-        </configuration>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>2.18.1</version>
         <executions>
diff --git a/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-server/pom.xml b/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-server/pom.xml
index 591b62d..dfc49f8 100644
--- a/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-server/pom.xml
+++ b/log4j-spring-cloud-config/log4j-spring-cloud-config-samples/log4j-spring-cloud-config-sample-server/pom.xml
@@ -35,7 +35,7 @@
     <maven.findbugs.version>3.0.5</maven.findbugs.version>
     <maven.google.code.findbugs.version>3.0.2</maven.google.code.findbugs.version>
     <maven.google.code.findbugs.findbugs.version>3.0.1</maven.google.code.findbugs.findbugs.version>
-    <maven.jacoco.version>0.8.1</maven.jacoco.version>
+    <maven.jacoco.version>0.8.6</maven.jacoco.version>
     <maven.pmd.version>3.9.0</maven.pmd.version>
     <site.plugin.version>3.4</site.plugin.version>
     <!-- maven plugin config -->
diff --git a/log4j-taglib/pom.xml b/log4j-taglib/pom.xml
index a240332..c26b692 100644
--- a/log4j-taglib/pom.xml
+++ b/log4j-taglib/pom.xml
@@ -76,6 +76,11 @@
       <artifactId>junit-jupiter-engine</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.hamcrest</groupId>
+      <artifactId>hamcrest-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <scope>test</scope>
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/CatchingTagTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/CatchingTagTest.java
index ae7f8a0..f6fbdf1 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/CatchingTagTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/CatchingTagTest.java
@@ -21,7 +21,7 @@
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.ClassRule;
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/EnterTagTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/EnterTagTest.java
index 6651d96..c9fc6ec 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/EnterTagTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/EnterTagTest.java
@@ -20,7 +20,7 @@
 import javax.servlet.jsp.tagext.Tag;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.ClassRule;
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/ExitTagTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/ExitTagTest.java
index 3e5ab22..7bc9eb4 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/ExitTagTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/ExitTagTest.java
@@ -20,7 +20,7 @@
 import javax.servlet.jsp.tagext.Tag;
 
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.Before;
 import org.junit.ClassRule;
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/IfEnabledTagTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/IfEnabledTagTest.java
index 9596c5b..3ecdb0c 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/IfEnabledTagTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/IfEnabledTagTest.java
@@ -21,7 +21,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/LoggingMessageTagSupportTest.java b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/LoggingMessageTagSupportTest.java
index 26aa46c..b1242b1 100644
--- a/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/LoggingMessageTagSupportTest.java
+++ b/log4j-taglib/src/test/java/org/apache/logging/log4j/taglib/LoggingMessageTagSupportTest.java
@@ -25,7 +25,7 @@
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.MarkerManager;
-import org.apache.logging.log4j.junit.LoggerContextRule;
+import org.apache.logging.log4j.core.junit.LoggerContextRule;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.ClassRule;
 import org.junit.Test;
diff --git a/pom.xml b/pom.xml
index 8efb53e..f424f0c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -208,14 +208,14 @@
     <!-- surefire.plugin.version 2.18 yields http://jira.codehaus.org/browse/SUREFIRE-1121, which is fixed in 2.18.1 -->
     <!-- surefire.plugin.version 2.19 yields https://issues.apache.org/jira/browse/SUREFIRE-1193. -->
     <!-- all versions after 2.13 yield https://issues.apache.org/jira/browse/SUREFIRE-720 -->
-    <surefire.plugin.version>2.22.2</surefire.plugin.version>
+    <surefire.plugin.version>3.0.0-M5</surefire.plugin.version>
     <failsafe.plugin.version>2.22.2</failsafe.plugin.version>
     <checkstyle.plugin.version>3.0.0</checkstyle.plugin.version>
     <deploy.plugin.version>2.8.2</deploy.plugin.version>
     <rat.plugin.version>0.13</rat.plugin.version>
     <pdf.plugin.version>1.2</pdf.plugin.version>
     <cobertura.plugin.version>2.7</cobertura.plugin.version>
-    <jacoco.plugin.version>0.8.5</jacoco.plugin.version>
+    <jacoco.plugin.version>0.8.6</jacoco.plugin.version>
     <release.plugin.version>2.5.3</release.plugin.version>
     <scm.plugin.version>1.9.5</scm.plugin.version>
     <jxr.plugin.version>2.5</jxr.plugin.version>
@@ -226,12 +226,13 @@
     <!-- See https://maven.apache.org/plugins/maven-site-plugin/migrate.html -->
     <velocity.plugin.version>1.5</velocity.plugin.version>
     <asciidoc.plugin.version>1.5.6</asciidoc.plugin.version>
-    <errorprone.version>2.3.2</errorprone.version>
+    <errorprone.version>2.5.1</errorprone.version>
     <plexus.errorprone.version>2.8.5</plexus.errorprone.version>
     <remote.resources.plugin.version>1.5</remote.resources.plugin.version>
     <manifestfile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestfile>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
+    <maven.compiler.source>11</maven.compiler.source>
+    <maven.compiler.target>11</maven.compiler.target>
+    <maven.compiler.release>11</maven.compiler.release>
     <maven.doap.skip>false</maven.doap.skip>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <docLabel>Site Documentation</docLabel>
@@ -247,7 +248,7 @@
     <junitJupiterVersion>5.7.0</junitJupiterVersion>
     <mockitoVersion>3.5.5</mockitoVersion>
     <argLine>-Xms256m -Xmx1024m</argLine>
-    <javaTargetVersion>1.8</javaTargetVersion>
+    <javaTargetVersion>11</javaTargetVersion>
     <module.name />
   </properties>
   <pluginRepositories>
@@ -292,12 +293,12 @@
       <dependency>
         <groupId>org.eclipse.tycho</groupId>
         <artifactId>org.eclipse.osgi</artifactId>
-        <version>3.12.1.v20170821-1548</version>
+        <version>3.13.0.v20180226-1711</version>
       </dependency>
       <dependency>
         <groupId>org.apache.felix</groupId>
         <artifactId>org.apache.felix.framework</artifactId>
-        <version>5.6.10</version>
+        <version>7.0.0</version>
       </dependency>
       <dependency>
         <groupId>org.apache.maven</groupId>
@@ -329,9 +330,8 @@
       </dependency>
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
-        <artifactId>log4j-api-java9</artifactId>
+        <artifactId>log4j-api-test</artifactId>
         <version>${project.version}</version>
-        <type>zip</type>
       </dependency>
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
@@ -340,12 +340,6 @@
       </dependency>
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
-        <artifactId>log4j-plugins-java9</artifactId>
-        <version>${project.version}</version>
-        <type>zip</type>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.logging.log4j</groupId>
         <artifactId>log4j-plugins</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -717,6 +711,12 @@
         <artifactId>junit</artifactId>
         <version>${junitVersion}</version>
         <scope>test</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-core</artifactId>
+          </exclusion>
+        </exclusions>
       </dependency>
       <!-- JUnit 4 engine -->
       <dependency>
@@ -911,7 +911,7 @@
       <dependency>
         <groupId>com.google.code.java-allocation-instrumenter</groupId>
         <artifactId>java-allocation-instrumenter</artifactId>
-        <version>3.0.1</version>
+        <version>3.3.0</version>
       </dependency>
       <dependency>
         <groupId>org.hdrhistogram</groupId>
@@ -948,7 +948,7 @@
         <plugin>
           <groupId>org.apache.felix</groupId>
           <artifactId>maven-bundle-plugin</artifactId>
-          <version>3.5.0</version>
+          <version>5.1.2</version>
           <inherited>true</inherited>
           <extensions>true</extensions>
           <executions>
@@ -1004,32 +1004,36 @@
           <configuration>
             <source>${maven.compiler.source}</source>
             <target>${maven.compiler.target}</target>
+            <release>${maven.compiler.release}</release>
             <showDeprecation>true</showDeprecation>
             <showWarnings>true</showWarnings>
             <encoding>UTF-8</encoding>
             <fork>true</fork>
             <meminitial>256</meminitial>
             <maxmem>1024</maxmem>
+            <compilerArgs>
+              <arg>-XDcompilePolicy=simple</arg>
+              <arg>-Xplugin:ErrorProne</arg>
+            </compilerArgs>
             <compilerArguments>
               <Xmaxwarns>10000</Xmaxwarns>
               <Xlint />
             </compilerArguments>
-            <compilerId>javac-with-errorprone</compilerId>
+            <annotationProcessorPaths>
+              <path>
+                <groupId>com.google.errorprone</groupId>
+                <artifactId>error_prone_core</artifactId>
+                <version>${errorprone.version}</version>
+              </path>
+              <path>
+                <groupId>org.apache.logging.log4j</groupId>
+                <artifactId>log4j-plugins</artifactId>
+                <version>${project.version}</version>
+              </path>
+            </annotationProcessorPaths>
             <forceJavacCompilerUse>true</forceJavacCompilerUse>
             <parameters>true</parameters>
           </configuration>
-          <dependencies>
-            <dependency>
-              <groupId>org.codehaus.plexus</groupId>
-              <artifactId>plexus-compiler-javac-errorprone</artifactId>
-              <version>${plexus.errorprone.version}</version>
-            </dependency>
-            <dependency>
-              <groupId>com.google.errorprone</groupId>
-              <artifactId>error_prone_core</artifactId>
-              <version>${errorprone.version}</version>
-            </dependency>
-          </dependencies>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -1580,11 +1584,8 @@
     </site>
   </distributionManagement>
   <modules>
-    <module>log4j-api-java9</module>
     <module>log4j-api</module>
-    <module>log4j-plugins-java9</module>
     <module>log4j-plugins</module>
-    <module>log4j-core-java9</module>
     <module>log4j-core</module>
     <module>log4j-layout-jackson</module>
     <module>log4j-layout-jackson-json</module>
diff --git a/src/site/asciidoc/manual/configuration.adoc b/src/site/asciidoc/manual/configuration.adoc
index cb17098..d0fed9e 100644
--- a/src/site/asciidoc/manual/configuration.adoc
+++ b/src/site/asciidoc/manual/configuration.adoc
@@ -1795,6 +1795,12 @@
 You can also specify a fully qualified class name of a custom class that
 implements the `Clock` interface.
 
+|[[usePreciseClock]]log4j2.usePreciseClock
+|LOG4J_USE_PRECISE_CLOCK
+|false
+|When false the clock resolution will be in milliseconds. When true it will use the smallest granularity supported by
+the JVM. The precise clock is not garbage free. This setting only applies when Log4j's default SystemClock is used.
+
 |[[level]]log4j2.level +
 ([[org.apache.logging.log4j.level]]org.apache.logging.log4j.level)
 |LOG4J_LEVEL
diff --git a/src/site/asciidoc/manual/garbagefree.adoc b/src/site/asciidoc/manual/garbagefree.adoc
index f18f6cb..edf4bcd 100644
--- a/src/site/asciidoc/manual/garbagefree.adoc
+++ b/src/site/asciidoc/manual/garbagefree.adoc
@@ -431,6 +431,8 @@
 garbage-free: `logger.debug(() -> callExpensiveMethod())`.
 * The `Logger.traceEntry` and `Logger.traceExit` methods create
 temporary objects.
+* Time calculations are not garbage free when log4j2.usePreciseClock is set to true.
+The default is false.
 ****
 
 [#Performance]
diff --git a/src/site/asciidoc/manual/layouts.adoc b/src/site/asciidoc/manual/layouts.adoc
index 95ec2db..55c6a21 100644
--- a/src/site/asciidoc/manual/layouts.adoc
+++ b/src/site/asciidoc/manual/layouts.adoc
@@ -282,7 +282,7 @@
 are also specified this attribute will override them. ThreadContext fields specified here that
 have no value will be omitted.
 
-|ThreadContextPrefix
+|threadContextPrefix
 |String
 |A String to prepend to all elements of the ThreadContextMap when rendered as a field. Defaults to an empty String.
 |===