1616 */
1717package org .apache .logging .log4j .osgi .tests ;
1818
19- import java . io . PrintStream ;
20- import java . lang . reflect . Field ;
21- import java .lang . reflect . Method ;
19+ import static org . junit . Assert . assertEquals ;
20+
21+ import java .util . List ;
2222import org .junit .Assert ;
23+ import org .junit .Before ;
24+ import org .junit .Rule ;
2325import org .junit .Test ;
26+ import org .junit .jupiter .api .function .ThrowingConsumer ;
2427import org .osgi .framework .Bundle ;
28+ import org .osgi .framework .BundleContext ;
2529import org .osgi .framework .BundleException ;
30+ import org .osgi .framework .launch .FrameworkFactory ;
2631
2732/**
2833 * Tests a basic Log4J 'setup' in an OSGi container.
2934 */
30- public abstract class AbstractLoadBundleTest extends AbstractOsgiTest {
35+ abstract class AbstractLoadBundleTest {
36+
37+ private BundleContext bundleContext ;
38+
39+ @ Rule
40+ public final OsgiRule osgi ;
41+
42+ AbstractLoadBundleTest (final FrameworkFactory frameworkFactory ) {
43+ this .osgi = new OsgiRule (frameworkFactory );
44+ }
45+
46+ @ Before
47+ public void before () {
48+ bundleContext = osgi .getFramework ().getBundleContext ();
49+ }
3150
3251 private Bundle installBundle (final String symbolicName ) throws BundleException {
3352 // The links are generated by 'exam-maven-plugin'
3453 final String url = String .format ("link:classpath:%s.link" , symbolicName );
35- return getBundleContext ().installBundle (url );
54+ return bundleContext .installBundle (url );
55+ }
56+
57+ private List <Bundle > startApacheSpiFly () throws BundleException {
58+ final List <Bundle > bundles = List .of (
59+ installBundle ("org.apache.aries.spifly.dynamic.bundle" ),
60+ installBundle ("org.objectweb.asm" ),
61+ installBundle ("org.objectweb.asm.commons" ),
62+ installBundle ("org.objectweb.asm.tree" ),
63+ installBundle ("org.objectweb.asm.tree.analysis" ),
64+ installBundle ("org.objectweb.asm.util" ));
65+ bundles .get (0 ).start ();
66+ return bundles ;
67+ }
68+
69+ private void uninstall (final List <Bundle > bundles ) throws BundleException {
70+ for (Bundle bundle : bundles ) {
71+ bundle .uninstall ();
72+ }
3673 }
3774
3875 private Bundle getApiBundle () throws BundleException {
@@ -51,67 +88,8 @@ private Bundle get12ApiBundle() throws BundleException {
5188 return installBundle ("org.apache.logging.log4j.1.2.api" );
5289 }
5390
54- private void log (final Bundle dummy ) throws ReflectiveOperationException {
55- // use reflection to log in the context of the dummy bundle
56-
57- final Class <?> logManagerClass = dummy .loadClass ("org.apache.logging.log4j.LogManager" );
58- final Method getLoggerMethod = logManagerClass .getMethod ("getLogger" , Class .class );
59-
60- final Class <?> loggerClass = dummy .loadClass ("org.apache.logging.log4j.configuration.CustomConfiguration" );
61-
62- final Object logger = getLoggerMethod .invoke (null , loggerClass );
63- final Method errorMethod = logger .getClass ().getMethod ("error" , Object .class );
64-
65- errorMethod .invoke (logger , "Test OK" );
66- }
67-
68- private PrintStream setupStream (final Bundle api , final PrintStream newStream ) throws ReflectiveOperationException {
69- // use reflection to access the classes internals and in the context of the api bundle
70-
71- final Class <?> statusLoggerClass = api .loadClass ("org.apache.logging.log4j.status.StatusLogger" );
72-
73- final Field statusLoggerField = statusLoggerClass .getDeclaredField ("STATUS_LOGGER" );
74- statusLoggerField .setAccessible (true );
75- final Object statusLoggerFieldValue = statusLoggerField .get (null );
76-
77- final Field loggerField = statusLoggerClass .getDeclaredField ("logger" );
78- loggerField .setAccessible (true );
79- final Object loggerFieldValue = loggerField .get (statusLoggerFieldValue );
80-
81- final Class <?> simpleLoggerClass = api .loadClass ("org.apache.logging.log4j.simple.SimpleLogger" );
82-
83- final Field streamField = simpleLoggerClass .getDeclaredField ("stream" );
84- streamField .setAccessible (true );
85-
86- final PrintStream oldStream = (PrintStream ) streamField .get (loggerFieldValue );
87-
88- streamField .set (loggerFieldValue , newStream );
89-
90- return oldStream ;
91- }
92-
93- private void start (final Bundle api , final Bundle plugins , final Bundle core , final Bundle dummy )
94- throws BundleException {
95- api .start ();
96- plugins .start ();
97- core .start ();
98- dummy .start ();
99- }
100-
101- private void stop (final Bundle api , final Bundle plugins , final Bundle core , final Bundle dummy )
102- throws BundleException {
103- dummy .stop ();
104- core .stop ();
105- plugins .stop ();
106- api .stop ();
107- }
108-
109- private void uninstall (final Bundle api , final Bundle plugins , final Bundle core , final Bundle dummy )
110- throws BundleException {
111- dummy .uninstall ();
112- core .uninstall ();
113- plugins .uninstall ();
114- api .uninstall ();
91+ private Bundle getApiTestsBundle () throws BundleException {
92+ return installBundle ("org.apache.logging.log4j.api.test" );
11593 }
11694
11795 /**
@@ -120,6 +98,7 @@ private void uninstall(final Bundle api, final Bundle plugins, final Bundle core
12098 @ Test
12199 public void testApiCoreStartStopStartStop () throws BundleException {
122100
101+ final List <Bundle > spiFly = startApacheSpiFly ();
123102 final Bundle api = getApiBundle ();
124103 final Bundle plugins = getPluginsBundle ();
125104 final Bundle core = getCoreBundle ();
@@ -128,45 +107,16 @@ public void testApiCoreStartStopStartStop() throws BundleException {
128107 Assert .assertEquals ("plugins is not in INSTALLED state" , Bundle .INSTALLED , plugins .getState ());
129108 Assert .assertEquals ("core is not in INSTALLED state" , Bundle .INSTALLED , core .getState ());
130109
131- api .start ();
132- plugins .start ();
133- core .start ();
134-
135- Assert .assertEquals ("api is not in ACTIVE state" , Bundle .ACTIVE , api .getState ());
136- Assert .assertEquals ("plugins is not in ACTIVE state" , Bundle .ACTIVE , plugins .getState ());
137- Assert .assertEquals ("core is not in ACTIVE state" , Bundle .ACTIVE , core .getState ());
110+ // 1st start-stop
111+ doOnBundlesAndVerifyState (Bundle ::start , Bundle .ACTIVE , api , plugins , core );
112+ doOnBundlesAndVerifyState (Bundle ::stop , Bundle .RESOLVED , core , plugins , api );
138113
139- core . stop ();
140- plugins . stop ( );
141- api . stop ( );
114+ // 2nd start- stop
115+ doOnBundlesAndVerifyState ( Bundle :: start , Bundle . ACTIVE , api , plugins , core );
116+ doOnBundlesAndVerifyState ( Bundle :: stop , Bundle . RESOLVED , core , plugins , api );
142117
143- Assert .assertEquals ("api is not in RESOLVED state" , Bundle .RESOLVED , api .getState ());
144- Assert .assertEquals ("plugins is not in RESOLVED state" , Bundle .RESOLVED , plugins .getState ());
145- Assert .assertEquals ("core is not in RESOLVED state" , Bundle .RESOLVED , core .getState ());
146-
147- api .start ();
148- plugins .start ();
149- core .start ();
150-
151- Assert .assertEquals ("api is not in ACTIVE state" , Bundle .ACTIVE , api .getState ());
152- Assert .assertEquals ("plugins is not in ACTIVE state" , Bundle .ACTIVE , plugins .getState ());
153- Assert .assertEquals ("core is not in ACTIVE state" , Bundle .ACTIVE , core .getState ());
154-
155- core .stop ();
156- plugins .stop ();
157- api .stop ();
158-
159- Assert .assertEquals ("api is not in RESOLVED state" , Bundle .RESOLVED , api .getState ());
160- Assert .assertEquals ("plugins is not in RESOLVED state" , Bundle .RESOLVED , plugins .getState ());
161- Assert .assertEquals ("core is not in RESOLVED state" , Bundle .RESOLVED , core .getState ());
162-
163- core .uninstall ();
164- plugins .uninstall ();
165- api .uninstall ();
166-
167- Assert .assertEquals ("api is not in UNINSTALLED state" , Bundle .UNINSTALLED , api .getState ());
168- Assert .assertEquals ("plugins is not in UNINSTALLED state" , Bundle .UNINSTALLED , plugins .getState ());
169- Assert .assertEquals ("core is not in UNINSTALLED state" , Bundle .UNINSTALLED , core .getState ());
118+ doOnBundlesAndVerifyState (Bundle ::uninstall , Bundle .UNINSTALLED , core , plugins , api );
119+ uninstall (spiFly );
170120 }
171121
172122 /**
@@ -175,44 +125,34 @@ public void testApiCoreStartStopStartStop() throws BundleException {
175125 @ Test
176126 public void testClassNotFoundErrorLogger () throws BundleException {
177127
128+ final List <Bundle > spiFly = startApacheSpiFly ();
178129 final Bundle api = getApiBundle ();
179130 final Bundle plugins = getPluginsBundle ();
180131 final Bundle core = getCoreBundle ();
181132
182- api .start ();
183- plugins .start ();
133+ doOnBundlesAndVerifyState (Bundle ::start , Bundle .ACTIVE , api , plugins );
184134 // fails if LOG4J2-1637 is not fixed
185135 try {
186136 core .start ();
187- } catch (final BundleException ex ) {
188- boolean shouldRethrow = true ;
189- final Throwable t = ex .getCause ();
190- if (t != null ) {
191- final Throwable t2 = t .getCause ();
192- if (t2 != null ) {
193- final String cause = t2 .toString ();
194- final boolean result =
195- cause .equals ("java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger" ) // Equinox
196- || cause .equals (
197- "java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger not found by org.apache.logging.log4j.core [2]" ); // Felix
198- Assert .assertFalse (
199- "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" ,
200- result );
201- shouldRethrow = !result ;
137+ } catch (final BundleException error0 ) {
138+ boolean log4jClassNotFound = false ;
139+ final Throwable error1 = error0 .getCause ();
140+ if (error1 != null ) {
141+ final Throwable error2 = error1 .getCause ();
142+ if (error2 != null ) {
143+ log4jClassNotFound = error2 .toString ()
144+ .startsWith ("java.lang.ClassNotFoundException: org.apache.logging.log4j.Logger" );
202145 }
203146 }
204- if (shouldRethrow ) {
205- throw ex ; // rethrow if the cause of the exception is something else
147+ if (! log4jClassNotFound ) {
148+ throw error0 ;
206149 }
207150 }
151+ assertEquals (String .format ("`%s` bundle state mismatch" , core ), Bundle .ACTIVE , core .getState ());
208152
209- core .stop ();
210- plugins .stop ();
211- api .stop ();
212-
213- core .uninstall ();
214- plugins .uninstall ();
215- api .uninstall ();
153+ doOnBundlesAndVerifyState (Bundle ::stop , Bundle .RESOLVED , core , plugins , api );
154+ doOnBundlesAndVerifyState (Bundle ::uninstall , Bundle .UNINSTALLED , core , plugins , api );
155+ uninstall (spiFly );
216156 }
217157
218158 /**
@@ -222,14 +162,13 @@ public void testClassNotFoundErrorLogger() throws BundleException {
222162 @ Test
223163 public void testLog4J12Fragement () throws BundleException , ReflectiveOperationException {
224164
165+ final List <Bundle > spiFly = startApacheSpiFly ();
225166 final Bundle api = getApiBundle ();
226167 final Bundle plugins = getPluginsBundle ();
227168 final Bundle core = getCoreBundle ();
228169 final Bundle compat = get12ApiBundle ();
229170
230- api .start ();
231- plugins .start ();
232- core .start ();
171+ doOnBundlesAndVerifyState (Bundle ::start , Bundle .ACTIVE , api , plugins , core );
233172
234173 final Class <?> coreClassFromCore = core .loadClass ("org.apache.logging.log4j.core.Core" );
235174 final Class <?> levelClassFrom12API = core .loadClass ("org.apache.log4j.Level" );
@@ -244,9 +183,21 @@ public void testLog4J12Fragement() throws BundleException, ReflectiveOperationEx
244183 levelClassFrom12API .getClassLoader (),
245184 levelClassFromAPI .getClassLoader ());
246185
247- core .stop ();
248- api .stop ();
186+ doOnBundlesAndVerifyState (Bundle ::stop , Bundle .RESOLVED , core , plugins , api );
187+ doOnBundlesAndVerifyState (Bundle ::uninstall , Bundle .UNINSTALLED , compat , core , plugins , api );
188+ uninstall (spiFly );
189+ }
249190
250- uninstall (api , plugins , core , compat );
191+ private static void doOnBundlesAndVerifyState (
192+ final ThrowingConsumer <Bundle > operation , final int expectedState , final Bundle ... bundles ) {
193+ for (final Bundle bundle : bundles ) {
194+ try {
195+ operation .accept (bundle );
196+ } catch (final Throwable error ) {
197+ final String message = String .format ("operation failure for bundle `%s`" , bundle );
198+ throw new RuntimeException (message , error );
199+ }
200+ assertEquals (String .format ("`%s` bundle state mismatch" , bundle ), expectedState , bundle .getState ());
201+ }
251202 }
252203}
0 commit comments