We have been using OSGI with Jboss 7.0.1 and have multiple bundles supporting our application. We are trying to adapt the versioning strategy of Major.Minor.Micro for Interface + Service Implementation + Consumer based model, but it seems our strategy might not be right.
When we bump up the minor version for api and service the consumer is unable to use the new service without having to do package refresh.
Below is the usecase.
Package com.helloworld.api is exported with version 1.0.0 from bundle Helloworld API (interface bundle)
public interface IHelloService {
public void sayHello(String abc);
}
Menifest File for Helloworld API
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworld API
Bundle-SymbolicName: exp1.com.helloworld.api
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.helloworld.internal.Activator
Bundle-Vendor: ABC
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.0"
Bundle-ClassPath: .
Export-Package: com.helloworld.api;version="1.0.0"
Implemented by HelloServiceImpl from bundle Helloworldservice
public class HelloServiceImpl implements IHelloService {
@Override
public void sayHello(String abc) {
System.out.println(" \n\n ~~~~~~~~~ "+abc+" ~~~~~~~~~ " + " \n\n");
}
}
Menifest File for Helloworldservice
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworldservice
Bundle-SymbolicName: exp1.com.helloworld.service
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.helloworldservice.internal.Activator
Bundle-Vendor: ABC
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: com.helloworld.api;version="1.0.0",
org.osgi.framework;version="1.3.0"
Bundle-ClassPath:
Consumed by Consumer from bundle Consumer Service (Using service tracker or Google Guice approach). It keeps on calling sayHello in loop.
HelloWorldServiceProxy.getInstance().getHelloWorldService().sayHello("abc " + "Index" + i);
Menifest File for Consumer Service
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Consumer Service
Bundle-SymbolicName: exp1.com.consumer
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.consumer.internal.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: com.helloworld.api;version="1.0.0",
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.0"
After that we make the modification to api and add new method. This results into bumping up the minor version to 1.1.0. To support this we implement the new method in service but expect the consumer to be untouched.
package com.helloworld.api is exported with version 1.1.0 from bundle Helloworld API
public interface IHelloService {
public void sayHello(String abc);
public void sayHello(String abc, String def, int a);
}
Menifest File for Helloworld API
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworld API
Bundle-SymbolicName: exp1.com.helloworld.api
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.helloworld.internal.Activator
Bundle-Vendor: ABC
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.4.0"
Bundle-ClassPath: .
Export-Package: helloworld.api;version="1.1.0"
Implemented by HelloServiceImpl from bundle Helloworldservice
public class HelloServiceImpl implements IHelloService {
@Override
public void sayHello(String abc) {
System.out.println(" \n\n ~~~~~~~~~ "+abc+" ~~~~~~~~~ " + " \n\n");
}
@Override
public void sayHelloNew(String abc, String def, int a) {
System.out.println(" \n\n ~~~~~~~~~ "+abc+" NEW METHOD ### WITH CHANGE ### ~~~~~~~~~ " + abc +" " + def +" \n\n");
}
}
Menifest File
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Helloworldservice
Bundle-SymbolicName: exp1.com.helloworld.service
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.helloworldservice.internal.Activator
Bundle-Vendor: ABC
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: com.helloworld.api;version="1.1.0",
org.osgi.framework;version="1.3.0"
Bundle-ClassPath:
However, now when we deploy HelloWorld Api and HelloWorld Service bundles, the consumer bundle is unable to start using the new service exported with package 1.1.0. We are having to refresh the consumer bundle in order to make it work.
Are we doing something wrong here ?
So far we have been deploying new bundles without any version (defaults to 0.0.0). Deploying new bundles with same package revision works fine for micro changes but any method signature change or new method usage results into NoSuchMethod exception until we perform the global package refresh from Jboss. That is the reason we decided to use Jboss version strategy.