You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2023/01/20 09:18:19 UTC

[logging-log4j2] branch master updated (9f266e107c -> cf0bf168eb)

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

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


    from 9f266e107c Do not interpret "disableAnsi" and "noConsoleNoAnsi" as escapes
     new cb0be38f89 [LOG4J2-3546] Fix SLF4J and JUL implementation in OSGi environment
     new cf0bf168eb Removes dependency on log4j-samples-configuration

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


Summary of changes:
 log4j-bom/pom.xml                                  |   6 ++
 log4j-osgi/pom.xml                                 |  47 ++++++++--
 .../log4j/osgi/tests/AbstractLoadBundleTest.java   |  95 +++----------------
 .../logging/log4j/osgi/tests/AbstractOsgiTest.java |  18 ----
 .../logging/log4j/osgi/tests/CoreOsgiTest.java     | 103 +++++++++++++++++++++
 .../log4j/osgi/tests}/CustomConfiguration.java     |  87 +++++++++++------
 .../osgi/tests}/CustomConfigurationFactory.java    |   8 +-
 .../logging/log4j/osgi/tests/JULProviderTest.java  |  70 ++++++++++++++
 .../log4j/osgi/tests/SLF4JProviderTest.java        |  69 ++++++++++++++
 .../log4j/osgi/tests/junit/BundleTestInfo.java     |  74 ---------------
 log4j-osgi/src/test/resources/log4j2.custom        |   1 +
 .../logging/log4j/plugins/osgi/Activator.java      |   1 +
 log4j-to-jul/pom.xml                               |   2 +-
 13 files changed, 368 insertions(+), 213 deletions(-)
 create mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CoreOsgiTest.java
 copy {log4j-samples/log4j-samples-configuration/src/main/java/org/apache/logging/log4j/configuration => log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests}/CustomConfiguration.java (57%)
 copy {log4j-samples/log4j-samples-configuration/src/main/java/org/apache/logging/log4j/configuration => log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests}/CustomConfigurationFactory.java (95%)
 create mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/JULProviderTest.java
 create mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/SLF4JProviderTest.java
 delete mode 100644 log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
 create mode 100644 log4j-osgi/src/test/resources/log4j2.custom


[logging-log4j2] 01/02: [LOG4J2-3546] Fix SLF4J and JUL implementation in OSGi environment

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

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

commit cb0be38f8977ad144d0624ce5acbf0f3124781d6
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sun Jul 3 21:04:11 2022 +0200

    [LOG4J2-3546] Fix SLF4J and JUL implementation in OSGi environment
    
    Tests `log4j-to-jul` and `log4j-to-slf4j` in an OSGI environment.
    
    Newer tests in `log4j-osgi` are written using PAX Exam in order to
    provide better OSGI testing.
---
 log4j-bom/pom.xml                                  |  6 ++
 log4j-osgi/pom.xml                                 | 53 ++++++++++++++--
 .../log4j/osgi/tests/AbstractLoadBundleTest.java   | 24 ++++---
 .../logging/log4j/osgi/tests/AbstractOsgiTest.java | 18 ------
 .../logging/log4j/osgi/tests/JULProviderTest.java  | 70 ++++++++++++++++++++
 .../log4j/osgi/tests/SLF4JProviderTest.java        | 69 ++++++++++++++++++++
 .../log4j/osgi/tests/junit/BundleTestInfo.java     | 74 ----------------------
 log4j-to-jul/pom.xml                               |  2 +-
 8 files changed, 203 insertions(+), 113 deletions(-)

diff --git a/log4j-bom/pom.xml b/log4j-bom/pom.xml
index d5b305ac0c..5f21d56331 100644
--- a/log4j-bom/pom.xml
+++ b/log4j-bom/pom.xml
@@ -298,6 +298,12 @@
         <artifactId>log4j-taglib</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <!-- Log4j-to-JUL bridge -->
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-to-jul</artifactId>
+        <version>${project.version}</version>
+      </dependency>
       <!-- SLF4J Adapter -->
       <dependency>
         <groupId>org.apache.logging.log4j</groupId>
