You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by Dieter Wimberger <di...@wimpi.net> on 2008/06/27 23:46:49 UTC

General questions about starting and stopping bundles

Hi all,

I have got some general questions about starting and stopping bundles.

Given that I made my first OSGi steps with Knopflerfish, I have  
usually been following their general recommendations on bundle design:
http://www.knopflerfish.org/programming.html

Starting:
Konpflerfish seems to suggest to spawn a thread if bundle activation  
is supposed to take a while.
(See section "Spawning a startup thread").

This basically translates to the following construct:

  public void start(final BundleContext bundleContext) throws  
Exception {
     c_BundleContext = bundleContext;

     Thread t = new Thread(
         new Runnable() {
           public void run() {
             ///do start logic
           }//run
         }//Runnable
     );//Thread

     t.setContextClassLoader(getClass().getClassLoader());
     t.start();
   }//start


Is this approach recommendable? Are there side-effects that could be  
container dependent?

Stopping:
Knopflerfish seems to assume that when a bundle is stopped, the  
framework should be taking care about unregistering services.
(See "Automatic cleanup of services")

Is this generally valid or container dependent?
Also, does this also apply to Listener instances (like for example a  
ServiceListener) and service references that are being used?
I.e. is there a need to call BundleContext.removeService/ 
FrameworkListener() or m_BundleContext.ungetService() for cleanup?

Any comments and answers are appreciated.

Regards,
Dieter




Re: General questions about starting and stopping bundles

Posted by Alin Dreghiciu <ad...@gmail.com>.
On Tue, Jul 1, 2008 at 10:41 PM, Dieter Wimberger <di...@wimpi.net> wrote:
> Alin:
>
>> The specs does not mandate this but I see it as a best practice when
>> the start method does not return in a "timely manner". Having this
>> thread also means that you must take care to stop the thread during
>> BundleActivator.stop as it can be that stop is called before your
>> starting thread ends.
>>
>
> You are making a good point here, except that I think that "stopping" is
> maybe not a good choice.
> Actually it's not recommendable to stop threads at all, it is a thread
> primitive that has been deprecated a while ago:
> http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html

By stopping threads I just wanted to say that those threads must stop
running not that the stop method must be called on the thread. Is it
up to you how do you stop the threads.

>
> However, it may make sense to handle this case, and maybe to join the start
> thread before proceeding with a stop.
>
> As a side note, I always found it semantically strange to have "starting"
> and "stopping" as states (4.3.2 Bundle States), rather than "transitions".
>
>
>>>
>>> Stopping:
>>> Knopflerfish seems to assume that when a bundle is stopped, the framework
>>> should be taking care about unregistering services.
>>> (See "Automatic cleanup of services")
>>>
>>> Is this generally valid or container dependent?
>>
>> This is mandated by the core specs (section 4.3.6 on specs 4.0.1).
>>
>>> Also, does this also apply to Listener instances (like for example a
>>> ServiceListener) and service references that are being used?
>>> I.e. is there a need to call
>>> BundleContext.removeService/FrameworkListener()
>>> or m_BundleContext.ungetService() for cleanup?
>>
>> In principle you should "undo" what you did during start, so release
>> resources, stop started threads, ...
>
> Good point, with the same exception as above (stopping threads may not be a
> good idea).
>
>
>> There is no need to unregister services registered during startup or
>> framework listeners because they will be cleaned up by the framework
>> after the stop method returns. Also, any services used by the bundle
>> being stopped will be released automatically by the framework.
>> But recall that other bundles that still have references to your
>> service will still be able to call your service so you may wanna play
>> defense and handle this case even if I consider this a programming
>> error from the point of view of the bundle that still uses the service
>> even if the service has been unregistered. When I wanna do that I
>> usually implement the service using a state service and by the moment
>> the bundle is stopped or the service s unregistered I change the
>> internal state of the service to stopped, state where I throw an
>> meaningful exception. But is a lot of work in plus that does not bring
>> real value to your service, it only helps the developer of the bundle
>> that is still using the invalid service to think about the fact that
>> he should not use anymore the service after it has been unregistered.
>>
>
> I usually try to design the use of other services in a way that allows "come
> and go". i.e. using a mediated reference instead of obtaining one and
> holding it; and kind of doing request/response transactions.
>
> However, I have come to the conclusion that if state needs to be maintained
> between calls to a service, then it is actually much more complex to handle
> (and design for) the "come and go" situation.
>
> Regards,
> Dieter
>
>



