1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.osgi;
19
20 import java.util.Collection;
21 import java.util.Hashtable;
22 import java.util.concurrent.ConcurrentLinkedDeque;
23 import java.util.concurrent.atomic.AtomicReference;
24
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
27 import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry;
28 import org.apache.logging.log4j.core.impl.Log4jProvider;
29 import org.apache.logging.log4j.core.impl.ThreadContextDataInjector;
30 import org.apache.logging.log4j.core.impl.ThreadContextDataProvider;
31 import org.apache.logging.log4j.core.util.Constants;
32 import org.apache.logging.log4j.core.util.ContextDataProvider;
33 import org.apache.logging.log4j.spi.Provider;
34 import org.apache.logging.log4j.status.StatusLogger;
35 import org.apache.logging.log4j.util.PropertiesUtil;
36 import org.osgi.framework.Bundle;
37 import org.osgi.framework.BundleActivator;
38 import org.osgi.framework.BundleContext;
39 import org.osgi.framework.BundleEvent;
40 import org.osgi.framework.InvalidSyntaxException;
41 import org.osgi.framework.ServiceReference;
42 import org.osgi.framework.ServiceRegistration;
43 import org.osgi.framework.SynchronousBundleListener;
44 import org.osgi.framework.wiring.BundleWiring;
45
46
47
48
49 public final class Activator implements BundleActivator, SynchronousBundleListener {
50
51 private static final Logger LOGGER = StatusLogger.getLogger();
52
53 private final AtomicReference<BundleContext> contextRef = new AtomicReference<>();
54
55 ServiceRegistration provideRegistration = null;
56 ServiceRegistration contextDataRegistration = null;
57
58 @Override
59 public void start(final BundleContext context) throws Exception {
60 final Provider provider = new Log4jProvider();
61 final Hashtable<String, String> props = new Hashtable<>();
62 props.put("APIVersion", "2.60");
63 final ContextDataProvider threadContextProvider = new ThreadContextDataProvider();
64 provideRegistration = context.registerService(Provider.class.getName(), provider, props);
65 contextDataRegistration = context.registerService(ContextDataProvider.class.getName(), threadContextProvider,
66 null);
67 loadContextProviders(context);
68
69 if (PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR) == null) {
70 System.setProperty(Constants.LOG4J_CONTEXT_SELECTOR, BundleContextSelector.class.getName());
71 }
72 if (this.contextRef.compareAndSet(null, context)) {
73 context.addBundleListener(this);
74
75 scanInstalledBundlesForPlugins(context);
76 }
77 }
78
79 private static void scanInstalledBundlesForPlugins(final BundleContext context) {
80 final Bundle[] bundles = context.getBundles();
81 for (final Bundle bundle : bundles) {
82
83 scanBundleForPlugins(bundle);
84 }
85 }
86
87 private static void scanBundleForPlugins(final Bundle bundle) {
88 final long bundleId = bundle.getBundleId();
89
90 if (bundle.getState() == Bundle.ACTIVE && bundleId != 0) {
91 LOGGER.trace("Scanning bundle [{}, id=%d] for plugins.", bundle.getSymbolicName(), bundleId);
92 PluginRegistry.getInstance().loadFromBundle(bundleId,
93 bundle.adapt(BundleWiring.class).getClassLoader());
94 }
95 }
96
97 private static void loadContextProviders(final BundleContext bundleContext) {
98 try {
99 final Collection<ServiceReference<ContextDataProvider>> serviceReferences =
100 bundleContext.getServiceReferences(ContextDataProvider.class, null);
101 for (final ServiceReference<ContextDataProvider> serviceReference : serviceReferences) {
102 final ContextDataProvider provider = bundleContext.getService(serviceReference);
103 ThreadContextDataInjector.contextDataProviders.add(provider);
104 }
105 } catch (final InvalidSyntaxException ex) {
106 LOGGER.error("Error accessing context data provider", ex);
107 }
108 }
109
110 private static void stopBundlePlugins(final Bundle bundle) {
111 LOGGER.trace("Stopping bundle [{}] plugins.", bundle.getSymbolicName());
112
113 PluginRegistry.getInstance().clearBundlePlugins(bundle.getBundleId());
114 }
115
116 @Override
117 public void stop(final BundleContext context) throws Exception {
118 provideRegistration.unregister();
119 contextDataRegistration.unregister();
120 this.contextRef.compareAndSet(context, null);
121 LogManager.shutdown();
122 }
123
124 @Override
125 public void bundleChanged(final BundleEvent event) {
126 switch (event.getType()) {
127
128 case BundleEvent.STARTED:
129 scanBundleForPlugins(event.getBundle());
130 break;
131
132 case BundleEvent.STOPPING:
133 stopBundlePlugins(event.getBundle());
134 break;
135
136 default:
137 break;
138 }
139 }
140 }