diff --git a/log4j-osgi/pom.xml b/log4j-osgi/pom.xml
index 3fa7fb2584..b6b076dbd8 100644
--- a/log4j-osgi/pom.xml
+++ b/log4j-osgi/pom.xml
@@ -32,6 +32,7 @@
     <projectDir>/osgi</projectDir>
     <module.name>org.apache.logging.log4j.osgi</module.name>
     <maven.doap.skip>true</maven.doap.skip>
+    <pax.exam.version>4.13.5</pax.exam.version>
   </properties>
   <dependencies>
     <dependency>
@@ -55,8 +56,19 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-to-jul</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-to-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j.samples</groupId>
+      <artifactId>log4j-samples-configuration</artifactId>
+      <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -75,11 +87,19 @@
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.logging.log4j.samples</groupId>
-      <artifactId>log4j-samples-configuration</artifactId>
-      <version>${project.version}</version>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-core</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.framework</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-core</artifactId>
@@ -124,6 +144,19 @@
   </dependencies>
   <build>
     <plugins>
+      <plugin>
+        <groupId>org.ops4j.pax.exam</groupId>
+        <artifactId>exam-maven-plugin</artifactId>
+        <version>${pax.exam.version}</version>
+        <executions>
+            <execution>
+                <phase>generate-test-resources</phase>
+                <goals>
+                    <goal>generate-link-files</goal>
+                </goals>
+            </execution>
+        </executions>
+      </plugin>
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
@@ -150,8 +183,14 @@
       <plugin>
         <artifactId>maven-surefire-plugin</artifactId>
         <configuration>
