首页 文章

使用新更改部署OSGI捆绑包的BKM是什么?

提问于
浏览
0

我们一直在使用OSGI和Jboss 7.0.1,并且有多个bundle支持我们的应用程序 . 我们正在尝试调整Major.Minor.Micro的版本控制策略,以用于基于接口服务实现消费者的模型,但似乎我们的策略可能不正确 .

当我们提升api和服务的次要版本时,消费者无法使用新服务而无需进行包刷新 .

下面是用例 .

com.helloworld.api 从包 Helloworld API (接口包)以1.0.0版导出

public interface IHelloService {
    public void sayHello(String abc);
}

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"

Helloworldservice 实现 HelloServiceImpl

public class HelloServiceImpl implements IHelloService {

@Override
  public void sayHello(String abc) {
      System.out.println(" \n\n ~~~~~~~~~ "+abc+" ~~~~~~~~~  " + "   \n\n");
  }
}

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:

消费者使用捆绑包 Consumer Service 消费(使用服务跟踪器或Google Guice方法) . 它继续在循环中调用sayHello .

HelloWorldServiceProxy.getInstance().getHelloWorldService().sayHello("abc  " + "Index" + i);

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"

之后我们对api进行修改并添加新方法 . 这导致将次要版本提升到1.1.0 . 为了支持这一点,我们在服务中实现了新方法,但期望消费者不受影响 .

package com.helloworld.api 从bundle Helloworld API 导出版本1.1.0

public interface IHelloService {
   public void sayHello(String abc);
   public void sayHello(String abc, String def, int a);
}

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"

由捆绑 Helloworldservice 实现 HelloServiceImpl

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");
  }
}

显示文件

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:

但是,现在当我们部署HelloWorld Api和HelloWorld Service捆绑包时,使用者捆绑包无法开始使用随包1.1.0导出的新服务 . 我们不得不刷新消费者捆绑包以使其工作 .

我们在这里做错了吗?

到目前为止,我们一直在部署没有任何版本的新捆绑包(默认为0.0.0) . 部署具有相同软件包修订版的新软件包适用于微更改,但在我们从Jboss执行全局软件包刷新之前,任何方法签名更改或新方法使用都会导致NoSuchMethod异常 . 这就是我们决定使用Jboss版本策略的原因 .

1 回答

  • 0

    安装/更新新捆绑包后,您应该始终刷新 . 没有例外 . 刷新未与更新/安装集成的唯一原因是您现在可以在刷新之前安装/更新多个软件包 .

    我对你的例子也有点疑惑 . 你谈到语义版本控制,但你的导入是从[1.3.0,∞),所以没有语义版本? (它还有助于删除大多数 Headers 之类的不必要信息 . )

    那么最佳做法是什么?

    首先,服务由包定义 . 对于此服务,您可以使用两种类型的接口:由使用者实现的接口和由提供者实现的接口 . 对于主要的释放凹凸,仅在非向后兼容时更改用户界面 . 提供者界面在次要释放凹凸上被破坏 . (major.minor.micro)OSGi支持接口的@ConsumerType(默认)和@ProviderType注释 .

    如果您使用bnd,则会自动获得导入范围 . 即如果你的 IHello (最好不要附加服务)从1.0开始:

    IHello.java:
     package com.example.hello;
    
     public interface IHello {
       void sayHell();
     }
    
     @Version("1.0.0")
     package-info.java:
    
     import org.osgi.annotation.versioning.Version;
    

    由于默认情况下这是@ConsumerType,我们将获得以下导入:

    Import-Package: com.example.hello;version='[1.0,2)'
    

    但是,IHello接口可能代表提供者 . 所以我们应该用@ProviderType注释它:

    IHello.java:
     package com.example.hello;
    
     import org.osgi.annotation.versioning.ProviderType;
    
     @ProviderType
     public interface IHello {
       void sayHell();
     }
    

    如果您现在编写实现IHello服务的提供程序,则bnd将检测com.example.hello包的版本 . 由于它看到你实现它,它将写出以下导入:

    Import-Package: com.example.hello;version='[1.0,1.1)'
    

    如果我们编写了IHello服务的客户端,我们的导入将是[1.0,2] .

    如果我们现在向IHello添加一个方法,我们应该将版本提升到1.1,因为IHello是一个@ProviderType . (如果它是@ConsumerType,我们将被迫将其提升到2.0)

    package-info.java:
     @Version("1.1.0")
     package-info.java:
    
     import org.osgi.annotation.versioning.Version;
    
     IHello.java:
     package com.example.hello;
    
     import org.osgi.annotation.versioning.ProviderType;
    
     @ProviderType
     public interface IHello {
       void sayHell();
       void sayHello(String s);
     }
    

    我们现在有效地打破了IHello服务的提供者,这正是我们想要的!这将阻止调用由针对1.0编译的实现支持的1.1服务 .

    摘要:

    安装/更新后必须进行

    • refresh .

    • 二手bnd

相关问题