1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.util;
18
19 import java.net.URL;
20 import java.security.Permission;
21 import java.util.Collection;
22 import java.util.List;
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.spi.LoggerContextFactory;
26 import org.apache.logging.log4j.spi.Provider;
27 import org.apache.logging.log4j.status.StatusLogger;
28 import org.osgi.framework.AdaptPermission;
29 import org.osgi.framework.AdminPermission;
30 import org.osgi.framework.Bundle;
31 import org.osgi.framework.BundleActivator;
32 import org.osgi.framework.BundleContext;
33 import org.osgi.framework.BundleEvent;
34 import org.osgi.framework.InvalidSyntaxException;
35 import org.osgi.framework.ServiceReference;
36 import org.osgi.framework.SynchronousBundleListener;
37 import org.osgi.framework.wiring.BundleWire;
38 import org.osgi.framework.wiring.BundleWiring;
39
40
41
42
43
44
45
46
47 public class Activator implements BundleActivator, SynchronousBundleListener {
48
49 private static final SecurityManager SECURITY_MANAGER = System.getSecurityManager();
50
51 private static final Logger LOGGER = StatusLogger.getLogger();
52
53
54
55 private boolean lockingProviderUtil;
56
57 private static void checkPermission(final Permission permission) {
58 if (SECURITY_MANAGER != null) {
59 SECURITY_MANAGER.checkPermission(permission);
60 }
61 }
62
63 private void loadProvider(final Bundle bundle) {
64 if (bundle.getState() == Bundle.UNINSTALLED) {
65 return;
66 }
67 try {
68 checkPermission(new AdminPermission(bundle, AdminPermission.RESOURCE));
69 checkPermission(new AdaptPermission(BundleWiring.class.getName(), bundle, AdaptPermission.ADAPT));
70 loadProvider(bundle.getBundleContext(), bundle.adapt(BundleWiring.class));
71 } catch (final SecurityException e) {
72 LOGGER.debug("Cannot access bundle [{}] contents. Ignoring.", bundle.getSymbolicName(), e);
73 } catch (final Exception e) {
74 LOGGER.warn("Problem checking bundle {} for Log4j 2 provider.", bundle.getSymbolicName(), e);
75 }
76 }
77
78 private void loadProvider(final BundleContext context, final BundleWiring bundleWiring) {
79 final String filter = "(APIVersion>=2.60)";
80 try {
81 final Collection<ServiceReference<Provider>> serviceReferences = context.getServiceReferences(Provider.class, filter);
82 Provider maxProvider = null;
83 for (final ServiceReference<Provider> serviceReference : serviceReferences) {
84 final Provider provider = context.getService(serviceReference);
85 if (maxProvider == null || provider.getPriority() > maxProvider.getPriority()) {
86 maxProvider = provider;
87 }
88 }
89 if (maxProvider != null) {
90 ProviderUtil.addProvider(maxProvider);
91 }
92 } catch (final InvalidSyntaxException ex) {
93 LOGGER.error("Invalid service filter: " + filter, ex);
94 }
95 final List<URL> urls = bundleWiring.findEntries("META-INF", "log4j-provider.properties", 0);
96 for (final URL url : urls) {
97 ProviderUtil.loadProvider(url, bundleWiring.getClassLoader());
98 }
99 }
100
101 @Override
102 public void start(final BundleContext context) throws Exception {
103 ProviderUtil.STARTUP_LOCK.lock();
104 lockingProviderUtil = true;
105 final BundleWiring self = context.getBundle().adapt(BundleWiring.class);
106 final List<BundleWire> required = self.getRequiredWires(LoggerContextFactory.class.getName());
107 for (final BundleWire wire : required) {
108 loadProvider(context, wire.getProviderWiring());
109 }
110 context.addBundleListener(this);
111 final Bundle[] bundles = context.getBundles();
112 for (final Bundle bundle : bundles) {
113 loadProvider(bundle);
114 }
115 unlockIfReady();
116 }
117
118 private void unlockIfReady() {
119 if (lockingProviderUtil && !ProviderUtil.PROVIDERS.isEmpty()) {
120 ProviderUtil.STARTUP_LOCK.unlock();
121 lockingProviderUtil = false;
122 }
123 }
124
125 @Override
126 public void stop(final BundleContext context) throws Exception {
127 context.removeBundleListener(this);
128 unlockIfReady();
129 }
130
131 @Override
132 public void bundleChanged(final BundleEvent event) {
133 switch (event.getType()) {
134 case BundleEvent.STARTED:
135 loadProvider(event.getBundle());
136 unlockIfReady();
137 break;
138
139 default:
140 break;
141 }
142 }
143
144 }