1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.osgi.boot.utils.internal;
20
21 import java.lang.reflect.Field;
22 import java.lang.reflect.Method;
23 import java.util.List;
24
25 import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
26 import org.eclipse.jetty.util.log.Log;
27 import org.eclipse.jetty.util.log.Logger;
28 import org.osgi.framework.Bundle;
29
30
31
32
33
34
35
36
37 public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
38 {
39 private static final Logger LOG = Log.getLogger(BundleClassLoaderHelper.class);
40
41 private static boolean identifiedOsgiImpl = false;
42
43 private static boolean isEquinox = false;
44
45 private static boolean isFelix = false;
46
47 private static void init(Bundle bundle)
48 {
49 identifiedOsgiImpl = true;
50 try
51 {
52 isEquinox = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost") != null;
53 }
54 catch (Throwable t)
55 {
56 isEquinox = false;
57 }
58 if (!isEquinox)
59 {
60 try
61 {
62 isFelix = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl") != null;
63 }
64 catch (Throwable t2)
65 {
66 isFelix = false;
67 }
68 }
69 }
70
71
72
73
74
75
76
77 public ClassLoader getBundleClassLoader(Bundle bundle)
78 {
79 String bundleActivator = (String) bundle.getHeaders().get("Bundle-Activator");
80
81 if (bundleActivator == null)
82 {
83 bundleActivator = (String) bundle.getHeaders().get("Jetty-ClassInBundle");
84 }
85 if (bundleActivator != null)
86 {
87 try
88 {
89 return bundle.loadClass(bundleActivator).getClassLoader();
90 }
91 catch (ClassNotFoundException e)
92 {
93 LOG.warn(e);
94 }
95 }
96
97 if (!identifiedOsgiImpl)
98 {
99 init(bundle);
100 }
101 if (isEquinox)
102 {
103 return internalGetEquinoxBundleClassLoader(bundle);
104 }
105 else if (isFelix)
106 {
107 return internalGetFelixBundleClassLoader(bundle);
108 }
109
110 LOG.warn("No classloader found for bundle "+bundle.getSymbolicName());
111 return null;
112 }
113
114 private static Method Equinox_BundleHost_getBundleLoader_method;
115
116 private static Method Equinox_BundleLoader_createClassLoader_method;
117
118 private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle)
119 {
120
121 try
122 {
123 if (Equinox_BundleHost_getBundleLoader_method == null)
124 {
125 Equinox_BundleHost_getBundleLoader_method =
126 bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost").getDeclaredMethod("getBundleLoader", new Class[] {});
127 Equinox_BundleHost_getBundleLoader_method.setAccessible(true);
128 }
129 Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {});
130 if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null)
131 {
132 Equinox_BundleLoader_createClassLoader_method =
133 bundleLoader.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader", new Class[] {});
134 Equinox_BundleLoader_createClassLoader_method.setAccessible(true);
135 }
136 return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {});
137 }
138 catch (Throwable t)
139 {
140 LOG.warn(t);
141 }
142 LOG.warn("No classloader for equinox platform for bundle "+bundle.getSymbolicName());
143 return null;
144 }
145
146 private static Field Felix_BundleImpl_m_modules_field;
147
148 private static Field Felix_ModuleImpl_m_classLoader_field;
149
150 private static Method Felix_adapt_method;
151
152 private static Method Felix_bundle_wiring_getClassLoader_method;
153
154 private static Class Felix_bundleWiringClazz;
155
156 private static Boolean isFelix403 = null;
157
158 private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle)
159 {
160
161 initFelix403(bundle);
162
163 if (isFelix403.booleanValue())
164 {
165 try
166 {
167 Object wiring = Felix_adapt_method.invoke(bundle, new Object[] {Felix_bundleWiringClazz});
168 ClassLoader cl = (ClassLoader)Felix_bundle_wiring_getClassLoader_method.invoke(wiring);
169 return cl;
170 }
171 catch (Exception e)
172 {
173 LOG.warn(e);
174 return null;
175 }
176 }
177
178
179
180 if (Felix_BundleImpl_m_modules_field == null)
181 {
182 try
183 {
184 Class bundleImplClazz = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl");
185 Felix_BundleImpl_m_modules_field = bundleImplClazz.getDeclaredField("m_modules");
186 Felix_BundleImpl_m_modules_field.setAccessible(true);
187 }
188 catch (ClassNotFoundException e)
189 {
190 LOG.warn(e);
191 }
192 catch (NoSuchFieldException e)
193 {
194 LOG.warn(e);
195 }
196 }
197
198
199 Object currentModuleImpl;
200 try
201 {
202 Object[] moduleArray = (Object[]) Felix_BundleImpl_m_modules_field.get(bundle);
203 currentModuleImpl = moduleArray[moduleArray.length - 1];
204 }
205 catch (Throwable t2)
206 {
207 try
208 {
209 List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_modules_field.get(bundle);
210 currentModuleImpl = moduleArray.get(moduleArray.size() - 1);
211 }
212 catch (Exception e)
213 {
214 LOG.warn(e);
215 return null;
216 }
217 }
218
219 if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null)
220 {
221 try
222 {
223 Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField("m_classLoader");
224 Felix_ModuleImpl_m_classLoader_field.setAccessible(true);
225 }
226 catch (ClassNotFoundException e)
227 {
228 LOG.warn(e);
229 return null;
230 }
231 catch (NoSuchFieldException e)
232 {
233 LOG.warn(e);
234 return null;
235 }
236 }
237
238
239
240 ClassLoader cl = null;
241 try
242 {
243 cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
244 if (cl != null)
245 return cl;
246 }
247 catch (Exception e)
248 {
249 LOG.warn(e);
250 return null;
251 }
252
253
254
255
256
257 try
258 {
259 bundle.loadClass("java.lang.Object");
260 cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
261 return cl;
262 }
263 catch (Exception e)
264 {
265 LOG.warn(e);
266 return null;
267 }
268 }
269
270
271 private static void initFelix403 (Bundle bundle)
272 {
273
274 if (isFelix403 == null)
275 {
276 try
277 {
278 Class bundleImplClazz = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl");
279 Felix_bundleWiringClazz = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring");
280 Felix_adapt_method = bundleImplClazz.getDeclaredMethod("adapt", new Class[] {Class.class});
281 Felix_adapt_method.setAccessible(true);
282 Felix_bundle_wiring_getClassLoader_method = Felix_bundleWiringClazz.getDeclaredMethod("getClassLoader");
283 Felix_bundle_wiring_getClassLoader_method.setAccessible(true);
284 isFelix403 = Boolean.TRUE;
285 }
286 catch (ClassNotFoundException e)
287 {
288 LOG.warn("Felix 4.x classes not found in environment");
289 isFelix403 = Boolean.FALSE;
290 }
291 catch (NoSuchMethodException e)
292 {
293 LOG.warn("Felix 4.x classes not found in environment");
294 isFelix403 = Boolean.FALSE;
295 }
296 }
297 }
298 }