0
votes

I am really new on this one (OSGI), trying to do simple examples. I cant make lazy actication work. I know there a few Blueprint impl out there to resolve such issues, but before proceeding with one, I thought it would be good to learn a few basics.


    Bundle DataService:
    Manifest-Version: 1.0  
    Bundle-Version: 1.0.0  
    Bundle-Name: DataService  
    Bundle-ManifestVersion: 2  
    Bundle-Activator: DataService.Activator  
    Import-Package: org.osgi.framework  
    Bundle-SymbolicName: DataService  
    Export-Package: DataService;version="1.0.0"  
    Bundle-ActivationPolicy: lazy  

    Bundle DataServiceClient:  
    Manifest-Version: 1.0  
    Bundle-Version: 1.0.0  
    Bundle-Name: DataServiceClient  
    Bundle-ManifestVersion: 2  
    Bundle-Activator: DataServiceClient.Activator  
    Import-Package: org.osgi.framework, DataService;version="[1.0.0,1.0.0]"  
    Bundle-SymbolicName: DataServiceClient

Ok I have changed my code, but still no luck.

Outer application, install bundles, starts framework and then only starts DataServiceClient bundle. No access to any bundle class.


    File bundleDir = new File("./bundles/");  
    String[] bundleResources = bundleDir.list();  
    for(String bundleResourcePath : bundleResources) {  
        File bundleResource = new File(bundleDir, bundleResourcePath);  
        InputStream bs =new FileInputStream(bundleResource);  
        mFramework.getBundleContext().installBundle(bundleResource.getName(), bs);  
    }  
    mFramework.start();  

    bl = mFramework.getBundleContext().getBundles();  
    for(Bundle b : bl) {  
        if (b.getBundleId() != 0 && b.getSymbolicName().contains("DataServiceClient")) {  
            b.start();  
        }           
    }   


Here is the start of DataServiceClient:


    System.out.println("DataServiceClient Start");
    IDataService  service = new DummyService();
    System.out.println(service.getData());



Here is the DummyService class in "DataService" bundle.


    public class DummyService implements IDataService {

        @Override
        public String getData() {
            return "DummyService Data";
        }
    }

Here is the start of "DataService" bundle:

    System.out.println("DataService Start");

The output I am getting:


    DataServiceClient Start
    DummyService Data

However I expect to see:


    DataServiceClient Start
    DataService Start
    DummyService Data

a little quatation from http://www.osgi.org/Design/LazyStart

Lazy Activation

Lazy activation is a life cycle policy that mandates a bundle MUST be activated upon the first successful request to load a class from that bundle.

However since it doesnt work, i guess i completely misunderstand the concept of lazy activation or i am doing something wrong.

Unless I explicitly call start for DataService bundle, it seems it doesnt invoke Activator.start for DataService bundle. This is what I am not getting atm.

Thx for your time

3

3 Answers

1
votes

Are you sure, your Activator is really not called. I often had the case that the activator was called but experienced and exception which OSGi swallowed. Can you try a println on the first line in the Activator.start to check this. A try catch with logging also is useful in this case.

Btw. Naming a package with an upper case letter is highly unusual. Not sure if it is a problem but I would avoid that.

1
votes

It's not clear what's going on when you call DummyClient.GetData(). You say that it invokes a class in the DataService bundle, but how?? DataService is an ordinary bundle and your code is the main Java launcher application, and there is no way in OSGi for the "outer" application to depend statically upon an ordinary bundle.

Anyway, even if you could do this, you execute this line of code before the bundle is started. The bundle activator will certainly not be called before the bundle is started!! I would expect your activator to be called at line 36, i.e. where you call bundle.start() on each bundle.

But really... what on earth are you trying to do?? The Bundle-ActivationPolicy: lazy flag is almost completely useless. I have eight years' experience of OSGi, and have only ever used this setting in Eclipse RCP applications, for legacy reasons. Unless you are writing an Eclipse plug-in or an Eclipse RCP application, you should not use Bundle-ActivationPolicy: lazy in OSGi.

The proper way to get lazy (or "just in time") instantiation in OSGi is to use Declarative Services (DS). All service objects published by DS are instantiated on demand, when a client first tries to invoke them rather than at the time they are registered. You do not need to do anything special to enable this.

0
votes

Regarding the changed code... you never actually start the bundle DataServiceClient, so its activator cannot be called. You have explicitly excluded it by name from the loop in which you start the bundles. OSGi will only ever call the BundleActivator on bundles that have been started with bundle.start().

This is a very widely misundertood point... OSGi never automatically starts bundles, even with the Bundle-ActivationPolicy: lazy flag enabled.

Probably what you meant to do is start the bundle as follows:

bundle.start(Bundle.START_ACTIVATION_POLICY).

In fact you do this for all bundles rather than arbitrarily starting a subset of bundles.

But again, I must reiterate the point I made in my other answer. Using Bundle-ActivationPolicy: lazy is pointless, except if you are developing Eclipse RCP applications, in which case you sometimes have to use it for stupid legacy reasons.