You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2016/11/03 16:57:20 UTC
logging-log4j2 git commit: [LOG4J2-1637] OSGi support is broken in
Log4j2 2.7.
Repository: logging-log4j2
Updated Branches:
refs/heads/master 5968074f2 -> 4a76057d2
[LOG4J2-1637] OSGi support is broken in Log4j2 2.7.
Related to LOG4J2-920.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4a76057d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4a76057d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4a76057d
Branch: refs/heads/master
Commit: 4a76057d22e29f479cd2512084e4e7146fb2913d
Parents: 5968074
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Nov 3 09:57:14 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Nov 3 09:57:14 2016 -0700
----------------------------------------------------------------------
log4j-osgi/pom.xml | 239 ++++++++++++++++++
.../osgi/tests/AbstractLoadBundleTest.java | 243 +++++++++++++++++++
.../tests/equinox/EquinoxLoadApiBundleTest.java | 33 +++
.../tests/felix/FelixLoadApiBundleTest.java | 32 +++
.../log4j/osgi/tests/junit/BundleTestInfo.java | 71 ++++++
.../log4j/osgi/tests/junit/OsgiRule.java | 75 ++++++
pom.xml | 1 +
7 files changed, 694 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/pom.xml
----------------------------------------------------------------------
diff --git a/log4j-osgi/pom.xml b/log4j-osgi/pom.xml
new file mode 100644
index 0000000..e14ce13
--- /dev/null
+++ b/log4j-osgi/pom.xml
@@ -0,0 +1,239 @@
+<?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>2.7.1-SNAPSHOT</version>
+ <relativePath>../</relativePath>
+ </parent>
+ <artifactId>log4j-osgi</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Log4j OSGi</name>
+ <description>The Apache Log4j OSGi tests</description>
+ <properties>
+ <log4jParentDir>${basedir}/..</log4jParentDir>
+ <docLabel>OSGi Documentation</docLabel>
+ <projectDir>/osgi</projectDir>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.spec.javax.jms</groupId>
+ <artifactId>jboss-jms-api_1.1_spec</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.logging.log4j.samples</groupId>
+ <artifactId>log4j-samples-configuration</artifactId>
+ <version>${project.version}</version>
+ </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>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.osgi</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <forkCount>2C</forkCount>
+ <reuseForks>true</reuseForks>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </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.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>org.apache.logging.log4j.osgi</Bundle-SymbolicName>
+ <Import-Package>
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>clirr-maven-plugin</artifactId>
+ <version>${clirr.plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <version>${changes.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <issueLinkTemplate>%URL%/show_bug.cgi?id=%ISSUE%</issueLinkTemplate>
+ <useJql>true</useJql>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <version>${checkstyle.plugin.version}</version>
+ <configuration>
+ <!--<propertiesLocation>${vfs.parent.dir}/checkstyle.properties</propertiesLocation> -->
+ <configLocation>${log4jParentDir}/checkstyle.xml</configLocation>
+ <suppressionsLocation>${log4jParentDir}/checkstyle-suppressions.xml</suppressionsLocation>
+ <enableRulesSummary>false</enableRulesSummary>
+ <propertyExpansion>basedir=${basedir}</propertyExpansion>
+ <propertyExpansion>licensedir=${log4jParentDir}/checkstyle-header.txt</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${javadoc.plugin.version}</version>
+ <configuration>
+ <bottom><![CDATA[<p align="center">Copyright © {inceptionYear}-{currentYear} {organizationName}. All Rights Reserved.<br />
+ Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, the Apache Logging project logo,
+ and the Apache Log4j logo are trademarks of The Apache Software Foundation.</p>]]></bottom>
+ <!-- module link generation is completely broken in the javadoc plugin for a multi-module non-aggregating
+ project -->
+ <detectOfflineLinks>false</detectOfflineLinks>
+ <linksource>true</linksource>
+ <links>
+ <link>http://www.osgi.org/javadoc/r4v43/core/</link>
+ </links>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>javadoc</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.plugin.version}</version>
+ <configuration>
+ <fork>true</fork>
+ <jvmArgs>-Duser.language=en</jvmArgs>
+ <threshold>Normal</threshold>
+ <effort>Default</effort>
+ <excludeFilterFile>${log4jParentDir}/findbugs-exclude-filter.xml</excludeFilterFile>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>${jxr.plugin.version}</version>
+ <reportSets>
+ <reportSet>
+ <id>non-aggregate</id>
+ <reports>
+ <report>jxr</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pmd-plugin</artifactId>
+ <version>${pmd.plugin.version}</version>
+ <configuration>
+ <targetJdk>${maven.compile.target}</targetJdk>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
+
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..2f3e3ae
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/AbstractLoadBundleTest.java
@@ -0,0 +1,243 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+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.OsgiRule;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.launch.FrameworkFactory;
+
+/**
+ * Tests a basic Log4J 'setup' in an OSGi container.
+ */
+public abstract class AbstractLoadBundleTest {
+
+ private BundleContext bundleContext;
+
+ private final BundleTestInfo bundleTestInfo;
+
+ private Path here;
+
+ @Rule
+ public OsgiRule osgi = new OsgiRule(getFactory());
+ /**
+ * Constructs a test for a given bundle.
+ */
+ public AbstractLoadBundleTest() {
+ super();
+ this.bundleTestInfo = new BundleTestInfo();
+ }
+
+ /**
+ * Called before each @Test.
+ */
+ @Before
+ public void before() throws BundleException {
+ bundleContext = osgi.getFramework().getBundleContext();
+
+ here = Paths.get(".").toAbsolutePath().normalize();
+ }
+
+ private Bundle getApiBundle() throws BundleException {
+ final Path apiPath = here.resolveSibling("log4j-api").resolve("target").resolve("log4j-api-" + bundleTestInfo.getVersion() + ".jar");
+ return bundleContext.installBundle(apiPath.toUri().toString());
+ }
+
+
+ private Bundle getCoreBundle() throws BundleException {
+ final Path corePath = here.resolveSibling("log4j-core").resolve("target").resolve("log4j-core-" + bundleTestInfo.getVersion() + ".jar");
+ return bundleContext.installBundle(corePath.toUri().toString());
+ }
+
+ private Bundle getDummyBundle() throws BundleException {
+ final Path dumyPath = here.resolveSibling("log4j-samples").resolve("configuration").resolve("target").resolve("log4j-samples-configuration-" + bundleTestInfo.getVersion() + ".jar");
+ return bundleContext.installBundle(dumyPath.toUri().toString());
+ }
+
+ protected abstract FrameworkFactory getFactory();
+
+ private void log(final Bundle dummy) throws ReflectiveOperationException {
+ // use reflection to log in the context of the dummy bundle
+
+ final Class<?> logManagerClass = dummy.loadClass("org.apache.logging.log4j.LogManager");
+ final Method getLoggerMethod = logManagerClass.getMethod("getLogger", Class.class);
+
+ final Class<?> loggerClass = dummy.loadClass("org.apache.logging.log4j.configuration.CustomConfiguration");
+
+ final Object logger = getLoggerMethod.invoke(null, loggerClass);
+ final Method infoMethod = logger.getClass().getMethod("error", Object.class);
+
+ infoMethod.invoke(logger, "Test OK");
+ }
+
+ private PrintStream setupStream(final Bundle api, final PrintStream newStream) throws ReflectiveOperationException {
+ // use reflection to access the classes internals and in the context of the api bundle
+
+ final Class<?> statusLoggerClass = api.loadClass("org.apache.logging.log4j.status.StatusLogger");
+
+ final Field statusLoggerField = statusLoggerClass.getDeclaredField("STATUS_LOGGER");
+ statusLoggerField.setAccessible(true);
+ final Object statusLoggerFieldValue = statusLoggerField.get(null);
+
+ final Field loggerField = statusLoggerClass.getDeclaredField("logger");
+ loggerField.setAccessible(true);
+ final Object loggerFieldValue = loggerField.get(statusLoggerFieldValue);
+
+ final Class<?> simpleLoggerClass = api.loadClass("org.apache.logging.log4j.simple.SimpleLogger");
+
+ final Field streamField = simpleLoggerClass.getDeclaredField("stream");
+ streamField.setAccessible(true);
+
+ final PrintStream oldStream = (PrintStream) streamField.get(loggerFieldValue);
+
+ streamField.set(loggerFieldValue, newStream);
+
+ return oldStream;
+ }
+
+ private void start(final Bundle api, final Bundle core, final Bundle dummy) throws BundleException {
+ api.start();
+ core.start();
+ dummy.start();
+ }
+
+ private void stop(final Bundle api, final Bundle core, final Bundle dummy) throws BundleException {
+ dummy.stop();
+ core.stop();
+ api.stop();
+ }
+ /**
+ * Tests LOG4J2-1637.
+ */
+ @Test
+ public void testClassNotFoundErrorLogger() throws BundleException {
+
+ final Bundle api = getApiBundle();
+ final Bundle core = getCoreBundle();
+
+ api.start();
+ // fails if LOG4J2-1637 is not fixed
+ try {
+ core.start();
+ }
+ catch (BundleException ex) {
+ final Throwable t = ex.getCause();
+ if (t != null)
+ {
+ final Throwable t2 = t.getCause();
+ if (t2 != null)
+ {
+ final String cause = t2.toString();
+ boolean result = cause.equals("java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger") // Equinox
+ || cause.equals("java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger not found by org.apache.logging.log4j.core [2]"); // Felix
+ Assert.assertFalse("org.apache.logging.log4j package is not properly imported in org.apache.logging.log4j.core bundle, check that the package is exported from api and is not split between api and core", result);
+ }
+ throw ex; // rethrow if the cause of the exception is something else
+ }
+ }
+
+ core.stop();
+ api.stop();
+
+ core.uninstall();
+ api.uninstall();
+ }
+
+ /**
+ * Tests LOG4J2-920.
+ */
+ @Test
+ @Ignore("org.osgi.framework.BundleException: The bundle \"org.apache.logging.log4j.core_2.7.1.SNAPSHOT [2]\" could not be resolved. Reason: Missing Constraint: Import-Package: javax.jms; version=\"[1.1.0,2.0.0)\"")
+ public void testMissingImportOfCoreOsgiPackage() throws BundleException, ReflectiveOperationException {
+
+ final Bundle api = getApiBundle();
+ final Bundle core = getCoreBundle();
+ final Bundle dummy = getDummyBundle();
+
+ start(api, core, dummy);
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintStream logStream = new PrintStream(baos);
+
+ final PrintStream bakStream = setupStream(api, logStream);
+
+ log(dummy);
+
+ setupStream(api, bakStream);
+
+ final boolean result = baos.toString().contains(
+ "ERROR StatusLogger Unable to create context org.apache.logging.log4j.core.osgi.BundleContextSelector");
+ Assert.assertFalse(
+ "org.apache.logging.log4j.core.osgi;resolution:=optional is missing in Import-Package in the POM", result);
+
+ stop(api, core, dummy);
+ uninstall(api, core, dummy);
+ }
+
+ /**
+ * Tests the log of a simple message in an OSGi container
+ */
+ @Test
+ @Ignore("org.osgi.framework.BundleException: The bundle \"org.apache.logging.log4j.core_2.7.1.SNAPSHOT [2]\" could not be resolved. Reason: Missing Constraint: Import-Package: javax.jms; version=\"[1.1.0,2.0.0)\"")
+ public void testSimpleLogInAnOsgiContext() throws BundleException, ReflectiveOperationException {
+
+ final Bundle api = getApiBundle();
+ final Bundle core = getCoreBundle();
+ final Bundle dummy = getDummyBundle();
+
+ start(api, 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
+ Assert.assertEquals("[main] ERROR org.apache.logging.log4j.configuration.CustomConfiguration - Test OK",
+ result);
+ } finally {
+ System.setOut(bakStream);
+ }
+
+ stop(api, core, dummy);
+ uninstall(api, core, dummy);
+ }
+
+ private void uninstall(final Bundle api, final Bundle core, final Bundle dummy) throws BundleException {
+ dummy.uninstall();
+ core.uninstall();
+ api.uninstall();
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/equinox/EquinoxLoadApiBundleTest.java
----------------------------------------------------------------------
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/equinox/EquinoxLoadApiBundleTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/equinox/EquinoxLoadApiBundleTest.java
new file mode 100644
index 0000000..10e7a06
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/equinox/EquinoxLoadApiBundleTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.equinox;
+
+import org.apache.logging.log4j.osgi.tests.AbstractLoadBundleTest;
+import org.eclipse.osgi.launch.EquinoxFactory;
+import org.osgi.framework.launch.FrameworkFactory;
+
+/**
+ * Tests loading the Core bundle into an Eclipse Equinox OSGi container.
+ */
+public class EquinoxLoadApiBundleTest extends AbstractLoadBundleTest {
+
+ @Override
+ protected FrameworkFactory getFactory() {
+ return new EquinoxFactory();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/felix/FelixLoadApiBundleTest.java
----------------------------------------------------------------------
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/felix/FelixLoadApiBundleTest.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/felix/FelixLoadApiBundleTest.java
new file mode 100644
index 0000000..0072486
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/felix/FelixLoadApiBundleTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.osgi.tests.felix;
+
+import org.apache.logging.log4j.osgi.tests.AbstractLoadBundleTest;
+import org.osgi.framework.launch.FrameworkFactory;
+
+/**
+ * Tests loading the Core bundle into an Apache Felix OSGi container.
+ */
+public class FelixLoadApiBundleTest extends AbstractLoadBundleTest {
+
+ @Override
+ protected FrameworkFactory getFactory() {
+ return new org.apache.felix.framework.FrameworkFactory();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..9a4f8a8
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/BundleTestInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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);
+ }
+ }
+
+ /**
+ * 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 + "]";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/OsgiRule.java
----------------------------------------------------------------------
diff --git a/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/OsgiRule.java b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/OsgiRule.java
new file mode 100644
index 0000000..9821c3b
--- /dev/null
+++ b/log4j-osgi/src/test/java/org/apache/logging/log4j/osgi/tests/junit/OsgiRule.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.osgi.tests.junit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.rules.ExternalResource;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.launch.Framework;
+import org.osgi.framework.launch.FrameworkFactory;
+
+/**
+ * JUnit rule to initialize and shutdown an OSGi framework.
+ */
+public class OsgiRule extends ExternalResource {
+
+ private final FrameworkFactory factory;
+ private Framework framework;
+
+ public OsgiRule(final FrameworkFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ protected void after() {
+ if (framework != null) {
+ try {
+ framework.stop();
+ } catch (final BundleException e) {
+ throw new RuntimeException(e);
+ } finally {
+ framework = null;
+ }
+ }
+ }
+
+ @Override
+ protected void before() throws Throwable {
+ final Map<String, String> configMap = new HashMap<>(2);
+ // Cleans framework before first init. Subsequent init invocations do not clean framework.
+ configMap.put("org.osgi.framework.storage.clean", "onFirstInit");
+ configMap.put("felix.log.level", "4");
+ configMap.put("eclipse.log.level", "ALL");
+ // Delegates loading of endorsed libraries to JVM classloader
+ // config.put("org.osgi.framework.bootdelegation", "javax.*,org.w3c.*,org.xml.*");
+ framework = factory.newFramework(configMap);
+ framework.init();
+ framework.start();
+ }
+
+ public Framework getFramework() {
+ return framework;
+ }
+
+ @Override
+ public String toString() {
+ return "OsgiRule [factory=" + factory + ", framework=" + framework + "]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4a76057d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 385f8ad..82a001d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1250,6 +1250,7 @@
<module>log4j-taglib</module>
<module>log4j-jmx-gui</module>
<module>log4j-samples</module>
+ <module>log4j-osgi</module>
<module>log4j-bom</module>
<module>log4j-nosql</module>
<module>log4j-web</module>