【问题标题】:Getting started with bundle DI in an OSGi environment在 OSGi 环境中开始使用 bundle DI
【发布时间】:2012-01-10 00:58:48
【问题描述】:

一段时间以来,我一直在开发一个使用 Apache Felix 作为我的 OSGi 运行时的应用程序,到目前为止,进展非常顺利。但是,我现在想采用依赖注入,Apache Felix 的“默认”机制似乎是 iPOJO。

但是,我发现有关 Apache felix 的文档和教程太薄弱了,我无法找到任何地方。所以我准备改变,但首先我最好解释一下我正在尝试做的(非常简单的)想法。

给定两个捆绑包;

消费者捆绑

package bundles.consumer;

class Consumer implements BundleActivator{
    @Inject
    private Producer producer;

    public void bundleActivated(BundleContext con) {
        this.producer.getNextItem();
    }
}

生产者捆绑包

package bundles.producer;

@Singleton
class Producer {
    public String getNextItem() {
        return "item x"; 
    }
}

我希望 OSGi 运行时启动 Consumer 包,意识到它需要一个 Producer 才能工作,然后框架启动 Producer 包并将实例注入到 Consumer 中。简单的。 iPOJO 建议仅使用注释(@Singleton、@Inject)或类似的方法来实现这一点,但我根本无法让它工作。 OSGi 显然有声明式服务,但这意味着要编写大量 XML,我真的想避免这些。

Anywoo,我准备适应 JBoss、Equinox 或替代 OSGi 运行时和替代依赖注入机制,无论是 Peaberry、Spring DM 还是完全不同的东西。我已经在使用 Maven。

我要问的是,有人可以使用生产者和消费者的想法创建一个 Hello World 来帮助我入门吗?我真的花了很多时间阅读并发现学习曲线难以逾越!


编辑,我尝试使用 SCR:http://tydus.net/codeExamples/mvnScr.tar

【问题讨论】:

  • 我同意这些答案,但想澄清一个误解。 iPOJO 不一定是 Felix 的“默认”DI 框架,它只是托管在 Apache 上的另一个项目。 iPOJO 适用于 Felix、Equinox、Knopflerfish 等。声明式服务 (DS) 也适用于 Felix、Equinox、Knopflerfish……Spring-DM 也是如此……Blueprint 也是如此。没有必要仅仅因为你无法让 iPOJO 工作而改变你的 OSGi 容器。
  • 另外,请描述为什么您无法让 iPOJO 工作,以及它究竟是如何失败的。它应该有效,但您没有向我们提供足够的信息来建议修复。
  • 尼尔,我知道你第一条评论中的情况,如果我原来的帖子有一点乱码,请原谅我。虽然我非常愿意花时间让 iPOJO 正常工作,但这里几乎是跑题了。根据其他成员的建议,我目前正在试验 SCR。实际上,我在寻求帮助时确实向您发送了一封电子邮件,但感谢您可能太忙而无法获得一对一的教程! (虽然那会很棒!)

标签: java osgi apache-felix


【解决方案1】:

最好使用声明式服务,因为它是 OSGi 标准。

您可以使用Java Annotations 来描述DS 依赖项、服务和组件Maven SCR plugin

问候, Dmytro

【讨论】:

  • +1 虽然最好使用 bnd 注释而不是 Maven SCR 插件注释,因为它们在 Maven 之外工作(当然也在 Maven 内部!)
  • 谢谢你,Dmytro。我一直在尝试 SCR,并且比 iPOJO 走得更远,但必须说明我的捆绑包的依赖项显然是“不满意”的。生产者类有@Component,消费者类有@Component 和一个@Reference 字段。启动捆绑包时,我没有收到任何错误消息(从 felix 控制台检查了log)。我也将ds.loglevel设置为999,ds.showtraces=true,ds.showerrors=true,但还是没有。您愿意为我发布一些示例代码吗?我可以解决错误消息,但这根本行不通,也没有说明原因!
  • 在这里查看:blog.knowhowlab.org/2010/10/…felix.apache.org/site/scr-annotations.html,当然还有 OSGi 规范(它包含一些代码示例)
【解决方案2】:

有两件事要记住; 1) 您的 bundle 可能需要一些额外的元数据用于依赖注入框架,并且 2) 您需要部署 DI 框架的运行时。

依赖注入不是核心 OSGi(即 Felix 框架)的一部分,因此您必须先部署 iPOJO 包,然后再部署自己的包。此外,您需要添加 IPOJO 所需的元数据,谷歌“maven-ipojo-plugin”了解更多信息。

