Announcement Announcement Module
Collapse
No announcement yet.
Service listener does not pick up published service Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Service listener does not pick up published service

    Hi,

    I think I am running into classloading issue with scoped plans.

    Basically a service published by one bundle within a plan is not picked up by a listener defined in another bundle.

    Is there some way to trace service imported/exporter chain?

    I believe I am running into (http://www.osgi.org/javadoc/r4v42/or...lang.String%29) ServiceReference.isAssignableTo check that fails, but I can't figure out what might be causing it.

    Shouldn't class space within a plan be fairly consistent? Is there some gotchas to look out for? For example if publishing bundle is using explicit imports and consuming bundle is using Import-Bundle?

  • #2
    Interesting problem. The class space within the scope should be consistent. Also, Import-Bundle is expanded during deployment into a series of Import-Package header entries so you essentially are using Import-Package. It could be that there's a bug in the service scoping logic when a ServiceListener is used. We'll look into this today although I think it's unlikely as the hook that's used for scoping is only involved when the actual service is being looked up, whereas a ServiceListener deals with ServiceReferences. In the meantime, am I right to assume that both the bundles to which you refer are in the same scope?

    Comment


    • #3
      Andy,

      Thank you for follow up. This issue is really messing with my head

      Here is some additional info:

      Environment configuration:
      1. dm-server ci 517 (but also an issue in 509 for sure).
      2. Slices (custom build to account for deployer refactoring)
      3. OS: windows and osx

      We are deploying a scoped plan file with following bundles (names changed to protect innocent):
      1. web.host - Slices host web application
      2. web.host.menu - regular bundle contains MenuContribution for web.host (had to split in out from war file, because services were not being published from ServerOsgiBundleXmlWebApplicationContext - NOT an issue any more, but we just haven't moved them into web.host)
      3. web.child.core - Child slice #1 - this contains core ui components
      4. web.child.extension.1 - Child slice #2 - contains extensions to web.child.core
      5. etc - some other bundles to round up application (service tier, domain, repository, etc)

      Some library bundles are not deployed as part of the plan, i.e. just picked up from repository/usr because of manifest imports/usage. These bundles do not publish services, i.e. just static class contributors.
      Bundle (shared.ui) that contains interfaces for the services that we publish from web applications sits in repository/usr and is NOT included in the plan.

      web.host.menu - publishes MenuContribution services, to set-up top tier of menu structure.

      web.host bundle defines an osgi:list with a listener to account for dynamic contributions to the menu structure made by child slices.
      Code:
       <osgi:list id="menuContributions" interface="shared.ui.menu.MenuContribution" cardinality="0..N">
              <osgi:listener bind-method="onBind" unbind-method="onUnbind">
                  <bean class="shared.ui.menu.support.MenuContributionListener">
                      <constructor-arg ref="menuBuilder"/>
                  </bean>
              </osgi:listener>
          </osgi:list>
      web.child.core bundle defines an osgi:list with a listener to account for dynamic contribution made to the tabs displayed on individual ui pages.

      Code:
      <osgi:list id="contentContributions" interface="shared.ui.contrib.Contribution" cardinality="0..N">
              <osgi:listener bind-method="onBind" unbind-method="onUnbind">
                  <bean class="shared.ui.contrib.support.ContributionListener">
                      <constructor-arg ref="contributionManager"/>
                  </bean>
              </osgi:listener>
          </osgi:list>
      web.child.core bundle publishes one MenuContribution service and one Contribution service. Both of these services are picked up by corresponding listeners.

      web.child.extension.1 publishes one MenuContribution service and two (2) Contribution services. Only MenuContribution service is picked up by the listener. Neither of Contribution services is bound!

      But as soon as I refresh the web.child.extension.1 bundle or touch the plan, all services for all bundles are found and bound to the correct lists and listeners.
      Furthermore, if I move up web.child.extension.1 above the web.child.core in the plan - I do not have an issue and all services are found.

      The thing that messes with my head the most is that out of 3 services published by web.child.extension.1 only 2 are not seen by listener on initial deploy. The MenuContribution service is always properly bound/unbound. The Contribution service is published, I can see in the admin and console but bound is never called for the listener. Here is another kicker - unbound is called for Contribution services for which bound was never called!

      I tried paying with manifest headers. Making sure that everything is imported with the correct versions and all imports match between web.child.core and web.child.core.extension. So far with no luck.

      I looked at spring.osgi OsgiServiceCollection to figure out how osgi:list works. (It will bind a ServiceListener to bundle context and finds all services that were already registered and trigger serviceChanged event on the listener manually). That explains why moving web.child.extension.1 (publisher) before web.child.core (consumer) binds services properly.

      I hope all that rambling is providing value. I don't have enough knowledge on the service scoping logic in dmServer and grasping at straws right now. The only straw is class space inconsistency, i.e. BundleContext.getServiceReferences() vs. BundleContext.getAllServiceReferences() semantics.

      When looking at the package imports I was noticing some slight difference with the way shared.ui.contrib.support was imported in publisher vs. consumer. In consumer it was imported with version of 0.0.0 and in publisher with a correct version of 1.1.0.RC3-SNAPSHOT. Having said that - all imports for both consumer and publisher resolved to a correct bundle.

      Comment


      • #4
        Thanks, Dmitry. The above should really help us in starting to get to the bottom of those.

        As a first approach, I think our best bet in diagnosing this would be to try to recreate the problem. We can probably have a go based on your description above but it'd be great if you could provide us with a plan file and a collection of bundles that reproduce the problem.

        Would that be possible? If not, we can certainly make an attempt based on your description but my concern is that we may miss some subtlety that's the cause of the problem.

        Comment


        • #5
          Andy,

          I am trying to find time to put together an example but that would probably force me to rebuild our application from ground up

          I will see if I can rip out some parts of the app but need to get an ok from people above.

          Comment


          • #6
            We tried to create a simple app to demo the problem. Attached to https://issuetracker.springsource.com/browse/DMS-2261

            Comment

            Working...
            X