【问题标题】:OSGI Bundle Lazy ActivationOSGI 捆绑延迟激活
【发布时间】:2014-01-12 13:16:19
【问题描述】:

我对这个(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的东西。

谢谢你的时间

【问题讨论】:

    标签: osgi osgi-bundle knopflerfish


    【解决方案1】:

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

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

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

    bundle.start(Bundle.START_ACTIVATION_POLICY).
    

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

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

    【讨论】:

    • 实际上它只启动 DataServiceClient 但你是对的,似乎懒惰激活不是我想的那样。我想这就是蓝图实施存在的原因:) 感谢您抽出宝贵时间,非常感谢。
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 嗨,尼尔,为什么懒惰激活没有用?我已经修改了我的代码,仍然没有成功。这似乎是一个非常基本的概念,但我想我错过了一些东西。
    • 我没说懒激活没用。如果您以正确的方式进行操作,这将非常有用。我说Bundle-ActivationPolicy: lazy标志没用。
    【解决方案3】:

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

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

    【讨论】:

    • 嗨,Christian,这只是用于培训 atm。但是您对命名约定是绝对正确的。但是我不确定应用程序是否会出现异常。代码中真的没有发生这样的事情。
    • 你能把你的完整例子贴在某个地方(github或类似的地方)吗?
    猜你喜欢
    • 1970-01-01
    • 2019-08-31
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多