Hi,
On 30.04.2009, at 16:44, Eugen Reiswich wrote:
First, why are you starting the bundles in one of the bundles?
Because my serviceimpl bundles are never started by Eclipse (in case
I reuse them in my RCP application). If I do add them to the
Eclipse launch-configuration they remain as resolved but are never
activated. Therefore they never register a service which is needed
within my application. The lazy loading concept does only activate a
bundle if one of it's classes is needed. As my application only uses
the service-interfaces (which are in a separate bundle) and never
the serviceimpls these bundles are never activated.
Second, as Peter points out, OSGi is a dynamic environment. So,
to make this robust, not error prone and not difficult to
maintain, you should be using service trackers to get your
services. e.g.
But that's exactly what causes all the trouble. If I use service
tracker I have no idea at what point in time all required services
are registred in the registry. So what can happen is that I start my
application, try to use a service and the service is not available
because it's not registered yet. What I do not want is e.g. to
display an error message with something like "please wait another 5
or maybe more seconds, till the service is registered". I want to
ensure a stable environment after my application is started.
protected void ensureServices(BundleContext context) {
ServiceTracker tracker = new ServiceTracker(context,
IMyService.class.getCannonicalName(), null);
tracker.open();
Object myService = tracker.waitForService(60 * 1000); // wait 60
seconds for the service to initialize
if (myService == null) {
// shutdown
}
}
You expect the service to be initialized at the least after 60
seconds. But how do you know that the service will be registered
within the 60 sec for sure? The ServiceTracker can still return NULL
after 60 seconds. Or am I wrong?
My third point is that you shouldn't block the Activator.start()
method, so you'd do:
public void start(final BundleContext context) {
new Thread(new Runnable() {
public void run() {
ensureServices(context);
}
}).start();
}
But that's the only way how I can for now ensure that all services
are started in a correct order. We have some service dependencies
which have to be resolved in a correct order. This is really error
prone but I don't know how to avoid this problem (see my issues with
the service tracker)
You create a lot of software for a function that is handled fully
invisible by DS, iPOJO, Spring, dep. manager etc. You're fighting
OSGi, you do not leverage it ...
DS, iPOJO and Spring DM are useful tools, but in my opinion they are
really complex. We have used Spring for a long time in several
projects and are no longer interested in configuring our application
with XML-files.
You can use iPOJO with annotations or with an API. XML is just one
possibility. And now, it seems that you can use DS with annotations too.
Clement
I know that what we are doing in our application is bad, but that's
why I am looking for a better solution.
Kind regards,
Eugen
Am Apr 30, 2009 um 15:41 schrieb Hal Hildebrand:
First, why are you starting the bundles in one of the bundles? For
one, the frameworks are usually persistent - Equinox certainly is.
So, what you'll find is that the second time you start up the
process - assuming you don't clean the installation- the bundles
will already be started. So, this is a bad thing to do right off
the bat.
Second, as Peter points out, OSGi is a dynamic environment. So, to
make this robust, not error prone and not difficult to maintain,
you should be using service trackers to get your services. e.g.
protected void ensureServices(BundleContext context) {
ServiceTracker tracker = new ServiceTracker(context,
IMyService.class.getCannonicalName(), null);
tracker.open();
Object myService = tracker.waitForService(60 * 1000); // wait 60
seconds for the service to initialize
if (myService == null) {
// shutdown
}
}
My third point is that you shouldn't block the Activator.start()
method, so you'd do:
public void start(final BundleContext context) {
new Thread(new Runnable() {
public void run() {
ensureServices(context);
}
}).start();
}
There are more sophisticated things you can do as well, but they
all ground out to much the same thing as above - i.e. looking in
the registry for a service, timing out.
On Apr 30, 2009, at 12:46 AM, Eugen Reiswich wrote:
Hi OSGi-devs,
I have the following problem with osgi services. We develop
basically applications where dynamic is not an issue. So what I
would like to make sure in my application is that all services are
registred properly at start up - if not, the application will be
shut down. In addition to that I want to reuse my bundles in RCP
applications so any concept must also be applicable for RCP
applications.
Say I have two bundles:
1. org.mycompany.service (contains a service interface)
2. org.mycompany.serviceimpl (contains the service implementation
and registers withing his activator an osgi-service)
What we do within the service bundle is this:
public void start(BundleContext context) throws Exception {
Bundle[] bundles = context.getBundles();
// find the implementation for the service bundle
for (Bundle bundle : bundles) {
if
("org.mycompany.serviceimpl".equals(bundle.getSymbolicName())) {
// service impl found
if (bundle.getState() != Bundle.ACTIVE) {
bundle.start();
}
}
}
// check if servicimpl has registred service properly
ServiceReference serviceReference = context
.getServiceReference(IMyService.class.getName());
if (serviceReference == null) {
// shut down application
}
...
From my point of view this is pretty error prone and difficult to
maintain. Is there a best practice approach how I can make sure
that all services are registered properly at start up of my
application? How can I start my serviceimpl bundles in RCP
application as no one depends on this bundle which is why the are
never started?
We have spend now a lot of time to find solutions for this problem
but they all seem to be improvable.
Regards,
Eugen
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev