Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions log4j-osgi-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@
<name>Apache Log4j OSGi tests</name>
<description>The Apache Log4j OSGi tests</description>
<properties>
<docLabel>OSGi Documentation</docLabel>
<projectDir>/osgi</projectDir>
<module.name>org.apache.logging.log4j.osgi</module.name>
<bnd.baseline.skip>true</bnd.baseline.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
<sign.skip>true</sign.skip>

<spotbugs.skip>true</spotbugs.skip>
<spifly.version>1.3.7</spifly.version>
</properties>
<dependencies>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,60 @@
*/
package org.apache.logging.log4j.osgi.tests;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static org.junit.Assert.assertEquals;

import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.function.ThrowingConsumer;
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 extends AbstractOsgiTest {
abstract class AbstractLoadBundleTest {

private BundleContext bundleContext;

@Rule
public final OsgiRule osgi;

AbstractLoadBundleTest(final FrameworkFactory frameworkFactory) {
this.osgi = new OsgiRule(frameworkFactory);
}

@Before
public void before() {
bundleContext = osgi.getFramework().getBundleContext();
}

private Bundle installBundle(final 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);
return bundleContext.installBundle(url);
}

private List<Bundle> startApacheSpiFly() throws BundleException {
final List<Bundle> bundles = List.of(
installBundle("org.apache.aries.spifly.dynamic.bundle"),
installBundle("org.objectweb.asm"),
installBundle("org.objectweb.asm.commons"),
installBundle("org.objectweb.asm.tree"),
installBundle("org.objectweb.asm.tree.analysis"),
installBundle("org.objectweb.asm.util"));
bundles.get(0).start();
return bundles;
}

private void uninstall(final List<Bundle> bundles) throws BundleException {
for (Bundle bundle : bundles) {
bundle.uninstall();
}
}

private Bundle getApiBundle() throws BundleException {
Expand All @@ -51,67 +88,8 @@ private Bundle get12ApiBundle() throws BundleException {
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

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 errorMethod = logger.getClass().getMethod("error", Object.class);

errorMethod.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 plugins, final Bundle core, final Bundle dummy)
throws BundleException {
api.start();
plugins.start();
core.start();
dummy.start();
}

private void stop(final Bundle api, final Bundle plugins, final Bundle core, final Bundle dummy)
throws BundleException {
dummy.stop();
core.stop();
plugins.stop();
api.stop();
}

private void uninstall(final Bundle api, final Bundle plugins, final Bundle core, final Bundle dummy)
throws BundleException {
dummy.uninstall();
core.uninstall();
plugins.uninstall();
api.uninstall();
private Bundle getApiTestsBundle() throws BundleException {
return installBundle("org.apache.logging.log4j.api.test");
}

/**
Expand All @@ -120,6 +98,7 @@ private void uninstall(final Bundle api, final Bundle plugins, final Bundle core
@Test
public void testApiCoreStartStopStartStop() throws BundleException {

final List<Bundle> spiFly = startApacheSpiFly();
final Bundle api = getApiBundle();
final Bundle plugins = getPluginsBundle();
final Bundle core = getCoreBundle();
Expand All @@ -128,45 +107,16 @@ public void testApiCoreStartStopStartStop() throws BundleException {
Assert.assertEquals("plugins is not in INSTALLED state", Bundle.INSTALLED, plugins.getState());
Assert.assertEquals("core is not in INSTALLED state", Bundle.INSTALLED, core.getState());

api.start();
plugins.start();
core.start();

Assert.assertEquals("api is not in ACTIVE state", Bundle.ACTIVE, api.getState());
Assert.assertEquals("plugins is not in ACTIVE state", Bundle.ACTIVE, plugins.getState());
Assert.assertEquals("core is not in ACTIVE state", Bundle.ACTIVE, core.getState());
// 1st start-stop
doOnBundlesAndVerifyState(Bundle::start, Bundle.ACTIVE, api, plugins, core);
doOnBundlesAndVerifyState(Bundle::stop, Bundle.RESOLVED, core, plugins, api);

core.stop();
plugins.stop();
api.stop();
// 2nd start-stop
doOnBundlesAndVerifyState(Bundle::start, Bundle.ACTIVE, api, plugins, core);
doOnBundlesAndVerifyState(Bundle::stop, Bundle.RESOLVED, core, plugins, api);

Assert.assertEquals("api is not in RESOLVED state", Bundle.RESOLVED, api.getState());
Assert.assertEquals("plugins is not in RESOLVED state", Bundle.RESOLVED, plugins.getState());
Assert.assertEquals("core is not in RESOLVED state", Bundle.RESOLVED, core.getState());

api.start();
plugins.start();
core.start();

Assert.assertEquals("api is not in ACTIVE state", Bundle.ACTIVE, api.getState());
Assert.assertEquals("plugins is not in ACTIVE state", Bundle.ACTIVE, plugins.getState());
Assert.assertEquals("core is not in ACTIVE state", Bundle.ACTIVE, core.getState());

core.stop();
plugins.stop();
api.stop();

Assert.assertEquals("api is not in RESOLVED state", Bundle.RESOLVED, api.getState());
Assert.assertEquals("plugins is not in RESOLVED state", Bundle.RESOLVED, plugins.getState());
Assert.assertEquals("core is not in RESOLVED state", Bundle.RESOLVED, core.getState());

core.uninstall();
plugins.uninstall();
api.uninstall();

Assert.assertEquals("api is not in UNINSTALLED state", Bundle.UNINSTALLED, api.getState());
Assert.assertEquals("plugins is not in UNINSTALLED state", Bundle.UNINSTALLED, plugins.getState());
Assert.assertEquals("core is not in UNINSTALLED state", Bundle.UNINSTALLED, core.getState());
doOnBundlesAndVerifyState(Bundle::uninstall, Bundle.UNINSTALLED, core, plugins, api);
uninstall(spiFly);
}

/**
Expand All @@ -175,44 +125,34 @@ public void testApiCoreStartStopStartStop() throws BundleException {
@Test
public void testClassNotFoundErrorLogger() throws BundleException {

final List<Bundle> spiFly = startApacheSpiFly();
final Bundle api = getApiBundle();
final Bundle plugins = getPluginsBundle();
final Bundle core = getCoreBundle();

api.start();
plugins.start();
doOnBundlesAndVerifyState(Bundle::start, Bundle.ACTIVE, api, plugins);
// fails if LOG4J2-1637 is not fixed
try {
core.start();
} catch (final BundleException ex) {
boolean shouldRethrow = true;
final Throwable t = ex.getCause();
if (t != null) {
final Throwable t2 = t.getCause();
if (t2 != null) {
final String cause = t2.toString();
final 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);
shouldRethrow = !result;
} catch (final BundleException error0) {
boolean log4jClassNotFound = false;
final Throwable error1 = error0.getCause();
if (error1 != null) {
final Throwable error2 = error1.getCause();
if (error2 != null) {
log4jClassNotFound = error2.toString()
.startsWith("java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger");
}
}
if (shouldRethrow) {
throw ex; // rethrow if the cause of the exception is something else
if (!log4jClassNotFound) {
throw error0;
}
}
assertEquals(String.format("`%s` bundle state mismatch", core), Bundle.ACTIVE, core.getState());

core.stop();
plugins.stop();
api.stop();

core.uninstall();
plugins.uninstall();
api.uninstall();
doOnBundlesAndVerifyState(Bundle::stop, Bundle.RESOLVED, core, plugins, api);
doOnBundlesAndVerifyState(Bundle::uninstall, Bundle.UNINSTALLED, core, plugins, api);
uninstall(spiFly);
}

/**
Expand All @@ -222,14 +162,13 @@ public void testClassNotFoundErrorLogger() throws BundleException {
@Test
public void testLog4J12Fragement() throws BundleException, ReflectiveOperationException {

final List<Bundle> spiFly = startApacheSpiFly();
final Bundle api = getApiBundle();
final Bundle plugins = getPluginsBundle();
final Bundle core = getCoreBundle();
final Bundle compat = get12ApiBundle();

api.start();
plugins.start();
core.start();
doOnBundlesAndVerifyState(Bundle::start, Bundle.ACTIVE, api, plugins, core);

final Class<?> coreClassFromCore = core.loadClass("org.apache.logging.log4j.core.Core");
final Class<?> levelClassFrom12API = core.loadClass("org.apache.log4j.Level");
Expand All @@ -244,9 +183,21 @@ public void testLog4J12Fragement() throws BundleException, ReflectiveOperationEx
levelClassFrom12API.getClassLoader(),
levelClassFromAPI.getClassLoader());

core.stop();
api.stop();
doOnBundlesAndVerifyState(Bundle::stop, Bundle.RESOLVED, core, plugins, api);
doOnBundlesAndVerifyState(Bundle::uninstall, Bundle.UNINSTALLED, compat, core, plugins, api);
uninstall(spiFly);
}

uninstall(api, plugins, core, compat);
private static void doOnBundlesAndVerifyState(
final ThrowingConsumer<Bundle> operation, final int expectedState, final Bundle... bundles) {
for (final Bundle bundle : bundles) {
try {
operation.accept(bundle);
} catch (final Throwable error) {
final String message = String.format("operation failure for bundle `%s`", bundle);
throw new RuntimeException(message, error);
}
assertEquals(String.format("`%s` bundle state mismatch", bundle), expectedState, bundle.getState());
}
}
}

This file was deleted.

Loading