diff options
author | Thomas Watson | 2020-05-08 13:40:38 +0000 |
---|---|---|
committer | Thomas Watson | 2020-05-08 20:50:48 +0000 |
commit | febf4782c5acfe6ee394b8b3c5573ee3f42ff009 (patch) | |
tree | 1db70bfc695026dd79d46a5ad639412b8526efa6 | |
parent | 3b7a9b51421cf64c7561aac8fea560630462d292 (diff) | |
download | rt.equinox.framework-febf4782c5acfe6ee394b8b3c5573ee3f42ff009.tar.gz rt.equinox.framework-febf4782c5acfe6ee394b8b3c5573ee3f42ff009.tar.xz rt.equinox.framework-febf4782c5acfe6ee394b8b3c5573ee3f42ff009.zip |
Bug 562980 - [osgi R8] Update ServiceReference.isAssignableTo with
clearification from R8
Change-Id: I7d9a78de8d0dc719ef33c5bde9401108acb2645a
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
6 files changed, 84 insertions, 40 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java index 556b07e0f..021a79e1d 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/sources/PackageSource.java @@ -22,7 +22,6 @@ import org.eclipse.osgi.container.ModuleWiring; import org.eclipse.osgi.internal.framework.EquinoxBundle; import org.eclipse.osgi.internal.framework.EquinoxContainer; import org.eclipse.osgi.internal.loader.BundleLoader; -import org.eclipse.osgi.internal.loader.SystemBundleLoader; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceFactory; import org.osgi.service.packageadmin.PackageAdmin; @@ -114,78 +113,111 @@ public abstract class PackageSource { * @param container the equinox container * @return true if assignable given package wiring */ - public static boolean isServiceAssignableTo(Bundle registrant, Bundle client, String className, Class<?> serviceClass, EquinoxContainer container) { + public static boolean isServiceAssignableTo(Bundle registrant, Bundle client, String className, + Class<?> serviceClass, boolean checkInternal, EquinoxContainer container) { // 1) if the registrant == client always return true if (registrant == client) { return true; } // 2) get the package name from the specified className String pkgName = BundleLoader.getPackageName(className); - if (pkgName.startsWith("java.")) //$NON-NLS-1$ + if (pkgName.startsWith("java.")) { //$NON-NLS-1$ return true; + } BundleLoader producerBL = getBundleLoader(registrant); - if (producerBL == null) + if (producerBL == null) { return false; + } BundleLoader consumerBL = getBundleLoader(client); - if (consumerBL == null) + if (consumerBL == null) { return false; + } // 3) for the specified bundle, find the wiring for the package. If no wiring is found return true - PackageSource consumerSource = consumerBL.getPackageSource(pkgName); - if (consumerSource == null) + PackageSource consumerSource = getSourceFromLoader(consumerBL, pkgName, className, checkInternal); + if (consumerSource == null) { + // confirmed no source for consumer return true; - // work around the issue when the package is in the EE and we delegate to boot for that package + } + // if boot delegate just return true if (container.isBootDelegationPackage(pkgName)) { - Bundle systemBundle = container.getStorage().getModuleContainer().getModule(0).getBundle(); - SystemBundleLoader systemLoader = (SystemBundleLoader) getBundleLoader(systemBundle); - if (systemLoader.isExportedPackage(pkgName)) { - return true; // in this case we have a common source from the EE - } + return true; } + // 4) For the registrant bundle, find the wiring for the package. - PackageSource producerSource = producerBL.getPackageSource(pkgName); + PackageSource producerSource = getSourceFromLoader(producerBL, pkgName, className, checkInternal); if (producerSource == null) { + // confirmed no local class either; now check service object if (serviceClass != null && ServiceFactory.class.isAssignableFrom(serviceClass)) { @SuppressWarnings("deprecation") Bundle bundle = container.getPackageAdmin().getBundle(serviceClass); - if (bundle != null && bundle != registrant) + if (bundle != null && bundle != registrant) { // in this case we have a wacky ServiceFactory that is doing something we cannot - // verify if it is correct. Instead of failing we allow the assignment and hope for the best + // verify if it is correct. Instead of failing we allow the assignment and hope + // for the best // bug 326918 return true; + } } - // 5) If no wiring is found for the registrant bundle then find the wiring for the classloader of the service object. If no wiring is found return false. - producerSource = getPackageSource(serviceClass, pkgName, container.getPackageAdmin()); - if (producerSource == null) + // 5) If no wiring is found for the registrant bundle then find the wiring for + // the classloader of the service object. If no wiring is found return false. + producerSource = getPackageSource(serviceClass, pkgName, className, checkInternal, + container.getPackageAdmin()); + if (producerSource == null) { return false; + } } // 6) If the two wirings found are equal then return true; otherwise return false. return producerSource.hasCommonSource(consumerSource); } - private static PackageSource getPackageSource(Class<?> serviceClass, String pkgName, @SuppressWarnings("deprecation") PackageAdmin packageAdmin) { - if (serviceClass == null) + private static PackageSource getSourceFromLoader(BundleLoader loader, String pkgName, String className, + boolean checkInternal) { + PackageSource source = loader.getPackageSource(pkgName); + if (source != null || !checkInternal) { + return source; + } + try { + if (loader.findLocalClass(className) != null) { + // create a source that represents the private package + return (new SingleSourcePackage(pkgName, loader)); + } + } catch (ClassNotFoundException e) { + // ignore + } + return null; + } + + private static PackageSource getPackageSource(Class<?> serviceClass, String pkgName, String className, + boolean checkInternal, + @SuppressWarnings("deprecation") PackageAdmin packageAdmin) { + if (serviceClass == null) { return null; + } @SuppressWarnings("deprecation") Bundle serviceBundle = packageAdmin.getBundle(serviceClass); - if (serviceBundle == null) + if (serviceBundle == null) { return null; + } BundleLoader producerBL = getBundleLoader(serviceBundle); - if (producerBL == null) + if (producerBL == null) { return null; - PackageSource producerSource = producerBL.getPackageSource(pkgName); - if (producerSource != null) + } + PackageSource producerSource = getSourceFromLoader(producerBL, pkgName, className, checkInternal); + if (producerSource != null) { return producerSource; + } // try the interfaces Class<?>[] interfaces = serviceClass.getInterfaces(); // note that getInterfaces never returns null for (Class<?> intf : interfaces) { - producerSource = getPackageSource(intf, pkgName, packageAdmin); - if (producerSource != null) + producerSource = getPackageSource(intf, pkgName, className, checkInternal, packageAdmin); + if (producerSource != null) { return producerSource; + } } // try super class - return getPackageSource(serviceClass.getSuperclass(), pkgName, packageAdmin); + return getPackageSource(serviceClass.getSuperclass(), pkgName, className, checkInternal, packageAdmin); } private static BundleLoader getBundleLoader(Bundle bundle) { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java index fe62d5a07..7ff945e6b 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/log/EventAdminAdapter.java @@ -13,8 +13,12 @@ *******************************************************************************/ package org.eclipse.osgi.internal.log; -import java.util.*; -import org.osgi.framework.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; @@ -42,8 +46,8 @@ public class EventAdminAdapter implements ServiceTrackerCustomizer<Object, Objec } public void start() { - eventAdminTracker.open(); - eventHandlerTracker.open(); + eventAdminTracker.open(true); + eventHandlerTracker.open(true); } public void stop() { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java index 7468872f8..e57ae096f 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/FilteredServiceListener.java @@ -17,7 +17,14 @@ package org.eclipse.osgi.internal.serviceregistry; import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.BundleContextImpl; import org.eclipse.osgi.internal.framework.FilterImpl; -import org.osgi.framework.*; +import org.osgi.framework.AllServiceListener; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceListener; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.UnfilteredServiceListener; import org.osgi.framework.hooks.service.ListenerHook; /** @@ -104,7 +111,7 @@ class FilteredServiceListener implements ServiceListener, ListenerHook.ListenerI if (event == null) { return; } - if (allservices || ServiceRegistry.isAssignableTo(context, reference)) { + if (allservices || ServiceRegistry.isAssignableTo(context, objectClass, reference)) { if (debug.DEBUG_EVENTS) { String listenerName = listener.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(listener)); //$NON-NLS-1$ Debug.println("dispatchFilteredServiceEvent(" + listenerName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java index 9beea76de..f04cf4270 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceReferenceImpl.java @@ -182,7 +182,7 @@ public class ServiceReferenceImpl<S> implements ServiceReference<S> { */ @Override public boolean isAssignableTo(Bundle bundle, String className) { - return registration.isAssignableTo(bundle, className); + return registration.isAssignableTo(bundle, className, true); } /** diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java index c81a64bfd..5f642f5f6 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistrationImpl.java @@ -696,8 +696,9 @@ public class ServiceRegistrationImpl<S> implements ServiceRegistration<S>, Compa } } - boolean isAssignableTo(Bundle client, String className) { - return PackageSource.isServiceAssignableTo(bundle, client, className, service.getClass(), context.getContainer()); + boolean isAssignableTo(Bundle client, String className, boolean checkInternal) { + return PackageSource.isServiceAssignableTo(bundle, client, className, service.getClass(), checkInternal, + context.getContainer()); } /** diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java index 36ceb9790..4b9092167 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/serviceregistry/ServiceRegistry.java @@ -348,7 +348,7 @@ public class ServiceRegistry { } catch (IllegalStateException e) { continue; // got unregistered, don't return reference } - if (allservices || isAssignableTo(context, reference)) { + if (allservices || isAssignableTo(context, clazz, reference)) { try { /* test for permission to get the service */ checkGetServicePermission(reference); } catch (SecurityException se) { @@ -1171,11 +1171,11 @@ public class ServiceRegistry { return true; } - static boolean isAssignableTo(BundleContextImpl context, ServiceReferenceImpl<?> reference) { + static boolean isAssignableTo(BundleContextImpl context, String clazz, ServiceReferenceImpl<?> reference) { Bundle bundle = context.getBundleImpl(); String[] clazzes = reference.getClasses(); for (int i = 0, len = clazzes.length; i < len; i++) - if (!reference.isAssignableTo(bundle, clazzes[i])) + if (!reference.getRegistration().isAssignableTo(bundle, clazzes[i], clazzes[i] == clazz)) return false; return true; } |