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 public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
37 {
38 private static final Logger LOG = Log.getLogger(BundleClassLoaderHelper.class);
39 private static enum OSGiContainerType {EquinoxOld, EquinoxLuna, FelixOld, Felix403, Concierge};
40 private static OSGiContainerType osgiContainer;
41 private static Class Equinox_BundleHost_Class;
42 private static Class Equinox_EquinoxBundle_Class;
43 private static Class Felix_BundleImpl_Class;
44 private static Class Felix_BundleWiring_Class;
45
46 private static Method Equinox_BundleHost_getBundleLoader_method;
47 private static Method Equinox_BundleLoader_createClassLoader_method;
48
49 private static Method Equinox_EquinoxBundle_getModuleClassLoader_Method;
50
51
52 private static Method Felix_BundleImpl_Adapt_Method;
53
54 private static Field Felix_BundleImpl_m_Modules_Field;
55 private static Field Felix_ModuleImpl_m_ClassLoader_Field;
56 private static Method Felix_BundleWiring_getClassLoader_Method;
57
58
59 private static Class Concierge_BundleImpl_Class;
60 private static Class Concierge_BundleWiring_Class;
61 private static Method Concierge_BundleImpl_Adapt_Method;
62 private static Method Concierge_BundleWiring_getClassLoader_Method;
63
64
65 private static void checkContainerType (Bundle bundle)
66 {
67 if (osgiContainer != null)
68 return;
69
70 try
71 {
72 Equinox_BundleHost_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost");
73 osgiContainer = OSGiContainerType.EquinoxOld;
74 return;
75 }
76 catch (ClassNotFoundException e)
77 {
78 LOG.ignore(e);
79 }
80
81 try
82 {
83 Equinox_EquinoxBundle_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.framework.EquinoxBundle");
84 osgiContainer = OSGiContainerType.EquinoxLuna;
85 return;
86 }
87 catch (ClassNotFoundException e)
88 {
89 LOG.ignore(e);
90 }
91
92 try
93 {
94
95 Felix_BundleImpl_Class = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl");
96 try
97 {
98 Felix_BundleImpl_Adapt_Method = Felix_BundleImpl_Class.getDeclaredMethod("adapt", new Class[] {Class.class});
99 osgiContainer = OSGiContainerType.Felix403;
100 return;
101 }
102 catch (NoSuchMethodException e)
103 {
104 osgiContainer = OSGiContainerType.FelixOld;
105 return;
106 }
107 }
108 catch (ClassNotFoundException e)
109 {
110 LOG.ignore(e);
111 }
112
113 try
114 {
115 Concierge_BundleImpl_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.concierge.BundleImpl");
116 osgiContainer = OSGiContainerType.Concierge;
117 return;
118 }
119 catch (ClassNotFoundException e)
120 {
121 LOG.ignore(e);
122 }
123
124 LOG.warn("Unknown OSGi container type");
125 return;
126 }
127
128
129
130
131
132
133
134
135
136
137
138 public ClassLoader getBundleClassLoader(Bundle bundle)
139 {
140 String bundleActivator = (String) bundle.getHeaders().get("Bundle-Activator");
141
142 if (bundleActivator == null)
143 {
144 bundleActivator = (String) bundle.getHeaders().get("Jetty-ClassInBundle");
145 }
146 if (bundleActivator != null)
147 {
148 try
149 {
150 return bundle.loadClass(bundleActivator).getClassLoader();
151 }
152 catch (ClassNotFoundException e)
153 {
154 LOG.warn(e);
155 }
156 }
157
158
159 return getBundleClassLoaderForContainer(bundle);
160 }
161
162
163
164
165
166 private ClassLoader getBundleClassLoaderForContainer (Bundle bundle)
167 {
168 checkContainerType (bundle);
169 if (osgiContainer == null)
170 {
171 LOG.warn("No classloader for unknown OSGi container type");
172 return null;
173 }
174
175 switch (osgiContainer)
176 {
177 case EquinoxOld:
178 case EquinoxLuna:
179 {
180 return internalGetEquinoxBundleClassLoader(bundle);
181 }
182
183 case FelixOld:
184 case Felix403:
185 {
186 return internalGetFelixBundleClassLoader(bundle);
187 }
188
189 case Concierge:
190 {
191 return internalGetConciergeBundleClassLoader(bundle);
192 }
193
194 default:
195 {
196 LOG.warn("No classloader found for bundle "+bundle.getSymbolicName());
197 return null;
198
199 }
200 }
201 }
202
203
204
205
206
207
208
209 private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle)
210 {
211 if (osgiContainer == OSGiContainerType.EquinoxOld)
212 {
213 try
214 {
215 if (Equinox_BundleHost_getBundleLoader_method == null)
216 {
217 Equinox_BundleHost_getBundleLoader_method =
218 Equinox_BundleHost_Class.getDeclaredMethod("getBundleLoader", new Class[] {});
219 Equinox_BundleHost_getBundleLoader_method.setAccessible(true);
220 }
221 Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {});
222 if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null)
223 {
224 Equinox_BundleLoader_createClassLoader_method =
225 bundleLoader.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader", new Class[] {});
226 Equinox_BundleLoader_createClassLoader_method.setAccessible(true);
227 }
228 return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {});
229 }
230 catch (ClassNotFoundException t)
231 {
232 LOG.warn(t);
233 return null;
234 }
235 catch (Throwable t)
236 {
237 LOG.warn(t);
238 return null;
239 }
240 }
241
242 if (osgiContainer == OSGiContainerType.EquinoxLuna)
243 {
244 try
245 {
246 if (Equinox_EquinoxBundle_getModuleClassLoader_Method == null)
247 Equinox_EquinoxBundle_getModuleClassLoader_Method = Equinox_EquinoxBundle_Class.getDeclaredMethod("getModuleClassLoader", new Class[] {Boolean.TYPE});
248
249 Equinox_EquinoxBundle_getModuleClassLoader_Method.setAccessible(true);
250 return (ClassLoader)Equinox_EquinoxBundle_getModuleClassLoader_Method.invoke(bundle, new Object[] {Boolean.FALSE});
251 }
252 catch (Exception e)
253 {
254 LOG.warn(e);
255 return null;
256 }
257 }
258
259 LOG.warn("No classloader for equinox platform for bundle "+bundle.getSymbolicName());
260 return null;
261 }
262
263
264
265
266
267
268
269
270 private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle)
271 {
272
273 if (osgiContainer == OSGiContainerType.Felix403)
274 {
275 try
276 {
277 if (Felix_BundleWiring_Class == null)
278 Felix_BundleWiring_Class = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring");
279
280
281 Felix_BundleImpl_Adapt_Method.setAccessible(true);
282
283 if (Felix_BundleWiring_getClassLoader_Method == null)
284 {
285 Felix_BundleWiring_getClassLoader_Method = Felix_BundleWiring_Class.getDeclaredMethod("getClassLoader");
286 Felix_BundleWiring_getClassLoader_Method.setAccessible(true);
287 }
288
289
290 Object wiring = Felix_BundleImpl_Adapt_Method.invoke(bundle, new Object[] {Felix_BundleWiring_Class});
291 return (ClassLoader)Felix_BundleWiring_getClassLoader_Method.invoke(wiring);
292 }
293 catch (Exception e)
294 {
295 LOG.warn(e);
296 return null;
297 }
298 }
299
300
301 if (osgiContainer == OSGiContainerType.FelixOld)
302 {
303 try
304 {
305 if (Felix_BundleImpl_m_Modules_Field == null)
306 {
307 Felix_BundleImpl_m_Modules_Field = Felix_BundleImpl_Class.getDeclaredField("m_modules");
308 Felix_BundleImpl_m_Modules_Field.setAccessible(true);
309 }
310
311
312 Object currentModuleImpl;
313
314 try
315 {
316 Object[] moduleArray = (Object[]) Felix_BundleImpl_m_Modules_Field.get(bundle);
317 currentModuleImpl = moduleArray[moduleArray.length - 1];
318 }
319 catch (Throwable t2)
320 {
321 try
322 {
323 List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_Modules_Field.get(bundle);
324 currentModuleImpl = moduleArray.get(moduleArray.size() - 1);
325 }
326 catch (Exception e)
327 {
328 LOG.warn(e);
329 return null;
330 }
331 }
332
333 if (Felix_ModuleImpl_m_ClassLoader_Field == null && currentModuleImpl != null)
334 {
335 try
336 {
337 Felix_ModuleImpl_m_ClassLoader_Field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField("m_classLoader");
338 Felix_ModuleImpl_m_ClassLoader_Field.setAccessible(true);
339 }
340 catch (Exception e)
341 {
342 LOG.warn(e);
343 return null;
344 }
345 }
346
347
348
349
350 ClassLoader cl = null;
351 try
352 {
353 cl = (ClassLoader) Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl);
354 if (cl != null)
355 return cl;
356 }
357 catch (Exception e)
358 {
359 LOG.warn(e);
360 return null;
361 }
362
363
364
365
366
367 try
368 {
369 bundle.loadClass("java.lang.Object");
370 cl = (ClassLoader) Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl);
371 return cl;
372 }
373 catch (Exception e)
374 {
375 LOG.warn(e);
376 return null;
377 }
378 }
379 catch (Exception e)
380 {
381 LOG.warn(e);
382 return null;
383 }
384 }
385
386 LOG.warn("No classloader for felix platform for bundle "+bundle.getSymbolicName());
387 return null;
388 }
389
390
391
392
393
394 private static ClassLoader internalGetConciergeBundleClassLoader(Bundle bundle)
395 {
396 if (osgiContainer == OSGiContainerType.Concierge)
397 {
398 try
399 {
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 if (Concierge_BundleWiring_Class == null) {
419 Concierge_BundleWiring_Class = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring");
420 Concierge_BundleImpl_Adapt_Method = Concierge_BundleImpl_Class.getMethod("adapt", new Class[] {Class.class});
421 Concierge_BundleImpl_Adapt_Method.setAccessible(true);
422 Concierge_BundleWiring_getClassLoader_Method = Concierge_BundleWiring_Class.getMethod("getClassLoader");
423 Concierge_BundleWiring_getClassLoader_Method.setAccessible(true);
424 }
425
426 Object wiring = Concierge_BundleImpl_Adapt_Method.invoke(bundle, new Object[] {Concierge_BundleWiring_Class});
427 ClassLoader cl = (ClassLoader)Concierge_BundleWiring_getClassLoader_Method.invoke(wiring);
428 return cl;
429 }
430 catch (Exception e)
431 {
432 LOG.warn(e);
433 return null;
434 }
435 }
436
437 LOG.warn("No classloader for Concierge platform for bundle "+bundle.getSymbolicName());
438 return null;
439 }
440 }