1
votes

I'm trying to debug a issue which seems to be caused by a weird behavior of one of my OSGi components during framework shutdown.

When I try to shutdown the framework by calling

context.getBundle(0).shutdown()

My component gets deactivated, but for some reason it is re-activated then deactivated again. The second activation/deactivation cycle is causing some weird behavior because the component registers with a "UI Container" which causes flickering in the UI of the application during shutdown.

My question is what could cause the second activation/deactivation cycle?

I'm using declarative services Maven, Apache Felix and the SCR plugin.


The links below are to the stack traces from the deactivate/re-activate/deactivate methods which where requested in an answer below:

deactivate stacktrace

re-activate stacktrace

deactivate stacktrace

1
Maybe you have any cycling dependencies, or 2 different bundles provide a version of package which could satisfy your bundle's dependency. - white
@white I don't think I have cyclic dependencies, that would probably cause the application to fail at startup. Could you please explain with more detail what you mean with "2 different bundles provide ..."? - Denis Rosca
Imagine your bundle depends on some.package that is f.ex. version [2.0,3.0), and bundle1 provides some.package(v2.1), bundle2 provides some.package(v2.2), and you are wired to bundle2. When bundle2 is stopped your bundle is stopped to, than wired to bundle1 and started again. - white
@white thank you, I'll double check and let you know. - Denis Rosca
bundle2 will not be re-wired until a package refresh is triggered. - Balazs Zsoldos

1 Answers

2
votes

I write an answer as it is longer than a comment can be (and it might be the answer):

  • ConfigAdmin stops before DS and the bundle that contains your component
  • When ConfigAdmin stops, it fires an event that the configuration is not available anymore
  • Your component is configured in the way that configuration is not required so it stops due to the reason that the already existing configuration disappears and re-activates as configuration is not necessary for the component

To find out if this is the case, please insert to following into your activate and deactivate functions:

Thread.dumpStack();

Then copy the stack traces into your question.

If this is the case, you can solve it by setting the configuration policy to be required on your component.

Update

What I did (and you can do as well) to compare the stack trace of deactivation and reactivation. You will find useful information where differences start.

Based on the uploaded stack traces: A component that provides an indirectly referenced service is deactivated and than activated again. Reason:

One of its dependencies (reference disappears) but another one satisfies the component.

The interesting part of the reactivation stack trace is the following:

at org.apache.felix.scr.impl.manager.AbstractComponentManager$3.register(AbstractComponentManager.java:972)
at org.apache.felix.scr.impl.manager.RegistrationManager.changeRegistration(RegistrationManager.java:134)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.registerService(AbstractComponentManager.java:1024)
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:818)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:946)
at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:871)
at org.apache.felix.scr.impl.manager.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1503)

If you can, please add a break point to the activate function of your component. During the reactivation, see the stack trace and go the the following line:

at org.apache.felix.scr.impl.manager.DependencyManager$SingleStaticCustomizer.removedService(DependencyManager.java:946)

See why the reactivate flag in the source code has the value true and the value of the serviceReference parameter of the removedService function. Find out also in the debug view, in which component you are at this point of the stack trace. As a result, you will know, which component is reactivated and based on which service reference. You can than reconfigure the component to wire only a unique service reference.

I would also consider writing a mail to the felix mailing list to calculate the reactivate flag in the way that if the system bundle is in stopping state, it should not reactivate the component.