-- 
Alin Dreghiciu
http://www.ops4j.org - New Energy for OSS Communities - Open
Participation Software.
http://www.qi4j.org - New Energy for Java - Domain Driven Development.
http://malaysia.jayway.net - New Energy for Projects - Great People
working on Great Projects at Great Places

Re: General questions about starting and stopping bundles

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Dieter Wimberger wrote:
> Alin:
>
>> The specs does not mandate this but I see it as a best practice when
>> the start method does not return in a "timely manner". Having this
>> thread also means that you must take care to stop the thread during
>> BundleActivator.stop as it can be that stop is called before your
>> starting thread ends.
>>
>
> You are making a good point here, except that I think that "stopping" 
> is maybe not a good choice.
> Actually it's not recommendable to stop threads at all, it is a thread 
> primitive that has been deprecated a while ago:
> http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html 
>
>
> However, it may make sense to handle this case, and maybe to join the 
> start thread before proceeding with a stop.
>
> As a side note, I always found it semantically strange to have 
> "starting" and "stopping" as states (4.3.2 Bundle States), rather than 
> "transitions".

Well, I think the suggestion was intended to say, "make sure the threads 
exit properly"...since this is all in one bundle, I assume that you 
would be able to set some flag on the thread to make it stop...

-> richard

>
>
>>>
>>> Stopping:
>>> Knopflerfish seems to assume that when a bundle is stopped, the 
>>> framework
>>> should be taking care about unregistering services.
>>> (See "Automatic cleanup of services")
>>>
>>> Is this generally valid or container dependent?
>>
>> This is mandated by the core specs (section 4.3.6 on specs 4.0.1).
>>
>>> Also, does this also apply to Listener instances (like for example a
>>> ServiceListener) and service references that are being used?
>>> I.e. is there a need to call 
>>> BundleContext.removeService/FrameworkListener()
>>> or m_BundleContext.ungetService() for cleanup?
>>
>> In principle you should "undo" what you did during start, so release
>> resources, stop started threads, ...
>
> Good point, with the same exception as above (stopping threads may not 
> be a good idea).
>
>
>> There is no need to unregister services registered during startup or
>> framework listeners because they will be cleaned up by the framework
>> after the stop method returns. Also, any services used by the bundle
>> being stopped will be released automatically by the framework.
>> But recall that other bundles that still have references to your
>> service will still be able to call your service so you may wanna play
>> defense and handle this case even if I consider this a programming
>> error from the point of view of the bundle that still uses the service
>> even if the service has been unregistered. When I wanna do that I
>> usually implement the service using a state service and by the moment
>> the bundle is stopped or the service s unregistered I change the
>> internal state of the service to stopped, state where I throw an
>> meaningful exception. But is a lot of work in plus that does not bring
>> real value to your service, it only helps the developer of the bundle
>> that is still using the invalid service to think about the fact that
>> he should not use anymore the service after it has been unregistered.
>>
>
> I usually try to design the use of other services in a way that allows 
> "come and go". i.e. using a mediated reference instead of obtaining 
> one and holding it; and kind of doing request/response transactions.
>
> However, I have come to the conclusion that if state needs to be 
> maintained between calls to a service, then it is actually much more 
> complex to handle (and design for) the "come and go" situation.
>
> Regards,
> Dieter
>

Re: General questions about starting and stopping bundles

Posted by "Richard S. Hall" <he...@ungoverned.org>.
Dieter Wimberger wrote:
> Alin:
>
>> The specs does not mandate this but I see it as a best practice when
>> the start method does not return in a "timely manner". Having this
>> thread also means that you must take care to stop the thread during
>> BundleActivator.stop as it can be that stop is called before your
>> starting thread ends.
>>
>
> You are making a good point here, except that I think that "stopping" 
> is maybe not a good choice.
> Actually it's not recommendable to stop threads at all, it is a thread 
> primitive that has been deprecated a while ago:
> http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html 
>
>
> However, it may make sense to handle this case, and maybe to join the 
> start thread before proceeding with a stop.
>
> As a side note, I always found it semantically strange to have 
> "starting" and "stopping" as states (4.3.2 Bundle States), rather than 
> "transitions".

