Uploaded image for project: 'Felix'
  1. Felix
  2. FELIX-5570

Immediate service component that provides a WeavingHook results in an NPE

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • scr-2.0.8
    • None
    • None

    Description

      If you have an immediate service component that provides a WeavingHook service then an NPE will result. An example service component XML:

      <?xml version="1.0" encoding="UTF-8"?>
      <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" immediate="true" name="Test Patches Weaver">
      <implementation class="test.patches.Weaver" />
      <service>
      <provide interface="org.osgi.framework.hooks.weaving.WeavingHook"/>
      </service>
      </scr:component>

      If you deploy this bundle along with SCR 2.0.8 on Felix Framework 5.6.2 the following NPE happens:

      ERROR: [Test Patches Weaver(0)] Error during instantiation of the implementation object
      java.lang.NullPointerException
      at org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:237)
      at org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:109)
      at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:906)
      at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:879)
      at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:823)
      at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:347)
      at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:247)
      at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:350)
      at org.apache.felix.framework.Felix.getService(Felix.java:3720)
      at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.transformClass(BundleWiringImpl.java:2359)
      at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2052)
      at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1518)
      at org.apache.felix.framework.BundleWiringImpl.access$200(BundleWiringImpl.java:79)
      at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1958)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1925)
      at org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:978)
      at org.apache.felix.scr.impl.manager.AbstractComponentManager.initDependencyManagers(AbstractComponentManager.java:976)
      at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1003)
      at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:859)
      at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:749)
      at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:675)
      at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:430)
      at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657)
      at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341)
      at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:390)
      at org.apache.felix.scr.impl.Activator.access$200(Activator.java:54)
      at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:265)
      at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:254)
      at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:227)
      at org.apache.felix.utils.extender.AbstractExtender.addingBundle(AbstractExtender.java:187)
      at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:469)
      at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:415)
      at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
      at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229)
      at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444)
      at org.apache.felix.framework.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:915)
      at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:834)
      at org.apache.felix.framework.EventDispatcher.fireBundleEvent(EventDispatcher.java:516)
      at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4562)
      at org.apache.felix.framework.Felix.activateBundle(Felix.java:2229)
      at org.apache.felix.framework.Felix.startBundle(Felix.java:2144)
      at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1371)
      at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
      at java.lang.Thread.run(Thread.java:745)

      This is because SCR is invoking SingleComponentManager.getServiceInternal after registering the WeavingHook service in order to get the service object for immediate activation. This ends up trying to load the test.patches.Weaver implementation class which then causes the framework to look for WeavingHooks to call. Which causes a recursive call back into SingleComponentManager.getServiceInternal for the same service component which triggers another load of the implementation class. Here Felix framework detects a recursive class load for the same class name and returns null from Bundle.loadClass() (Something I think is not correct, I think instead a CNFE must be thrown or some other class loader LinkageError).

      This null class results in the above NPE. I found this bug while running SCR on the Equinox framework. On Equinox a CNFE is thrown and logged by SCR and things seem to recover from that but we are left with an error message in the log making it look like things are not working.

      Both Equinox and Felix seem to detect the recursive class load that SCR is causing but handle the situation slightly different. In both cases I argue that SCR should avoid recursive calls into SingleComponentManager.getServiceInternal for the same service component.

      The difficulty here is that SCR can depend on the framework to avoid recursive calls into its ServiceFactory because the specification mandates that (see org.osgi.framework.ServiceException.FACTORY_RECURSION). But here SCR is invoking SingleComponentManager.getServiceInternal itself and an internal implementation detail of an immediate service component. It seems that for this internal call to SingleComponentManager.getServiceInternal something should be done to prevent recurse calls so that this is consistent with how non-immediate components work.

      Also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=512707

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              tjwatson Tom Watson
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated: