0

我对这个(OSGI)真的很陌生,试图做一些简单的例子。我不能让懒惰的行动起作用。我知道有一些 Blueprint impl 可以解决此类问题,但在继续使用之前,我认为学习一些基础知识会很好。

    捆绑数据服务:
    清单版本:1.0  
    捆绑版本:1.0.0  
    捆绑名称:DataService  
    捆绑清单版本:2  
    捆绑激活器:DataService.Activator  
    导入包:org.osgi.framework  
    Bundle-SymbolicName:数据服务  
    导出包:DataService;version="1.0.0"  
    Bundle-ActivationPolicy:懒惰  

    捆绑数据服务客户端:  
    清单版本:1.0  
    捆绑版本:1.0.0  
    捆绑名称:DataServiceClient  
    捆绑清单版本:2  
    捆绑激活器:DataServiceClient.Activator  
    导入包:org.osgi.framework, DataService;version="[1.0.0,1.0.0]"  
    捆绑符号名称:DataServiceClient

好的,我已经更改了代码,但仍然没有运气。

外部应用程序,安装包,启动框架,然后只启动 DataServiceClient 包。无法访问任何捆绑类。

    文件 bundleDir = new File("./bundles/");  
    字符串[] bundleResources = bundleDir.list();  
    for(字符串捆绑资源路径:捆绑资源){  
        文件 bundleResource = new File(bundleDir, bundleResourcePath);  
        InputStream bs =new FileInputStream(bundleResource);  
        mFramework.getBundleContext().installBundle(bundleResource.getName(), bs);  
    }  
    mFramework.start();  

    bl = mFramework.getBundleContext().getBundles();  
    for(捆绑 b:bl){  
        if (b.getBundleId() != 0 && b.getSymbolicName().contains("DataServiceClient")) {  
            b.开始();  
        }           
    }   


这是 DataServiceClient 的开始:

    System.out.println("DataServiceClient 启动");
    IDataService 服务 = new DummyService();
    System.out.println(service.getData());



这是“DataService”包中的 DummyService 类。

    公共类 DummyService 实现 IDataService {

        @覆盖
        公共字符串 getData() {
            返回“虚拟服务数据”;
        }
    }

这是“DataService”包的开始:

    System.out.println("数据服务启动");

我得到的输出:

    数据服务客户端启动
    虚拟服务数据

但是我希望看到:

    数据服务客户端启动
    数据服务启动
    虚拟服务数据

来自http://www.osgi.org/Design/LazyStart的一个小例子

延迟激活

延迟激活是一种生命周期策略,它要求必须在第一次成功请求从该包加载类时激活包。

但是,由于它不起作用,我想我完全误解了延迟激活的概念,或者我做错了什么。

除非我为 DataService 包显式调用 start ,否则它似乎不会为 DataService 包调用 Activator.start 。这就是我没有得到atm的东西。

谢谢你的时间

4

3 回答 3

1

不清楚调用 DummyClient.GetData() 时发生了什么。你说它调用 DataService 包中的一个类,但是如何呢?DataService 是一个普通的包,您的代码是主要的 Java 启动器应用程序,在 OSGi 中,“外部”应用程序无法静态依赖于一个普通的包。

不管怎样,即使你能做到这一点,你也要在包启动之前执行这行代码。在bundle启动之前肯定不会调用bundle activator!!我希望在第 36 行调用您的激活器,即您bundle.start()在每个捆绑包上调用的位置。

但真的......你到底想做什么?旗帜Bundle-ActivationPolicy: lazy几乎完全没用。我有八年的 OSGi 经验,并且由于遗留原因,我只在 Eclipse RCP 应用程序中使用过这个设置。除非您正在编写 Eclipse 插件或 Eclipse RCP 应用程序,否则不应Bundle-ActivationPolicy: lazy在 OSGi中使用。

在 OSGi 中获得惰性(或“及时”)实例化的正确方法是使用声明式服务 (DS)。DS 发布的所有服务对象都是按需实例化的,当客户端第一次尝试调用它们时,而不是在它们注册时。您无需执行任何特殊操作即可启用此功能。

于 2013-12-25T03:54:32.293 回答
1

你确定吗,你的激活器真的没有被调用。我经常遇到激活器被调用但遇到OSGi吞下的异常的情况。您可以在 Activator.start 的第一行尝试 println 来检查这一点。在这种情况下,带有日志记录的 try catch 也很有用。

顺便提一句。用大写字母命名一个包是非常不寻常的。不确定这是否是一个问题,但我会避免这种情况。

于 2013-12-25T00:31:20.527 回答
0

关于更改的代码...您实际上从未启动过 bundle DataServiceClient,因此无法调用其激活器。您已在启动捆绑包的循环中按名称明确排除它。OSGi 只会调用BundleActivatorbundle.start().

这是一个被广泛误解的观点...... OSGi从不自动启动 bundles,即使Bundle-ActivationPolicy: lazy启用了标志。

可能您的意思是按如下方式启动捆绑包:

bundle.start(Bundle.START_ACTIVATION_POLICY).

实际上,您对所有捆绑包都这样做,而不是任意启动捆绑包的子集。

但是,我必须再次重申我在另一个答案中提出的观点。使用Bundle-ActivationPolicy: lazy是没有意义的,除非您正在开发 Eclipse RCP 应用程序,在这种情况下,您有时不得不出于愚蠢的遗留原因使用它。

于 2013-12-25T16:33:29.573 回答