diff options
author | Jan Bartel | 2014-04-07 10:57:41 +0000 |
---|---|---|
committer | Jan Bartel | 2014-04-07 10:59:17 +0000 |
commit | 90f387bc34ca9b5ed974661849ca5c51e663c0a9 (patch) | |
tree | 816a939be4003dd1a26f75d3b3cb32f6bff9c784 /jetty-osgi/jetty-osgi-boot | |
parent | 64e11bc8e8d0dea9eca99a3914c0c01c1ecc0075 (diff) | |
download | org.eclipse.jetty.project-90f387bc34ca9b5ed974661849ca5c51e663c0a9.tar.gz org.eclipse.jetty.project-90f387bc34ca9b5ed974661849ca5c51e663c0a9.tar.xz org.eclipse.jetty.project-90f387bc34ca9b5ed974661849ca5c51e663c0a9.zip |
431892 DefaultFileLocatorHelper.getBundleInstallLocation fails for equinox 3.10
Diffstat (limited to 'jetty-osgi/jetty-osgi-boot')
2 files changed, 260 insertions, 171 deletions
diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java index 79e350cacc..199bde3c35 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultBundleClassLoaderHelper.java @@ -37,37 +37,81 @@ import org.osgi.framework.Bundle; public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper { private static final Logger LOG = Log.getLogger(BundleClassLoaderHelper.class); + private static enum OSGiContainerType {EquinoxOld, EquinoxLuna, FelixOld, Felix403}; + private static OSGiContainerType osgiContainer; + private static Class Equinox_BundleHost_Class; + private static Class Equinox_EquinoxBundle_Class; + private static Class Felix_BundleImpl_Class; + private static Class Felix_BundleWiring_Class; + //old equinox + private static Method Equinox_BundleHost_getBundleLoader_method; + private static Method Equinox_BundleLoader_createClassLoader_method; + //new equinox + private static Method Equinox_EquinoxBundle_getModuleClassLoader_Method; + + //new felix + private static Method Felix_BundleImpl_Adapt_Method; + //old felix + private static Field Felix_BundleImpl_m_Modules_Field; + private static Field Felix_ModuleImpl_m_ClassLoader_Field; + private static Method Felix_BundleWiring_getClassLoader_Method; - private static boolean identifiedOsgiImpl = false; - - private static boolean isEquinox = false; - - private static boolean isFelix = false; - - private static void init(Bundle bundle) + + private static void checkContainerType (Bundle bundle) { - identifiedOsgiImpl = true; + if (osgiContainer != null) + return; + try { - isEquinox = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost") != null; + Equinox_BundleHost_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost"); + osgiContainer = OSGiContainerType.EquinoxOld; + return; } - catch (Throwable t) + catch (ClassNotFoundException e) { - isEquinox = false; + LOG.ignore(e); } - if (!isEquinox) + + try { + Equinox_EquinoxBundle_Class = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.framework.EquinoxBundle"); + osgiContainer = OSGiContainerType.EquinoxLuna; + return; + } + catch (ClassNotFoundException e) + { + LOG.ignore(e); + } + + try + { + //old felix or new felix? + Felix_BundleImpl_Class = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl"); try { - isFelix = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl") != null; + Felix_BundleImpl_Adapt_Method = Felix_BundleImpl_Class.getDeclaredMethod("adapt", new Class[] {Class.class}); + osgiContainer = OSGiContainerType.Felix403; + return; } - catch (Throwable t2) + catch (NoSuchMethodException e) { - isFelix = false; + osgiContainer = OSGiContainerType.FelixOld; + return; } } + catch (ClassNotFoundException e) + { + LOG.warn("Unknown OSGi container type"); + return; + } + } + + + + /** * Assuming the bundle is started. * @@ -77,7 +121,7 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper public ClassLoader getBundleClassLoader(Bundle bundle) { String bundleActivator = (String) bundle.getHeaders().get("Bundle-Activator"); - + if (bundleActivator == null) { bundleActivator = (String) bundle.getHeaders().get("Jetty-ClassInBundle"); @@ -93,121 +137,94 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper LOG.warn(e); } } - // resort to introspection - if (!identifiedOsgiImpl) - { - init(bundle); - } - if (isEquinox) - { - return internalGetEquinoxBundleClassLoader(bundle); - } - else if (isFelix) - { - return internalGetFelixBundleClassLoader(bundle); - } - LOG.warn("No classloader found for bundle "+bundle.getSymbolicName()); - return null; + // resort to introspection + return getBundleClassLoaderForContainer(bundle); } - - private static Method Equinox_BundleHost_getBundleLoader_method; - - private static Method Equinox_BundleLoader_createClassLoader_method; - - private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle) + + /** + * @param bundle + * @return + */ + private ClassLoader getBundleClassLoaderForContainer (Bundle bundle) { - // assume equinox: - try + checkContainerType (bundle); + if (osgiContainer == null) + { + LOG.warn("No classloader for unknown OSGi container type"); + return null; + } + + switch (osgiContainer) { - if (Equinox_BundleHost_getBundleLoader_method == null) + case EquinoxOld: + case EquinoxLuna: { - Equinox_BundleHost_getBundleLoader_method = - bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost").getDeclaredMethod("getBundleLoader", new Class[] {}); - Equinox_BundleHost_getBundleLoader_method.setAccessible(true); + return internalGetEquinoxBundleClassLoader(bundle); } - Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {}); - if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null) + + case FelixOld: + case Felix403: { - Equinox_BundleLoader_createClassLoader_method = - bundleLoader.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader", new Class[] {}); - Equinox_BundleLoader_createClassLoader_method.setAccessible(true); + return internalGetFelixBundleClassLoader(bundle); + } + default: + { + LOG.warn("No classloader found for bundle "+bundle.getSymbolicName()); + return null; + } - return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {}); - } - catch (Throwable t) - { - LOG.warn(t); } - LOG.warn("No classloader for equinox platform for bundle "+bundle.getSymbolicName()); - return null; } - - private static Field Felix_BundleImpl_m_modules_field; - - private static Field Felix_ModuleImpl_m_classLoader_field; - - private static Method Felix_adapt_method; - private static Method Felix_bundle_wiring_getClassLoader_method; - private static Class Felix_bundleWiringClazz; - private static Boolean isFelix403 = null; - - private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle) + /** + * @param bundle + * @return + */ + private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle) { - //firstly, try to find classes matching a newer version of felix - initFelix403(bundle); - - if (isFelix403.booleanValue()) + if (osgiContainer == OSGiContainerType.EquinoxOld) { try { - Object wiring = Felix_adapt_method.invoke(bundle, new Object[] {Felix_bundleWiringClazz}); - ClassLoader cl = (ClassLoader)Felix_bundle_wiring_getClassLoader_method.invoke(wiring); - return cl; + if (Equinox_BundleHost_getBundleLoader_method == null) + { + Equinox_BundleHost_getBundleLoader_method = + Equinox_BundleHost_Class.getDeclaredMethod("getBundleLoader", new Class[] {}); + Equinox_BundleHost_getBundleLoader_method.setAccessible(true); + } + Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle, new Object[] {}); + if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null) + { + Equinox_BundleLoader_createClassLoader_method = + bundleLoader.getClass().getClassLoader().loadClass("org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader", new Class[] {}); + Equinox_BundleLoader_createClassLoader_method.setAccessible(true); + } + return (ClassLoader) Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader, new Object[] {}); } - catch (Exception e) + catch (ClassNotFoundException t) { - LOG.warn(e); + LOG.warn(t); return null; } - } - - - // Fallback to trying earlier versions of felix. - if (Felix_BundleImpl_m_modules_field == null) - { - try - { - Class bundleImplClazz = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl"); - Felix_BundleImpl_m_modules_field = bundleImplClazz.getDeclaredField("m_modules"); - Felix_BundleImpl_m_modules_field.setAccessible(true); - } - catch (ClassNotFoundException e) + catch (Throwable t) { - LOG.warn(e); - } - catch (NoSuchFieldException e) - { - LOG.warn(e); + LOG.warn(t); + return null; } } - - // Figure out which version of the modules is exported - Object currentModuleImpl; - try - { - Object[] moduleArray = (Object[]) Felix_BundleImpl_m_modules_field.get(bundle); - currentModuleImpl = moduleArray[moduleArray.length - 1]; - } - catch (Throwable t2) + + if (osgiContainer == OSGiContainerType.EquinoxLuna) { try { - List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_modules_field.get(bundle); - currentModuleImpl = moduleArray.get(moduleArray.size() - 1); + if (Equinox_EquinoxBundle_getModuleClassLoader_Method == null) + Equinox_EquinoxBundle_getModuleClassLoader_Method = Equinox_EquinoxBundle_Class.getDeclaredMethod("getModuleClassLoader", new Class[] {Boolean.TYPE}); + + Equinox_EquinoxBundle_getModuleClassLoader_Method.setAccessible(true); + return (ClassLoader)Equinox_EquinoxBundle_getModuleClassLoader_Method.invoke(bundle, new Object[] {Boolean.FALSE}); } catch (Exception e) { @@ -215,84 +232,135 @@ public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper return null; } } + + LOG.warn("No classloader for equinox platform for bundle "+bundle.getSymbolicName()); + return null; + } + + + - if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null) + /** + * @param bundle + * @return + */ + private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle) + { + + if (osgiContainer == OSGiContainerType.Felix403) { try { - Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField("m_classLoader"); - Felix_ModuleImpl_m_classLoader_field.setAccessible(true); + if (Felix_BundleWiring_Class == null) + Felix_BundleWiring_Class = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring"); + + + Felix_BundleImpl_Adapt_Method.setAccessible(true); + + if (Felix_BundleWiring_getClassLoader_Method == null) + { + Felix_BundleWiring_getClassLoader_Method = Felix_BundleWiring_Class.getDeclaredMethod("getClassLoader"); + Felix_BundleWiring_getClassLoader_Method.setAccessible(true); + } + + + Object wiring = Felix_BundleImpl_Adapt_Method.invoke(bundle, new Object[] {Felix_BundleWiring_Class}); + return (ClassLoader)Felix_BundleWiring_getClassLoader_Method.invoke(wiring); } - catch (ClassNotFoundException e) - { - LOG.warn(e); - return null; - } - catch (NoSuchFieldException e) + catch (Exception e) { LOG.warn(e); return null; } } - // first make sure that the classloader is ready: - // the m_classLoader field must be initialized by the - // ModuleImpl.getClassLoader() private method. - ClassLoader cl = null; - try - { - cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl); - if (cl != null) - return cl; - } - catch (Exception e) - { - LOG.warn(e); - return null; - } - - // looks like it was not ready: - // the m_classLoader field must be initialized by the - // ModuleImpl.getClassLoader() private method. - // this call will do that. - try - { - bundle.loadClass("java.lang.Object"); - cl = (ClassLoader) Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl); - return cl; - } - catch (Exception e) - { - LOG.warn(e); - return null; - } - } - private static void initFelix403 (Bundle bundle) - { - //see if the version of Felix is a new one - if (isFelix403 == null) - { + if (osgiContainer == OSGiContainerType.FelixOld) + { try { - Class bundleImplClazz = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl"); - Felix_bundleWiringClazz = bundle.getClass().getClassLoader().loadClass("org.osgi.framework.wiring.BundleWiring"); - Felix_adapt_method = bundleImplClazz.getDeclaredMethod("adapt", new Class[] {Class.class}); - Felix_adapt_method.setAccessible(true); - Felix_bundle_wiring_getClassLoader_method = Felix_bundleWiringClazz.getDeclaredMethod("getClassLoader"); - Felix_bundle_wiring_getClassLoader_method.setAccessible(true); - isFelix403 = Boolean.TRUE; - } - catch (ClassNotFoundException e) + if (Felix_BundleImpl_m_Modules_Field == null) + { + Felix_BundleImpl_m_Modules_Field = Felix_BundleImpl_Class.getDeclaredField("m_modules"); + Felix_BundleImpl_m_Modules_Field.setAccessible(true); + } + + // Figure out which version of the modules is exported + Object currentModuleImpl; + + try + { + Object[] moduleArray = (Object[]) Felix_BundleImpl_m_Modules_Field.get(bundle); + currentModuleImpl = moduleArray[moduleArray.length - 1]; + } + catch (Throwable t2) + { + try + { + List<Object> moduleArray = (List<Object>) Felix_BundleImpl_m_Modules_Field.get(bundle); + currentModuleImpl = moduleArray.get(moduleArray.size() - 1); + } + catch (Exception e) + { + LOG.warn(e); + return null; + } + } + + if (Felix_ModuleImpl_m_ClassLoader_Field == null && currentModuleImpl != null) + { + try + { + Felix_ModuleImpl_m_ClassLoader_Field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField("m_classLoader"); + Felix_ModuleImpl_m_ClassLoader_Field.setAccessible(true); + } + catch (Exception e) + { + LOG.warn(e); + return null; + } + } + + // first make sure that the classloader is ready: + // the m_classLoader field must be initialized by the + // ModuleImpl.getClassLoader() private method. + ClassLoader cl = null; + try + { + cl = (ClassLoader) Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl); + if (cl != null) + return cl; + } + catch (Exception e) + { + LOG.warn(e); + return null; + } + + // looks like it was not ready: + // the m_classLoader field must be initialized by the + // ModuleImpl.getClassLoader() private method. + // this call will do that. + try + { + bundle.loadClass("java.lang.Object"); + cl = (ClassLoader) Felix_ModuleImpl_m_ClassLoader_Field.get(currentModuleImpl); + return cl; + } + catch (Exception e) + { + LOG.warn(e); + return null; + } + } + catch (Exception e) { - LOG.warn("Felix 4.x classes not found in environment"); - isFelix403 = Boolean.FALSE; + LOG.warn(e); + return null; } - catch (NoSuchMethodException e) - { - LOG.warn("Felix 4.x classes not found in environment"); - isFelix403 = Boolean.FALSE; - } } + + LOG.warn("No classloader for felix platform for bundle "+bundle.getSymbolicName()); + return null; } } diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java index c1d3bcaa73..fed6f8b6cf 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/utils/internal/DefaultFileLocatorHelper.java @@ -63,7 +63,25 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper // DirZipBundleEntry private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;// ZipFile + + private static final String[] FILE_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry","org.eclipse.osgi.storage.bundlefile.FileBundleEntry"}; + private static final String[] ZIP_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry","org.eclipse.osgi.storage.bundlefile.ZipBundleEntry"}; + private static final String[] DIR_ZIP_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry","org.eclipse.osgi.storage.bundlefile.DirZipBundleEntry"}; + private static final String[] BUNDLE_URL_CONNECTION_CLASSES = {"org.eclipse.osgi.framework.internal.core.BundleURLConnection", "org.eclipse.osgi.storage.url.BundleURLConnection"}; + + public static boolean match (String name, String... names) + { + if (name == null || names == null) + return false; + boolean matched = false; + for (int i=0; i< names.length && !matched; i++) + if (name.equals(names[i])) + matched = true; + return matched; + } + + /** * Works with equinox, felix, nuxeo and probably more. Not exactly in the * spirit of OSGi but quite necessary to support self-contained webapps and @@ -107,7 +125,8 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper BUNDLE_ENTRY_FIELD.setAccessible(true); } Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con); - if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry")) + + if (match(bundleEntry.getClass().getName(), FILE_BUNDLE_ENTRY_CLASSES)) { if (FILE_FIELD == null) { @@ -117,7 +136,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper File f = (File) FILE_FIELD.get(bundleEntry); return f.getParentFile().getParentFile(); } - else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry")) + else if (match(bundleEntry.getClass().getName(), ZIP_BUNDLE_ENTRY_CLASSES)) { url = bundle.getEntry("/"); @@ -144,7 +163,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper ZipFile zipFile = (ZipFile) ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile); return new File(zipFile.getName()); } - else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry")) + else if (match (bundleEntry.getClass().getName(), DIR_ZIP_BUNDLE_ENTRY_CLASSES)) { // that will not happen as we did ask for the manifest not a // directory. @@ -309,7 +328,7 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper URLConnection conn = url.openConnection(); conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) + if (BUNDLE_URL_CONNECTION_getLocalURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) { BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null); BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true); @@ -340,7 +359,9 @@ public class DefaultFileLocatorHelper implements BundleFileLocatorHelper URLConnection conn = url.openConnection(); conn.setDefaultUseCaches(Resource.getDefaultUseCaches()); - if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection")) + if (BUNDLE_URL_CONNECTION_getFileURL == null + && + match (conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES)) { BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null); BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true); |