[ 
https://issues.apache.org/jira/browse/FELIX-341?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12523829
 ] 

Felix Meschberger commented on FELIX-341:
-----------------------------------------

Rajini provided me with additional testcase instructions, which showed the 
following behaviour:

Consider Bundle B1 with Component C1 registered as a service and Bundle B2 with 
Component C2 registered as a service. C1 has a mandatory dependency on C2 and 
B1 is started before B2.

When the framework is shut down, B2 is stopped before B1. While stopping B2, 
Component C2 is unregistered as a service and deactivated. As a result C1 is to 
be deactivated and hence unregistered as a service. This deactivation of C1 is 
launched asynchronously such that B1 will not deactivate C1 as it already is 
assumed to be deactivated.

Due to timing issues the asynchronous deactivation of C1 may be delayed such 
that service registration of C1 is unregistered by the framework due to Bundle 
B1 stop before C1 deactivation could unregister the service. This could cause  
trying to unregister the same service twice and hence the IllegalStateException.

Though this seems to be a multithreading corner case, there is another catch 
with asynchronously deactivating components due to unregistered services: If a 
component has a dependency on another service, it should be notified of the 
removal of the service as fast as possible. Hence, this situation should be 
handled synchronously to the service unregistration notice. So the fix is to 
immediately deactivate the depending component and schedule the reactivation 
asynchronously.

At the same time I add more logging and more security to not activate 
components while the owning bundle is actually shutting down.

> Intermittent exception during Felix shutdown
> --------------------------------------------
>
>                 Key: FELIX-341
>                 URL: https://issues.apache.org/jira/browse/FELIX-341
>             Project: Felix
>          Issue Type: Bug
>          Components: Declarative Services
>    Affects Versions: 1.0.0
>            Reporter: Rajini Sivaram
>            Assignee: Felix Meschberger
>
> One of my testcases intermittently throws an exception during shutdown. I 
> have managed to recreate the exception under a debugger, and it shows two 
> threads trying to unregister the same service. The test fails only when 
> declarative services are used. I am using Felix 1.0.0 framework and the 
> latest snapshot of SCR. The test uses multiple versions of a bundle, but I am 
> not sure if that has anything to do with the exception.
>  
> The exception thrown is:
>  
>     --- Exception with component : Unexpected problem executing task ---
>     java.lang.IllegalStateException: Service already unregistered.
>         at org.apache.felix.framework.ServiceRegistrationImpl.unregister 
> (ServiceRegistrationImpl.java:105)
>         at 
> org.apache.felix.scr.AbstractComponentManager.unregisterComponentService(AbstractComponentManager.java:503)
>         at org.apache.felix.scr.AbstractComponentManager.deactivateInternal 
> (AbstractComponentManager.java:369)
>         at 
> org.apache.felix.scr.AbstractComponentManager.access$200(AbstractComponentManager.java:55)
>         at 
> org.apache.felix.scr.AbstractComponentManager$3.run(AbstractComponentManager.java
>  :176)
>         at 
> org.apache.felix.scr.ComponentActorThread.run(ComponentActorThread.java:81)
>  
> Here is the stack trace of the two threads under the debugger (both are using 
> the same object):
>  
>                 Thread [FelixStartLevel] (Suspended (breakpoint at line 97 in 
> ServiceRegistrationImpl))
>                         ServiceRegistrationImpl.unregister() line: 97
>                         ServiceRegistry.unregisterServices (Bundle) line: 119
>                         Felix._stopBundle(FelixBundle, boolean) line: 1946
>                         Felix.stopBundle(FelixBundle, boolean) line: 1866
>                         Felix.setFrameworkStartLevel (int) line: 1080
>                         StartLevelImpl.run() line: 258
>                         Thread.run() line: 803
>                 Thread [SCR Component Actor] (Suspended (breakpoint at line 
> 97 in ServiceRegistrationImpl))
>                         ServiceRegistrationImpl.unregister() line: 97
>                         
> ImmediateComponentManager(AbstractComponentManager).unregisterComponentService()
>  line: 503 
>                         
> ImmediateComponentManager(AbstractComponentManager).deactivateInternal() 
> line: 369
>                         
> AbstractComponentManager.access$200(AbstractComponentManager) line: 55
>                         AbstractComponentManager$3.run() line: 176 
>                         ComponentActorThread.run() line: 81
>  
>  
> The exception thrown is the IllegalStateException from
>     public void unregister()
>     {
>         if (m_svcObj != null)
>         {
>             m_registry.unregisterService(m_bundle, this);
>             m_svcObj = null;
>             m_factory = null;
>         } 
>         else
>         {
>             throw new IllegalStateException("Service already unregistered.");
>         }
>     }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to