Well, I think the suggestion was intended to say, "make sure the threads 
exit properly"...so, if you cannot control them, you might need to 
actually stop() them...as long as the thread is completely 
self-contained in the bundle, I don't see this causing a lot of 
problems...unless there are statics that get accessed and could be in an 
inconsistent state.

-> richard

>
>
>>>
>>> Stopping:
>>> Knopflerfish seems to assume that when a bundle is stopped, the 
>>> framework
>>> should be taking care about unregistering services.
>>> (See "Automatic cleanup of services")
>>>
>>> Is this generally valid or container dependent?
>>
>> This is mandated by the core specs (section 4.3.6 on specs 4.0.1).
>>
>>> Also, does this also apply to Listener instances (like for example a
>>> ServiceListener) and service references that are being used?
>>> I.e. is there a need to call 
>>> BundleContext.removeService/FrameworkListener()
>>> or m_BundleContext.ungetService() for cleanup?
>>
>> In principle you should "undo" what you did during start, so release
>> resources, stop started threads, ...
>
> Good point, with the same exception as above (stopping threads may not 
> be a good idea).
>
>
>> There is no need to unregister services registered during startup or
>> framework listeners because they will be cleaned up by the framework
>> after the stop method returns. Also, any services used by the bundle
>> being stopped will be released automatically by the framework.
>> But recall that other bundles that still have references to your
>> service will still be able to call your service so you may wanna play
>> defense and handle this case even if I consider this a programming
>> error from the point of view of the bundle that still uses the service
>> even if the service has been unregistered. When I wanna do that I
>> usually implement the service using a state service and by the moment
>> the bundle is stopped or the service s unregistered I change the
>> internal state of the service to stopped, state where I throw an
>> meaningful exception. But is a lot of work in plus that does not bring
>> real value to your service, it only helps the developer of the bundle
>> that is still using the invalid service to think about the fact that
>> he should not use anymore the service after it has been unregistered.
>>
>
> I usually try to design the use of other services in a way that allows 
> "come and go". i.e. using a mediated reference instead of obtaining 
> one and holding it; and kind of doing request/response transactions.
>
> However, I have come to the conclusion that if state needs to be 
> maintained between calls to a service, then it is actually much more 
> complex to handle (and design for) the "come and go" situation.
>
> Regards,
> Dieter
>

Re: General questions about starting and stopping bundles

Posted by Dieter Wimberger <di...@wimpi.net>.
Alin:

> The specs does not mandate this but I see it as a best practice when
> the start method does not return in a "timely manner". Having this
> thread also means that you must take care to stop the thread during
> BundleActivator.stop as it can be that stop is called before your
> starting thread ends.
>

You are making a good point here, except that I think that "stopping"  
is maybe not a good choice.
Actually it's not recommendable to stop threads at all, it is a thread  
primitive that has been deprecated a while ago:
http://java.sun.com/j2se/1.3/docs/guide/misc/threadPrimitiveDeprecation.html

However, it may make sense to handle this case, and maybe to join the  
start thread before proceeding with a stop.

As a side note, I always found it semantically strange to have  
"starting" and "stopping" as states (4.3.2 Bundle States), rather than  
"transitions".


>>
>> Stopping:
>> Knopflerfish seems to assume that when a bundle is stopped, the  
>> framework
>> should be taking care about unregistering services.
>> (See "Automatic cleanup of services")
>>
>> Is this generally valid or container dependent?
>
> This is mandated by the core specs (section 4.3.6 on specs 4.0.1).
>
>> Also, does this also apply to Listener instances (like for example a
>> ServiceListener) and service references that are being used?
>> I.e. is there a need to call BundleContext.removeService/ 
>> FrameworkListener()
>> or m_BundleContext.ungetService() for cleanup?
>
> In principle you should "undo" what you did during start, so release
> resources, stop started threads, ...

Good point, with the same exception as above (stopping threads may not  
be a good idea).


