I ran into a problem with Equinox 3.5.1.R35x_v20090806:

In my log file I find the following exception stack trace after calling 
PackageAdmin.refreshPackages(null).

org.osgi.framework.BundleException: Exception in 
com.tibco.xxx.Activator.start() of bundle com.tibco.xxx.
        at 
org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:805)
        at 
org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:754)
        at 
org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:352)
        at 
org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:280)
        at 
org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:272)
        at com.tibco.xxx.refreshRuntime(xxx.java:872)
        at com.tibco.xx.access$6(xxxImpl.java:569)
        at com.tibco.xxx$2.run(xxxImpl.java:229)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.IllegalStateException: The service has been unregistered
        at 
org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.getReferenceImpl(ServiceRegistrationImpl.java:277)
        at 
org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.lookupServiceRegistrations(ServiceRegistry.java:867)
        at 
org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.getServiceReferences(ServiceRegistry.java:290)
        at 
org.eclipse.osgi.framework.internal.core.BundleContextImpl.getAllServiceReferences(BundleContextImpl.java:577)
        at 
org.osgi.util.tracker.ServiceTracker.getInitialReferences(ServiceTracker.java:360)
        at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:321)
        at com.tibco.xxx.start(xxx.java:150)
        at com.tibco.xxx.Activator.start(Activator.java:39)
        at 
org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:782)
        at java.security.AccessController.doPrivileged(Native Method)
        at 
org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:773)

The exception is thrown while starting a bundle after the refreshPackages call. 
I assume the refreshThread is still ongoing in the background and as part of 
the process stops and restarts bundles, which causes OSGi services to be 
unregistered and then (hopefully) registered again.

The ServiceTracker of the bundle that is started wants to look for all services 
that have a certain property set. However, during the initial scan of all 
services, one of them is unregistered, which causes the seen exception.

There seems to be a race condition in which lookupServiceRegistrations() 
acquires the lock to ServiceRegistry and copies the results to an ArrayList.

        private List lookupServiceRegistrations(String clazz, Filter filter) {
                List result;
                synchronized (this) {
                        if (clazz == null) { /* all services */
                                result = allPublishedServices;
                        } else {
                                /* services registered under the class name */
                                result = (List) 
publishedServicesByClass.get(clazz);
                        }

                        if ((result == null) || (result.size() == 0)) {
                                return Collections.EMPTY_LIST;
                        }

                        result = new ArrayList(result); /* make a new list 
since we don't want to change the real list */
                }

In the meantime the service is unregistered and removed from 
allPublishedServices:

        void removeServiceRegistration(BundleContextImpl context, 
ServiceRegistrationImpl serviceReg) {
                // Remove the ServiceRegistrationImpl from the list of Services 
published by BundleContextImpl.
                List contextServices = (List) 
publishedServicesByContext.get(context);
                if (contextServices != null) {
                        contextServices.remove(serviceReg);
                }

                // Remove the ServiceRegistrationImpl from the list of Services 
published by Class Name.
                String[] clazzes = serviceReg.getClasses();
                for (int i = 0, size = clazzes.length; i < size; i++) {
                        String clazz = clazzes[i];
                        List services = (List) 
publishedServicesByClass.get(clazz);
                        services.remove(serviceReg);
                }

                // Remove the ServiceRegistrationImpl from the list of all 
published Services.
                allPublishedServices.remove(serviceReg);
        }

However, lookupServiceRegistrations() goes on to iterate over the result list 
and runs into the exception above.

                for (Iterator iter = result.iterator(); iter.hasNext();) {
                        ServiceRegistrationImpl registration = 
(ServiceRegistrationImpl) iter.next();
                        if (!filter.match(registration.getReferenceImpl())) {
                                iter.remove();
                        }
                }


Has anyone seen this? Is this a know problem? I guess I could file a bug for 
this.

Thanks,

   Tim.

"It is a simple task to make things complex, but a complex task to make them 
simple."
 -- Fortune Cookie

_______________________________________________
equinox-dev mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/equinox-dev

Reply via email to