【问题标题】:How to expose a service from one OSGi bundle in another without ClassCastException如何在没有 ClassCastException 的情况下从另一个 OSGi 包中公开服务
【发布时间】:2026-01-12 22:30:01
【问题描述】:

几年来,我一直在使用 ServiceMix,但仍然没有成功地在我的包之间共享服务实现 - 由于使用了代理实现,它总是导致 ClassCastException。

我有两个捆绑包和一个嵌入式 jar。

  • 嵌入式 jar 包含我的服务类实现的接口。
  • Bundle 'A' 具有服务类实现并导出 impl 所在的包。
  • Bundle 'B' 导入了 bundle 'A' 暴露的包。在 Bundle 'B' 中,以下代码成功获取服务;

        IScenarioService scenarioService = null;
    try
    {
        ServiceReference<?>[] servRefs = context.getServiceReferences(IScenarioService.class.getName(), null);
        if (servRefs == null || servRefs.length == 0)
        {
            LOGGER.error("Found no service references for " + IScenarioService.class.getName());
            return false;
        }
        else
        {
            LOGGER.info("Services: " + servRefs.length);
            boolean assign = servRefs[0].isAssignableTo(context.getBundle(), IScenarioService.class.getName());
            LOGGER.info("Assign: " + assign);
    
            scenarioService = (IScenarioService) context.getService(servRefs[0]);
        }
    }
    catch (InvalidSyntaxException e)
    {
        LOGGER.error(e.getMessage());
        e.printStackTrace();
        return false;
    }
    

我的日志显示找到了 1 个服务并且服务“isAssignable”,但在线 scenarioService = (IScenarioService) context.getService(servRefs[0]); 我得到了

java.lang.ClassCastException: Proxy511e3d1b_93b7_4de1_835f_3e5df19040b4 无法转换为 xx.x.xx.IScenarioService

我尝试通过 Blueprint 注入服务,在上面的代码中访问,更改 pom 的 maven-bundle-plugin 中的导入/导出关系,以及将所有接口存储在 Bundle 'A' 中并导出相关包....都无济于事。

有人可以提供一个答案让我摆脱痛苦吗? 谢谢。

【问题讨论】:

    标签: java osgi apache-karaf apache-servicemix


    【解决方案1】:

    我认为问题在于提供服务的包和使用服务的包看到 IScenarioService 类的不同实例。这通常是由于在两个包中嵌入接口或有两个提供接口的包引起的。

    避免这种情况的最简单方法是将接口包放在导出包的第三个包中,并在服务提供者和服务消费者包中导入包。

    当您使用默认值时,maven bundle 插件会自动执行此操作。

    例如,请参阅this tutorial。模型包包含服务接口,持久包包含服务提供者,用户界面包包含服务消费者。

    正如您在代码中看到的那样,maven bundle 插件只在父级中设置,几乎不需要在各个包中进行额外的 OSGi 设置。

    如您所见,如果您操作正确,提供和使用服务非常简单。

    【讨论】:

    • 太棒了,感谢您抽出宝贵时间做出如此迅速的回应。我现在已经将嵌入式 jar 转换为它自己的包,并导出了接口包,该包又由两个相应的包(服务提供者和服务用户)导入 - 现在可以按预期工作。
    • 对于任何其他用户,请注意,我还在我的 pom 包配置中添加了“NONE”行,这有助于在部署服务提供者包时解决依赖性问题 - 不确定如果这正是它应该使用的方式,但节省了很多痛苦
    • 不确定 obrRepository NONE 是否真的解决了这个问题。它只告诉 maven bundle 插件不要将 bundle 元数据保存在 maven repo 中。你确定这个问题没有被其他东西解决吗?
    • 感谢克里斯蒂安;你是对的,删除这条线并重新部署仍然有效。谢谢。
    最近更新 更多