> There is no need to unregister services registered during startup or
> framework listeners because they will be cleaned up by the framework
> after the stop method returns. Also, any services used by the bundle
> being stopped will be released automatically by the framework.
> But recall that other bundles that still have references to your
> service will still be able to call your service so you may wanna play
> defense and handle this case even if I consider this a programming
> error from the point of view of the bundle that still uses the service
> even if the service has been unregistered. When I wanna do that I
> usually implement the service using a state service and by the moment
> the bundle is stopped or the service s unregistered I change the
> internal state of the service to stopped, state where I throw an
> meaningful exception. But is a lot of work in plus that does not bring
> real value to your service, it only helps the developer of the bundle
> that is still using the invalid service to think about the fact that
> he should not use anymore the service after it has been unregistered.
>

I usually try to design the use of other services in a way that allows  
"come and go". i.e. using a mediated reference instead of obtaining  
one and holding it; and kind of doing request/response transactions.

However, I have come to the conclusion that if state needs to be  
maintained between calls to a service, then it is actually much more  
complex to handle (and design for) the "come and go" situation.

Regards,
Dieter


Re: General questions about starting and stopping bundles

Posted by Alin Dreghiciu <ad...@gmail.com>.
On Sat, Jun 28, 2008 at 12:46 AM, Dieter Wimberger <di...@wimpi.net> wrote:
> Hi all,
>
> I have got some general questions about starting and stopping bundles.
>
> Given that I made my first OSGi steps with Knopflerfish, I have usually been
> following their general recommendations on bundle design:
> http://www.knopflerfish.org/programming.html
>
> Starting:
> Konpflerfish seems to suggest to spawn a thread if bundle activation is
> supposed to take a while.
> (See section "Spawning a startup thread").
>
> This basically translates to the following construct:
>
>  public void start(final BundleContext bundleContext) throws Exception {
>    c_BundleContext = bundleContext;
>
>    Thread t = new Thread(
>        new Runnable() {
>          public void run() {
>            ///do start logic
>          }//run
>        }//Runnable
>    );//Thread
>
>    t.setContextClassLoader(getClass().getClassLoader());
>    t.start();
>  }//start
>
>
> Is this approach recommendable? Are there side-effects that could be
> container dependent?

The specs does not mandate this but I see it as a best practice when
the start method does not return in a "timely manner". Having this
thread also means that you must take care to stop the thread during
BundleActivator.stop as it can be that stop is called before your
starting thread ends.

>
> Stopping:
> Knopflerfish seems to assume that when a bundle is stopped, the framework
> should be taking care about unregistering services.
> (See "Automatic cleanup of services")
>
> Is this generally valid or container dependent?

This is mandated by the core specs (section 4.3.6 on specs 4.0.1).

> Also, does this also apply to Listener instances (like for example a
> ServiceListener) and service references that are being used?
> I.e. is there a need to call BundleContext.removeService/FrameworkListener()
> or m_BundleContext.ungetService() for cleanup?

In principle you should "undo" what you did during start, so release
resources, stop started threads, ...
There is no need to unregister services registered during startup or
framework listeners because they will be cleaned up by the framework
after the stop method returns. Also, any services used by the bundle
being stopped will be released automatically by the framework.
But recall that other bundles that still have references to your
service will still be able to call your service so you may wanna play
defense and handle this case even if I consider this a programming
error from the point of view of the bundle that still uses the service
even if the service has been unregistered. When I wanna do that I
usually implement the service using a state service and by the moment
the bundle is stopped or the service s unregistered I change the
internal state of the service to stopped, state where I throw an
meaningful exception. But is a lot of work in plus that does not bring
real value to your service, it only helps the developer of the bundle
that is still using the invalid service to think about the fact that
he should not use anymore the service after it has been unregistered.

>
> Any comments and answers are appreciated.
>
> Regards,
> Dieter
>
>
>
>



-- 
Alin Dreghiciu
http://www.ops4j.org - New Energy for OSS Communities - Open
Participation Software.
http://www.qi4j.org - New Energy for Java - Domain Driven Development.
http://malaysia.jayway.net - New Energy for Projects - Great People
working on Great Projects at Great Places