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:20 UTC
[logging-log4j2] 01/02: [LOG4J2-3546] Fix SLF4J and JUL implementation in OSGi environment
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>