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