[ https://issues.apache.org/jira/browse/FELIX-3761?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13498685#comment-13498685 ]
Guillaume Nodet commented on FELIX-3761: ---------------------------------------- I'm proposing the following patch, which is only about removing the bundle lock access in the Felix#registerService method {code} 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 8ffec89..08b6d90 100644 --- a/framework/src/main/java/org/apache/felix/framework/Felix.java +++ b/framework/src/main/java/org/apache/felix/framework/Felix.java @@ -3446,51 +3446,32 @@ public class Felix extends BundleImpl implements Framework 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(bundle, 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. if (ServiceRegistry.isHook( {code} > When a bundle registers a service, the bundle lock is obtained without any > real purpose > --------------------------------------------------------------------------------------- > > Key: FELIX-3761 > URL: https://issues.apache.org/jira/browse/FELIX-3761 > Project: Felix > Issue Type: Bug > Affects Versions: framework-4.0.2 > Reporter: Guillaume Nodet > > It leads to the following kind of deadlocks: > {code} > "Felix WebConsole worker" Id=170 in WAITING on > lock=[Ljava.lang.Object;@108a93d9 > at java.lang.Object.wait(Native Method) > at java.lang.Object.wait(Object.java:485) > at org.apache.felix.framework.Felix.acquireBundleLock(Felix.java:5203) > at org.apache.felix.framework.Felix.registerService(Felix.java:3452) > at > org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:346) > at > org.apache.felix.framework.BundleContextImpl.registerService(BundleContextImpl.java:320) > at > org.apache.felix.webconsole.internal.core.BundlesServlet.activate(BundlesServlet.java:132) > at > org.apache.felix.webconsole.internal.servlet.PluginHolder$InternalPlugin.doGetConsolePlugin(PluginHolder.java:752) > at > org.apache.felix.webconsole.internal.servlet.PluginHolder$Plugin.getConsolePlugin(PluginHolder.java:535) > at > org.apache.felix.webconsole.internal.servlet.PluginHolder.getPlugin(PluginHolder.java:205) > at > org.apache.felix.webconsole.internal.servlet.OsgiManager.initInternalPlugins(OsgiManager.java:1016) > at > org.apache.felix.webconsole.internal.servlet.OsgiManager.doUpdateConfiguration(OsgiManager.java:981) > at > org.apache.felix.webconsole.internal.servlet.OsgiManager$6.run(OsgiManager.java:930) > at > org.apache.felix.webconsole.internal.servlet.Executor$Worker.run(Executor.java:67) > "FelixFrameworkWiring" Id=168 in WAITING on lock=java.lang.Object@3d6bca49 > at java.lang.Object.wait(Native Method) > at java.lang.Object.wait(Object.java:485) > at > org.apache.felix.webconsole.internal.servlet.Executor.shutdown(Executor.java:45) > - locked org.apache.felix.webconsole.internal.servlet.Executor@21875b11 > at > org.apache.felix.webconsole.internal.servlet.OsgiManager.dispose(OsgiManager.java:407) > at > org.apache.felix.webconsole.internal.KarafOsgiManagerActivator.stop(KarafOsgiManagerActivator.java:52) > at > org.apache.felix.framework.util.SecureAction.stopActivator(SecureAction.java:667) > at org.apache.felix.framework.Felix.stopBundle(Felix.java:2604) > at org.apache.felix.framework.Felix$RefreshHelper.stop(Felix.java:4961) > at org.apache.felix.framework.Felix.refreshPackages(Felix.java:4203) > at > org.apache.felix.framework.FrameworkWiringImpl.run(FrameworkWiringImpl.java:172) > at java.lang.Thread.run(Thread.java:680) > {code} > There's really no need to grab the bundle lock because the bundle is > necessarily starting / active / stopping, else an exception would have been > thrown when calling the registerService because the BundleContext object > would have been invalidated, and the registry itself is synchronized. -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira