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)