[FELIX-3761] When a bundle registers a service, the bundle lock is obtained without any real purpose
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1421958 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index d7bbfa0..bbdd980 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -343,7 +343,7 @@
}
}
- return m_felix.registerService(m_bundle, clazzes, svcObj, dict);
+ return m_felix.registerService(this, clazzes, svcObj, dict);
}
public <S> ServiceRegistration<S> registerService(
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index b360a61..b72d606 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -763,6 +763,10 @@
// so create a gate for that purpose.
m_shutdownGate = new ThreadGate();
+ // Start services
+ m_fwkWiring.start();
+ m_fwkStartLevel.start();
+
try
{
Felix.m_secureAction.startActivator(
@@ -3258,7 +3262,7 @@
* @return A <code>ServiceRegistration</code> object or null.
**/
ServiceRegistration registerService(
- BundleImpl bundle, String[] classNames, Object svcObj, Dictionary dict)
+ BundleContextImpl context, String[] classNames, Object svcObj, Dictionary dict)
{
if (classNames == null)
{
@@ -3269,50 +3273,31 @@
throw new IllegalArgumentException("Service object cannot be null.");
}
- // Acquire bundle lock.
- try
- {
- acquireBundleLock(bundle, Bundle.STARTING | Bundle.ACTIVE | Bundle.STOPPING);
- }
- catch (IllegalStateException ex)
- {
- throw new IllegalStateException(
- "Can only register services while bundle is active or activating.");
- }
-
ServiceRegistration reg = null;
- try
+ // Check to make sure that the service object is
+ // an instance of all service classes; ignore if
+ // service object is a service factory.
+ if (!(svcObj instanceof ServiceFactory))
{
- // Check to make sure that the service object is
- // an instance of all service classes; ignore if
- // service object is a service factory.
- if (!(svcObj instanceof ServiceFactory))
+ for (int i = 0; i < classNames.length; i++)
{
- for (int i = 0; i < classNames.length; i++)
+ Class clazz = Util.loadClassUsingClass(svcObj.getClass(), classNames[i], m_secureAction);
+ if (clazz == null)
{
- Class clazz = Util.loadClassUsingClass(svcObj.getClass(), classNames[i], m_secureAction);
- if (clazz == null)
- {
- throw new IllegalArgumentException(
- "Cannot cast service: " + classNames[i]);
- }
- else if (!clazz.isAssignableFrom(svcObj.getClass()))
- {
- throw new IllegalArgumentException(
- "Service object is not an instance of \""
- + classNames[i] + "\".");
- }
+ throw new IllegalArgumentException(
+ "Cannot cast service: " + classNames[i]);
+ }
+ else if (!clazz.isAssignableFrom(svcObj.getClass()))
+ {
+ throw new IllegalArgumentException(
+ "Service object is not an instance of \""
+ + classNames[i] + "\".");
}
}
+ }
- reg = m_registry.registerService(bundle, classNames, svcObj, dict);
- }
- finally
- {
- // Always release bundle lock.
- releaseBundleLock(bundle);
- }
+ reg = m_registry.registerService(context, classNames, svcObj, dict);
// Check to see if this a listener hook; if so, then we need
// to invoke the callback with all existing service listeners.
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
index d6e7e79..e6509ce 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
@@ -37,19 +37,25 @@
private static final int STARTLEVEL_IDX = 1;
private final Felix m_felix;
+ private final ServiceRegistry m_registry;
private final List m_requests = new ArrayList();
private final List<FrameworkListener[]> m_requestListeners
= new ArrayList<FrameworkListener[]>();
- private final ServiceRegistration<StartLevel> m_slReg;
+ private ServiceRegistration<StartLevel> m_slReg;
private Thread m_thread = null;
FrameworkStartLevelImpl(Felix felix, ServiceRegistry registry)
{
m_felix = felix;
- m_slReg = registry.registerService(felix,
- new String[] { StartLevel.class.getName() },
- new StartLevelImpl(felix),
- null);
+ m_registry = registry;
+ }
+
+ void start()
+ {
+ m_slReg = m_registry.registerService(m_felix._getBundleContext(),
+ new String[] { StartLevel.class.getName() },
+ new StartLevelImpl(m_felix),
+ null);
}
// Should only be called hold requestList lock.
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
index da7bfee..8ad803c 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
@@ -31,20 +31,26 @@
class FrameworkWiringImpl implements FrameworkWiring, Runnable
{
private final Felix m_felix;
+ private final ServiceRegistry m_registry;
private final List<Collection<Bundle>> m_requests = new ArrayList();
private final List<FrameworkListener[]> m_requestListeners
= new ArrayList<FrameworkListener[]>();
- private final ServiceRegistration<PackageAdmin> m_paReg;
+ private ServiceRegistration<PackageAdmin> m_paReg;
private Thread m_thread = null;
public FrameworkWiringImpl(Felix felix, ServiceRegistry registry)
{
m_felix = felix;
- m_paReg = registry.registerService(felix,
- new String[] { PackageAdmin.class.getName() },
- new PackageAdminImpl(felix),
- null);
+ m_registry = registry;
+ }
+
+ void start()
+ {
+ m_paReg = m_registry.registerService(m_felix._getBundleContext(),
+ new String[] { PackageAdmin.class.getName() },
+ new PackageAdminImpl(m_felix),
+ null);
}
/**
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
index b604de2..9bf5d31 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistry.java
@@ -23,6 +23,7 @@
import org.apache.felix.framework.capabilityset.SimpleFilter;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceException;
@@ -101,12 +102,14 @@
// Caller is expected to fire REGISTERED event.
public ServiceRegistration registerService(
- Bundle bundle, String[] classNames, Object svcObj, Dictionary dict)
+ BundleContext context, String[] classNames, Object svcObj, Dictionary dict)
{
ServiceRegistrationImpl reg = null;
synchronized (this)
{
+ Bundle bundle = context.getBundle();
+
// Create the service registration.
reg = new ServiceRegistrationImpl(
this, bundle, classNames, new Long(m_currentServiceId++), svcObj, dict);
diff --git a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
index c8c8a9e..6f3b92f 100644
--- a/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ServiceRegistryTest.java
@@ -42,6 +42,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
EventHook hook = new EventHook()
{
@@ -53,7 +58,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, hook, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {EventHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getHooks(EventHook.class).size());
assertTrue(sr.getHooks(EventHook.class).iterator().next() instanceof ServiceReference);
assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
@@ -73,6 +78,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
@@ -81,7 +91,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {EventHook.class.getName()}, sf, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {EventHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getHooks(EventHook.class).size());
assertSame(reg.getReference(), sr.getHooks(EventHook.class).iterator().next());
assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -100,6 +110,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
FindHook hook = new FindHook()
{
@@ -112,7 +127,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, hook, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {FindHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getHooks(FindHook.class).size());
assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
@@ -131,6 +146,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
@@ -139,7 +159,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {FindHook.class.getName()}, sf, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {FindHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getHooks(FindHook.class).size());
assertSame(reg.getReference(), sr.getHooks(FindHook.class).iterator().next());
assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -158,6 +178,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
ListenerHook hook = new ListenerHook()
{
@@ -173,7 +198,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {ListenerHook.class.getName()}, hook, new Hashtable());
assertEquals(1, sr.getHooks(ListenerHook.class).size());
assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
assertSame(hook, ((ServiceRegistrationImpl) reg).getService());
@@ -192,6 +217,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
MockControl sfControl = MockControl.createNiceControl(ServiceFactory.class);
sfControl.replay();
@@ -200,7 +230,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {ListenerHook.class.getName()}, sf, new Hashtable());
assertEquals(1, sr.getHooks(ListenerHook.class).size());
assertSame(reg.getReference(), sr.getHooks(ListenerHook.class).iterator().next());
assertSame(sf, ((ServiceRegistrationImpl) reg).getService());
@@ -219,6 +249,11 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
class CombinedService implements ListenerHook, FindHook, EventHook, Runnable
{
@@ -249,7 +284,7 @@
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {
+ ServiceRegistration reg = sr.registerService(c, new String [] {
Runnable.class.getName(),
ListenerHook.class.getName(),
FindHook.class.getName(),
@@ -276,12 +311,17 @@
Bundle b = (Bundle) control.getMock();
control.replay();
+ MockControl controlContext = MockControl.createNiceControl(BundleContext.class);
+ BundleContext c = (BundleContext) controlContext.getMock();
+ controlContext.expectAndReturn(c.getBundle(), b);
+ controlContext.replay();
+
ServiceRegistry sr = new ServiceRegistry(new Logger(), null);
String svcObj = "hello";
assertEquals("Precondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Precondition failed", 0, sr.getHooks(ListenerHook.class).size());
- ServiceRegistration reg = sr.registerService(b, new String [] {String.class.getName()}, svcObj, new Hashtable());
+ ServiceRegistration reg = sr.registerService(c, new String [] {String.class.getName()}, svcObj, new Hashtable());
assertEquals("Postcondition failed", 0, sr.getHooks(EventHook.class).size());
assertEquals("Postcondition failed", 0, sr.getHooks(FindHook.class).size());
assertEquals("Postcondition failed", 0, sr.getHooks(ListenerHook.class).size());
diff --git a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
index c4622a7..837167d 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
@@ -48,6 +48,7 @@
final Bundle b1 = getMockBundle();
final Bundle b2 = getMockBundle();
final Bundle b3 = getMockBundle();
+ final Bundle b4 = getMockBundle();
final Set calledHooks = new HashSet();
final EventHook eh1 = new EventHook()
@@ -79,8 +80,8 @@
Logger logger = new Logger();
ServiceRegistry registry = new ServiceRegistry(logger, null);
- registry.registerService(null, new String [] {EventHook.class.getName()}, eh1, new Hashtable());
- registry.registerService(null, new String [] {EventHook.class.getName()}, eh2, new Hashtable());
+ registry.registerService(b4.getBundleContext(), new String [] {EventHook.class.getName()}, eh1, new Hashtable());
+ registry.registerService(b4.getBundleContext(), new String [] {EventHook.class.getName()}, eh2, new Hashtable());
// -- Set up event dispatcher
EventDispatcher ed = new EventDispatcher(logger, registry);