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