-          <!-- Skipping tests as I don't know why they are failing -->
-          <skip>false</skip>
+          <classpathDependencyExcludes>
+            <classpathDependencyExclude>org.osgi:org.osgi.framework</classpathDependencyExclude>
+          </classpathDependencyExcludes>
+          <systemPropertyVariables>
+            <!-- PAX logging has a copy of Log4j2 API-->
+            <pax.exam.logging>false</pax.exam.logging>
+            <java.protocol.handler.pkgs>org.ops4j.pax.url</java.protocol.handler.pkgs>
+          </systemPropertyVariables>
         </configuration>
       </plugin>
     </plugins>
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
index 0c9f1c92a1..a73202ca22 100644
--- a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
@@ -20,7 +20,6 @@ import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
-import java.nio.file.Path;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -32,33 +31,32 @@ import org.osgi.framework.BundleException;
  */
 public abstract class AbstractLoadBundleTest extends AbstractOsgiTest {
 
+    private Bundle installBundle(String symbolicName) throws BundleException {
+        // The links are generated by 'exam-maven-plugin'
+        final String url = String.format("link:classpath:%s.link", symbolicName);
+        return getBundleContext().installBundle(url);
+    }
+
     private Bundle getApiBundle() throws BundleException {
-        final Path apiPath = getHere().resolveSibling("log4j-api").resolve("target").resolve(getBundleTestInfo().buildJarFileName("log4j-api"));
-        return getBundleContext().installBundle(apiPath.toUri().toString());
+        return installBundle("org.apache.logging.log4j.api");
     }
 
     private Bundle getPluginsBundle() throws BundleException {
-        final Path apiPath = getHere().resolveSibling("log4j-plugins").resolve("target").resolve(getBundleTestInfo().buildJarFileName("log4j-plugins"));
-        return getBundleContext().installBundle(apiPath.toUri().toString());
+        return installBundle("org.apache.logging.log4j.plugins");
     }
 
-
     private Bundle getCoreBundle() throws BundleException {
-        final Path corePath = getHere().resolveSibling("log4j-core").resolve("target").resolve(getBundleTestInfo().buildJarFileName("log4j-core"));
-        return getBundleContext().installBundle(corePath.toUri().toString());
+        return installBundle("org.apache.logging.log4j.core");
     }
 
     private Bundle getDummyBundle() throws BundleException {
-        final Path dumyPath = getHere().resolveSibling("log4j-samples").resolve("log4j-samples-configuration").resolve("target").resolve(getBundleTestInfo().buildJarFileName("log4j-samples-configuration"));
-        return getBundleContext().installBundle(dumyPath.toUri().toString());
+        return installBundle("org.apache.logging.log4j.samples.log4j-samples-configuration");
     }
 
     private Bundle get12ApiBundle() throws BundleException {
-        final Path apiPath = getHere().resolveSibling("log4j-1.2-api").resolve("target").resolve(getBundleTestInfo().buildJarFileName("log4j-1.2-api"));
-        return getBundleContext().installBundle(apiPath.toUri().toString());
+        return installBundle("org.apache.logging.log4j.1.2-api");
     }
 
-
     private void log(final Bundle dummy) throws ReflectiveOperationException {
         // use reflection to log in the context of the dummy bundle
 
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractOsgiTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractOsgiTest.java
index a717c464f5..a8db58438f 100644
--- a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractOsgiTest.java
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractOsgiTest.java
@@ -16,10 +16,6 @@
  */
 package org.apache.logging.log4j.osgi.tests;
 
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import org.apache.logging.log4j.osgi.tests.junit.BundleTestInfo;
 import org.apache.logging.log4j.osgi.tests.junit.OsgiTestRule;
 import org.junit.Before;
 import org.junit.Rule;
@@ -33,10 +29,6 @@ public abstract class AbstractOsgiTest {
 
     private BundleContext bundleContext;
 
-    private final BundleTestInfo bundleTestInfo;
-
-    private Path here;
-
     @Rule
     public OsgiTestRule osgi = new OsgiTestRule(getFactory());
 
@@ -45,7 +37,6 @@ public abstract class AbstractOsgiTest {
      */
     public AbstractOsgiTest() {
         super();
-        this.bundleTestInfo = new BundleTestInfo();
     }
 
     /**
@@ -54,21 +45,12 @@ public abstract class AbstractOsgiTest {
     @Before
     public void before() {
         bundleContext = osgi.getFramework().getBundleContext();
-        here = Paths.get(".").toAbsolutePath().normalize();
     }
 
     public BundleContext getBundleContext() {
         return bundleContext;
     }
 
-    public BundleTestInfo getBundleTestInfo() {
-        return bundleTestInfo;
-    }
-
     protected abstract FrameworkFactory getFactory();
 
-    public Path getHere() {
-        return here;
-    }
-
 }
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/JULProviderTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/JULProviderTest.java
new file mode 100644
index 0000000000..49e0587072
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/JULProviderTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.osgi.tests;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+import javax.inject.Inject;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.apache.logging.log4j.tojul.JULLoggerContextFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.linkBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class JULProviderTest {
+
+    @Inject
+    private BundleContext context;
+
+    @Configuration
+    public Option[] config() {
+        return options(
+                linkBundle("org.apache.logging.log4j.api"),
+                linkBundle("org.apache.logging.log4j.to-jul"),
+                // required by Pax Exam's logging
+                linkBundle("slf4j.api"),
+                linkBundle("ch.qos.logback.classic"),
+                linkBundle("ch.qos.logback.core"),
+                junitBundles());
+    }
+
+    @Test
+    public void testJulFactoryResolves() {
+        final Optional<Bundle> julBundle = Stream.of(context.getBundles())
+                .filter(b -> "org.apache.logging.log4j.to-jul".equals(b.getSymbolicName()))
+                .findAny();
+        assertTrue(julBundle.isPresent());
+        final LoggerContextFactory factory = LogManager.getFactory();
+        assertEquals(JULLoggerContextFactory.class, factory.getClass());
+    }
+}
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/SLF4JProviderTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/SLF4JProviderTest.java
new file mode 100644
index 0000000000..7f46786978
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/SLF4JProviderTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.osgi.tests;
+
+import java.util.Optional;
+import java.util.stream.Stream;
+import javax.inject.Inject;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.apache.logging.slf4j.SLF4JLoggerContextFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.linkBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class SLF4JProviderTest {
+
+    @Inject
+    private BundleContext context;
+
+    @Configuration
+    public Option[] config() {
+        return options(
+                linkBundle("org.apache.logging.log4j.api"),
+                linkBundle("org.apache.logging.log4j.to-slf4j"),
+                linkBundle("slf4j.api"),
+                linkBundle("ch.qos.logback.classic"),
+                linkBundle("ch.qos.logback.core"),
+                junitBundles());
+    }
+
+    @Test
+    public void testSlf4jFactoryResolves() {
+        final Optional<Bundle> slf4jBundle = Stream.of(context.getBundles())
+                .filter(b -> "org.apache.logging.log4j.to-slf4j".equals(b.getSymbolicName()))
+                .findAny();
+        assertTrue(slf4jBundle.isPresent());
+        final LoggerContextFactory factory = LogManager.getFactory();
+        assertEquals(SLF4JLoggerContextFactory.class, factory.getClass());
+    }
+}
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
deleted file mode 100644
index 02596168d8..0000000000
--- a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
+++ /dev/null
@@ -1,74 +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.osgi.tests.junit;
-
-import java.io.FileReader;
-import java.io.IOException;
-
-import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-
-/**
- * Provides tests with bundle information. Reads the {@code pom.xml} in the current directory to get project settings.
- */
-public class BundleTestInfo {
-
-    private final MavenProject project;
-
-    /**
-     * Constructs a new helper objects and initializes itself.
-     */
-    public BundleTestInfo() {
-        try (final FileReader reader = new FileReader("pom.xml")) {
-            // get a raw POM view, not a fully realized POM object.
-            final Model model = new MavenXpp3Reader().read(reader);
-            this.project = new MavenProject(model);
-        } catch (final IOException | XmlPullParserException e) {
-            throw new IllegalStateException("Could not read pom.xml", e);
-        }
-    }
-
-    public String buildJarFileName(final String artifactId) {
-        return artifactId + "-" + getVersion() + ".jar";
-    }
-
-    /**
-     * Gets the Maven artifact ID.
-     *
-     * @return the Maven artifact ID.
-     */
-    public String getArtifactId() {
-        return project.getArtifactId();
-    }
-
-    /**
-     * Gets the Maven version String.
-     *
-     * @return the Maven version String.
-     */
-    public String getVersion() {
-        return project.getVersion();
-    }
-
-    @Override
-    public String toString() {
-        return "BundleTestInfo [project=" + project + "]";
-    }
-}
diff --git a/log4j-to-jul/pom.xml b/log4j-to-jul/pom.xml
index b3637c19fb..9b4dc81168 100644
--- a/log4j-to-jul/pom.xml
+++ b/log4j-to-jul/pom.xml
@@ -67,7 +67,7 @@
         <artifactId>maven-bundle-plugin</artifactId>
         <configuration>
           <instructions>
-            <Export-Package>org.apache.logging.tojul</Export-Package>
+            <Export-Package>org.apache.logging.log4j.tojul</Export-Package>
           </instructions>
         </configuration>
       </plugin>


[logging-log4j2] 02/02: Removes dependency on log4j-samples-configuration

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

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

commit cf0bf168eb4b0630eb88dfbe15346c88465f51d4
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Thu Jan 19 09:10:32 2023 +0100

    Removes dependency on log4j-samples-configuration
    
    Depending on an unpublished artifact causes problems with `mvn site`.
---
 log4j-osgi/pom.xml                                 |   6 --
 .../log4j/osgi/tests/AbstractLoadBundleTest.java   |  73 +------------
 .../logging/log4j/osgi/tests/CoreOsgiTest.java     | 103 ++++++++++++++++++
 .../log4j/osgi/tests/CustomConfiguration.java      | 115 +++++++++++++++++++++
 .../osgi/tests/CustomConfigurationFactory.java     |  65 ++++++++++++
 log4j-osgi/src/test/resources/log4j2.custom        |   1 +
 .../logging/log4j/plugins/osgi/Activator.java      |   1 +
 7 files changed, 288 insertions(+), 76 deletions(-)

diff --git a/log4j-osgi/pom.xml b/log4j-osgi/pom.xml
index b6b076dbd8..f1b2eec154 100644
--- a/log4j-osgi/pom.xml
+++ b/log4j-osgi/pom.xml
@@ -65,12 +65,6 @@
       <artifactId>log4j-to-slf4j</artifactId>
       <scope>test</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j.samples</groupId>
-      <artifactId>log4j-samples-configuration</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
-    </dependency>
     <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest</artifactId>
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
index a73202ca22..4cbb9c1436 100644
--- a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.logging.log4j.osgi.tests;
 
-import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -26,6 +25,9 @@ import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 /**
  * Tests a basic Log4J 'setup' in an OSGi container.
  */
@@ -49,10 +51,6 @@ public abstract class AbstractLoadBundleTest extends AbstractOsgiTest {
         return installBundle("org.apache.logging.log4j.core");
     }
 
-    private Bundle getDummyBundle() throws BundleException {
-        return installBundle("org.apache.logging.log4j.samples.log4j-samples-configuration");
-    }
-
     private Bundle get12ApiBundle() throws BundleException {
         return installBundle("org.apache.logging.log4j.1.2-api");
     }
@@ -215,71 +213,6 @@ public abstract class AbstractLoadBundleTest extends AbstractOsgiTest {
         api.uninstall();
     }
 
-    /**
-     * Tests LOG4J2-920.
-     */
-    @Test
-    public void testLoadingOfConfigurableCoreClasses() throws BundleException, ReflectiveOperationException {
-
-        final Bundle api = getApiBundle();
-        final Bundle plugins = getPluginsBundle();
-        final Bundle core = getCoreBundle();
-        final Bundle dummy = getDummyBundle();
-
-        start(api, plugins, core, dummy);
-
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        final PrintStream logStream = new PrintStream(baos);
-
-        final PrintStream bakStream = setupStream(api, logStream);
-
-        log(dummy);
-
-        setupStream(api, bakStream);
-
-        // org.apache.logging.log4j.core.osgi.BundleContextSelector cannot be found by org.apache.logging.log4j.api
-        final boolean result = baos.toString().contains("BundleContextSelector cannot be found");
-        Assert.assertFalse("Core class BundleContextSelector cannot be loaded in OSGI setup", result);
-
-        stop(api, plugins, core, dummy);
-        uninstall(api, plugins, core, dummy);
-    }
-
-    /**
-     * Tests the log of a simple message in an OSGi container
-     */
-    @Test
-    public void testSimpleLogInAnOsgiContext() throws BundleException, ReflectiveOperationException {
-
-        final Bundle api = getApiBundle();
-        final Bundle plugins = getPluginsBundle();
-        final Bundle core = getCoreBundle();
-        final Bundle dummy = getDummyBundle();
-
-        start(api, plugins, core, dummy);
-
-        final PrintStream bakStream = System.out;
-        try {
-            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            final PrintStream logStream = new PrintStream(baos);
-            System.setOut(logStream);
-
-            log(dummy);
-
-            final String result = baos.toString().substring(
-                12).trim(); // remove the instant then the spaces at start and end, that are non constant
-            String expected = "[main] ERROR org.apache.logging.log4j.configuration.CustomConfiguration - Test OK";
-            Assert.assertTrue("Incorrect string. Expected string ends with: " + expected + " Actual: " + result,
-                    result.endsWith(expected));
-        } finally {
-            System.setOut(bakStream);
-        }
-
-        stop(api, plugins, core, dummy);
-        uninstall(api, plugins, core, dummy);
-    }
-
-
     /**
      * Tests the loading of the 1.2 Compatibility API bundle, its classes should be loadable from the Core bundle,
      * and the class loader should be the same between a class from core and a class from compat
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CoreOsgiTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CoreOsgiTest.java
new file mode 100644
index 0000000000..309846d25d
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CoreOsgiTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.osgi.tests;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+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.core.config.Configuration;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
+import org.apache.logging.log4j.core.osgi.BundleContextSelector;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.spi.LoggerContextFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+
+import static org.junit.Assert.assertEquals;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.linkBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerClass.class)
+public class CoreOsgiTest {
+
+    @org.ops4j.pax.exam.Configuration
+    public Option[] config() {
+        return options(linkBundle("org.apache.logging.log4j.api"),
+                linkBundle("org.apache.logging.log4j.plugins"),
+                linkBundle("org.apache.logging.log4j.core"),
+                linkBundle("org.apache.logging.log4j.1.2-api").start(false),
+                // required by Pax Exam's logging
+                linkBundle("slf4j.api"),
+                linkBundle("ch.qos.logback.classic"),
+                linkBundle("ch.qos.logback.core"),
+                junitBundles());
+    }
+
+    @Test
+    public void testSimpleLogInAnOsgiContext() {
+        final CustomConfiguration custom = getConfiguration();
+        // Logging
+        final Logger logger = LogManager.getLogger(getClass());
+        logger.info("Hello OSGI from Log4j2!");
+        assertEquals(1, custom.getEvents().size());
+        final LogEvent event = custom.getEvents().get(0);
+        assertEquals("Hello OSGI from Log4j2!", event.getMessage().getFormattedMessage());
+        assertEquals(Level.INFO, event.getLevel());
+        custom.clearEvents();
+    }
+
+    @Test
+    public void testLog4j12InAnOsgiContext() {
+        final CustomConfiguration custom = getConfiguration();
+        // Logging
+        final org.apache.log4j.Logger logger = org.apache.log4j.LogManager.getLogger(getClass());
+        logger.info("Hello OSGI from Log4j 1.2!");
+        assertEquals(1, custom.getEvents().size());
+        final LogEvent event = custom.getEvents().get(0);
+        assertEquals("Hello OSGI from Log4j 1.2!", event.getMessage().getFormattedMessage());
+        assertEquals(Level.INFO, event.getLevel());
+        custom.clearEvents();
+    }
+
+    /**
+     * Tests LOG4J2-920.
+     */
+    @Test
+    public void testBundleContextSelector() {
+        final LoggerContextFactory factory = LogManager.getFactory();
+        assertEquals(Log4jContextFactory.class, factory.getClass());
+        final ContextSelector selector = ((Log4jContextFactory) factory).getSelector();
+        assertEquals(BundleContextSelector.class, selector.getClass());
+    }
+
+    private static CustomConfiguration getConfiguration() {
+        final LoggerContextFactory factory = LogManager.getFactory();
+        assertEquals(Log4jContextFactory.class, factory.getClass());
+        final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+        final Configuration config = ctx.getConfiguration();
+        assertEquals(CustomConfiguration.class, config.getClass());
+        return (CustomConfiguration) config;
+    }
+}
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfiguration.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfiguration.java
new file mode 100644
index 0000000000..8fffcb5355
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfiguration.java
@@ -0,0 +1,115 @@
+/*
+ * 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.osgi.tests;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.ErrorHandler;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.AbstractConfiguration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+
+/**
+ * This Configuration is the same as the DefaultConfiguration but shows how a
+ * custom configuration can be built programmatically
+ */
+public class CustomConfiguration extends AbstractConfiguration {
+
+    /**
+     * The name of the default configuration.
+     */
+    public static final String CONFIG_NAME = "Custom";
+
+    private final ListAppender appender = new ListAppender();
+
+    public CustomConfiguration(final LoggerContext loggerContext) {
+        this(loggerContext, ConfigurationSource.NULL_SOURCE);
+    }
+
+    /**
+     * Constructor to create the default configuration.
+     */
+    public CustomConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
+        super(loggerContext, source);
+        setName(CONFIG_NAME);
+        appender.start();
+        addAppender(appender);
+        final LoggerConfig root = getRootLogger();
+        root.addAppender(appender, null, null);
+        root.setLevel(Level.ALL);
+    }
+
+    @Override
+    protected void doConfigure() {
+    }
+
+    public List<LogEvent> getEvents() {
+        return appender.getEvents();
+    }
+
+    public void clearEvents() {
+        appender.getEvents().clear();
+    }
+
+    private static class ListAppender extends AbstractLifeCycle implements Appender {
+
+        private final List<LogEvent> events = Collections.<LogEvent>synchronizedList(new ArrayList<>());
+
+        @Override
+        public void append(LogEvent event) {
+            events.add(event.toImmutable());
+        }
+
+        @Override
+        public String getName() {
+            return "LIST";
+        }
+
+        @Override
+        public Layout getLayout() {
+            return null;
+        }
+
+        @Override
+        public boolean ignoreExceptions() {
+            return false;
+        }
+
+        @Override
+        public ErrorHandler getHandler() {
+            return null;
+        }
+
+        @Override
+        public void setHandler(ErrorHandler handler) {
+        }
+
+        public List<LogEvent> getEvents() {
+            return events;
+        }
+
+    }
+}
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfigurationFactory.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfigurationFactory.java
new file mode 100644
index 0000000000..e19cd1ec38
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/CustomConfigurationFactory.java
@@ -0,0 +1,65 @@
+/*
+ * 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.osgi.tests;
+
+import java.net.URI;
+
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
+import org.apache.logging.log4j.core.config.Order;
+import org.apache.logging.log4j.plugins.Namespace;
+import org.apache.logging.log4j.plugins.Plugin;
+
+/**
+ * Factory to construct a  CustomConfiguration.
+ */
+@Namespace(ConfigurationFactory.NAMESPACE)
+@Plugin("CustomConfigurationFactory")
+@Order(50)
+public class CustomConfigurationFactory extends ConfigurationFactory {
+
+    /**
+     * Valid file extensions for XML files.
+     */
+    public static final String[] SUFFIXES = new String[] {".custom"};
+
+    /**
+     * Returns the Configuration.
+     * @param source The InputSource.
+     * @return The Configuration.
+     */
+    @Override
+    public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
+        return new CustomConfiguration(loggerContext, source);
+    }
+
+    @Override
+    public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
+        return new CustomConfiguration(loggerContext);
+    }
+
+    /**
+     * Returns the file suffixes for XML files.
+     * @return An array of File extensions.
+     */
+    @Override
+    public String[] getSupportedTypes() {
+        return SUFFIXES;
+    }
+}
diff --git a/log4j-osgi/src/test/resources/log4j2.custom b/log4j-osgi/src/test/resources/log4j2.custom
new file mode 100644
index 0000000000..36435a1e28
--- /dev/null
+++ b/log4j-osgi/src/test/resources/log4j2.custom
@@ -0,0 +1 @@
+# This file enables the CustomConfigurationFactory
\ No newline at end of file
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/osgi/Activator.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/osgi/Activator.java
index b4c615d390..a6098a5f02 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/osgi/Activator.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/osgi/Activator.java
@@ -167,6 +167,7 @@ public final class Activator implements BundleActivator, SynchronousBundleListen
                     loadPlugins(bundle);
                     scanBundleForPlugins(bundle);
                 }
+                break;
 
             case BundleEvent.STOPPING:
                 if (CORE_MODULE_NAME.equals(bundle.getSymbolicName()) && pluginRegistry != null) {