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