Felix
  1. Felix
  2. FELIX-3096

Could not add FrameworkListener from ServiceListener

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: framework-3.2.2
    • Fix Version/s: framework-4.0.0
    • Component/s: None
    • Labels:
      None

      Description

      It's now impossible to add a FrameworkListener from ServiceListener in 3.2.x, worked in 3.0.9. The code below hangs in addFrameworkListener when it tries to acquire a global lock on the framework bundle.

      Framework framework = ...
      framework.init();

      final BundleContext ctx = framework.getBundleContext();
      ctx.addServiceListener(new ServiceListener() {
      public void serviceChanged(ServiceEvent event) {
      if (...) {
      ctx.addFrameworkListener(new FrameworkListener() {
      public void frameworkEvent(FrameworkEvent event)

      { System.out.println(event); }

      });
      }
      }
      });

      StartLevel sl = (StartLevel) ctx.getService(ctx.getServiceReference(StartLevel.class.getName()));

      // Install bundles, set start level.
      ...

      framework.start();
      framework.waitForStop();

        Activity

        Hide
        Felix Meschberger added a comment -

        You might want to check with the latest trunk build which has a fix for FELIX-3000 committed. That calls the listeners without holding a lock any more.

        Show
        Felix Meschberger added a comment - You might want to check with the latest trunk build which has a fix for FELIX-3000 committed. That calls the listeners without holding a lock any more.
        Hide
        Richard S. Hall added a comment -

        I think this issue is different than FELIX-3000. The system bundle lock is being held because it is in the middle of being started, but on the start level thread (which is how the framework ultimately starts up its bundles) the outer listener code is being invoked, which requires the system bundle's lock to add a listener.

        Technically, this is correct. It is a perfect example of what not to do, block the incoming thread and then make a call back into the framework on another thread. Of course, this one happens due to how the framework starts up...perhaps one approach would be to not use the start level thread on the initial start up of the framework so the startup would all happen on the same thread and thus the lock could be reentered.

        I'll have to think about it.

        Show
        Richard S. Hall added a comment - I think this issue is different than FELIX-3000 . The system bundle lock is being held because it is in the middle of being started, but on the start level thread (which is how the framework ultimately starts up its bundles) the outer listener code is being invoked, which requires the system bundle's lock to add a listener. Technically, this is correct. It is a perfect example of what not to do, block the incoming thread and then make a call back into the framework on another thread. Of course, this one happens due to how the framework starts up...perhaps one approach would be to not use the start level thread on the initial start up of the framework so the startup would all happen on the same thread and thus the lock could be reentered. I'll have to think about it.
        Hide
        Richard S. Hall added a comment -

        After more investigation, I think I've come to a way to resolve this. Due to some unrelated event dispatching refactoring for R4.3, we might be able to allow listeners to be added without holding the bundle lock. I still need to investigate it a little more, but so far so good.

        Show
        Richard S. Hall added a comment - After more investigation, I think I've come to a way to resolve this. Due to some unrelated event dispatching refactoring for R4.3, we might be able to allow listeners to be added without holding the bundle lock. I still need to investigate it a little more, but so far so good.
        Hide
        Richard S. Hall added a comment -

        It should be working now in trunk. We avoid holding the bundle lock for adding listeners by double checking if the bundle context is still valid before adding the listener, which is guaranteed to happen before a bundle's listeners are removed when it is stopped or fail if it happens after.

        Please close this issue if satisfied, thanks.

        Show
        Richard S. Hall added a comment - It should be working now in trunk. We avoid holding the bundle lock for adding listeners by double checking if the bundle context is still valid before adding the listener, which is guaranteed to happen before a bundle's listeners are removed when it is stopped or fail if it happens after. Please close this issue if satisfied, thanks.

          People

          • Assignee:
            Richard S. Hall
            Reporter:
            Vlad Arkhipov
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development