Thomas Watson created FELIX-5570:
------------------------------------

             Summary: Immediate service component that provides a WeavingHook 
results in an NPE
                 Key: FELIX-5570
                 URL: https://issues.apache.org/jira/browse/FELIX-5570
             Project: Felix
          Issue Type: Bug
          Components: Declarative Services (SCR)
    Affects Versions: scr-2.0.8
            Reporter: Thomas Watson


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



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to