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