KevinO
KevinO

Reputation: 1030

OSGi/Equinox, Declarative Service and Lazy Load

I'm attempting to use Declarative Services to create a service bundle that provides functionality to another bundle. However, I want my Service Provider bundle to not start until it is needed. Let me describe my conditions.

There are two bundles:

-com.example.serviceprovider

-com.example.serviceconsumer

The Service Provider bundle provides a services using Declarative Services as follows:

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true"     immediate="true" name="samplerunnable1">
<implementation class="com.example.serviceprovider.SampleRunnable"/>
<service>
    <provide interface="java.lang.Runnable"/>
</service>

The Service Consumer references the provided services as follows:

<reference name="SampleRunnable"
    interface="java.lang.Runnable"
    bind="setRunnable"
    unbind="unsetRunnable"
    cardinality="1..n"
    policy="dynamic"/>

When both of these bundles are "ACTIVE" on start up, the Service Consumer has no trouble communicating with the service declared by the Service Provider. The problem happens when I try and have the service provider start in a lazy fashion.

After the Service Provider is set to load lazy this is what I get in the OSGi console:

osgi> ss
  "Framework is launched."
  id      State       Bundle
  15      STARTING    com.example.serviceconsumer_1.0.0.X
  16      RESOLVED    com.example.serviceprovider_1.0.0.X

What I would expect to see, is that even though bundle 16 is only "RESOLVED" that it would have at least registered is service. But when I call the "bundle" command, it states "No registered services."

osgi> bundle 16
com.example.serviceprovider_1.0.0.X [17]
  Id=17, Status=RESOLVED    Data Root=C:\apache\apache-tomcat-.0.40\work\Catalina\localhost\examplesX\eclipse\configuration\org.eclipse.osgi\bundles\17\data
  "No registered services."
  No services in use.
  No exported packages
  Imported packages
     org.osgi.framework; version="1.7.0"<org.eclipse.osgi_3.8.0.v20120529-1548 [0]>
  No fragment bundles
  Named class space
    com.example.serivceprovider; bundle-version="1.0.0.X"[provided]
  No required bundles

Maybe I've missed the fundamental concept of lazy loaded bundles and services registration. If a bundle is in a "RESOLVED" state, shouldn't it have all it's "wires" connected? (ie, has a classloader, resolved import and export dependencies and services registered.) If the Service Consumer tries to access the service shouldn't that bundle transition to the "ACTIVE" state? What piece am I missing here?

Upvotes: 2

Views: 1991

Answers (2)

Peter Kriens
Peter Kriens

Reputation: 15372

Declarative services were designed for this case. Starting a bundle means that's functionality should be available, it does not mean it actually uses resources. Only stop bundles when you don't want is function.

This question is a good example of trying to control too much. In a component oriented world programmers should use lazy initialisation as much as possible but they should never attempt to control the life cycle.

Upvotes: 2

Neil Bartlett
Neil Bartlett

Reputation: 23948

Bundles in the RESOLVED state cannot provide services, and they will be ignored by Declarative Services. You should in general start all bundles during launch time, even if you want lazy loading behaviour. The key is to make the activation of the bundles cheap (or free!), and only pay for initialization of components when they are required.

DS takes care of lazy activation by default already. There is nothing you need to enable or change for this to happen. Essentially DS publishes the service entry in the registry, but it does not actually instantiate your component (or even load its class) until some client tries to use the service.

Furthermore, because DS does not load the class until required, OSGi does not even need to create a ClassLoader for the bundle, so long as your bundle does not have a BundleActivator.

To reiterate, you should not seek to make your bundles stay in RESOLVED state. Such bundles can only export static code and resources, but they cannot "do" anything and they cannot participate in the service registry.

Upvotes: 4

Related Questions