如果您正在寻找比 Felix 本身更简单的容器,请尝试 Karaf(它带有许多企业附加功能)。

就我个人而言,我喜欢声明式服务(所以 +1 Dmytro),因为它非常简单,只是从 OSGi 中删除了样板代码(记得部署 it 并在你的包中提供 component.xml 参见 maven-scr-plugin更多信息)。


编辑

(回答评论并链接到下面的 tarball)

我将@Service 注解从 Producer 移到了 ProducerImpl。

生成的 SCR component.xml 对消费者来说不太正确,通过添加一个 unbind() 方法并更改 @Reference 如下工作:

//...
import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY;
import static org.apache.felix.scr.annotations.ReferencePolicy.DYNAMIC;

//...
@Component
public class Consumer
{
    @Reference(policy = DYNAMIC, cardinality = MANDATORY_UNARY)
    private Producer producer;

    public void unbindProducer() {
        System.out.println("Producer unbound.");
        this.producer = null;
    }
//...
}

部署 Maven

当您使用 maven 时,请安装 Pax Url for maven,这样您就可以轻松地从本地和远程存储库安装包。

首先让 maven 为你下载一个版本(pax-url-mvn 版本 1.3.5 可用)然后安装文件(或复制到 Felix 捆绑目录)

-> install file:/YOUR_PATH_TO_MAVEN_REPO/.m2/repository/org/ops4j/pax/url/pax-url-mvn/1.3.5/pax-url-mvn-1.3.5.jar
Bundle ID: 7
-> start 7
DEBUG: WIRE: [7.0] osgi.wiring.package; (osgi.wiring.package=javax.net.ssl) -> [0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (osgi.wiring.package=javax.xml.parsers) -> [0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework)(version>=1.0.0)(!(version>=2.0.0))) -> [0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.service.cm)(version>=1.0.0)(!(version>=2.0.0))) -> [2.0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.service.url)(version>=1.0.0)(!(version>=2.0.0))) -> [0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (osgi.wiring.package=org.w3c.dom) -> [0]
DEBUG: WIRE: [7.0] osgi.wiring.package; (osgi.wiring.package=org.xml.sax) -> [0]
-> 

您现在可以使用 mvn URL 处理程序从本地存储库安装自己的包:

-> install mvn:com.examples/producer/1.0.1
Bundle ID: 10
-> start 10
-> install mvn:com.examples/consumer/1.0.1     
Bundle ID: 11
-> start 11
DEBUG: WIRE: [11.0] osgi.wiring.package; (&(osgi.wiring.package=com.examples.producer)(version>=1.0.0)(!(version>=2.0.0))) -> [10.0]
Producer bound.
Consumer activate
Aloha.
-> 

【讨论】:

  • 感谢您的 cmets。 iPOJO 运行时已安装并处于活动状态,并且正在使用 maven-ipojo-plugin 处理我的包(我手动检查了)。我真的很喜欢 Felix,因为它非常轻量级和可定制,但感谢 Karaf 的链接,我会检查一下。 SCR 和声明式服务似乎是一种可行的方法,但目前我根本无法让它工作并且没有收到任何错误消息(请参阅上面对 Dymtro 的评论)。
  • Felix 很棒,但对于实验来说,Karaf 为您提供了一个不错的完整套件。我很乐意查看任何声明式服务代码。请发布生成的 OSGI-INF/component.xml 和一个简单的服务。
  • 我没有空间在此评论中发布它,这里是项目的 URL; tydus.net/codeExamples/mvnScr.tar
  • 非常感谢您抽出宝贵时间,帮了大忙!
  • 不客气,OSGi 的学习曲线非常陡峭,但值得付出努力 =)
【解决方案3】:

我为 Equinox 声明式服务包编写了一个片段,它允许您使用对应于 DS 服务 XML 元素的注释来标记您的类;是的,这是一个有其自身局限性的 hack,但到目前为止,它在包含 90 多个捆绑包的项目中运行良好。如果您有兴趣,我可能会在本周清理、记录并发布它。

【讨论】:

  • 感谢您的 cmets。我更喜欢使用标准/发布的代码,因为文档更有可能更好。欢迎任何有用的教程链接。
猜你喜欢
  • 1970-01-01
  • 2016-03-08
  • 2012-04-17
  • 2011-09-21
  • 1970-01-01
  • 2012-10-16
  • 2013-03-28
  • 1970-01-01
  • 2010-11-12
相关资源
最近更新 更多