Java 如何在没有ClassCastException的情况下从一个OSGi包公开另一个OSGi包中的服务

Java 如何在没有ClassCastException的情况下从一个OSGi包公开另一个OSGi包中的服务,java,osgi,apache-karaf,apache-servicemix,Java,Osgi,Apache Karaf,Apache Servicemix,我已经断断续续地使用ServiceMix好几年了,但仍然没有成功地在捆绑包之间共享服务实现——由于使用了代理实现,它总是导致ClassCastException 我有两个包和一个内嵌的罐子 嵌入的jar包含我的服务类实现的接口 捆绑包“A”具有服务类实现,并导出impl所在的包 捆绑包“B”导入捆绑包“A”公开的包。在Bundle“B”中,以下代码成功获取服务 IScenarioService scenarioService = null; try { ServiceRefer

我已经断断续续地使用ServiceMix好几年了,但仍然没有成功地在捆绑包之间共享服务实现——由于使用了代理实现,它总是导致ClassCastException

我有两个包和一个内嵌的罐子

  • 嵌入的jar包含我的服务类实现的接口
  • 捆绑包“A”具有服务类实现,并导出impl所在的包
  • 捆绑包“B”导入捆绑包“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;
    }
    
    IScenarioService场景服务=null;
    尝试
    {
    ServiceReference[]servRefs=context.getServiceReferences(IScenarioService.class.getName(),null);
    if(servRefs==null | | servRefs.length==0)
    {
    错误(“未找到“+IScenarioService.class.getName()”的服务引用);
    返回false;
    }
    其他的
    {
    LOGGER.info(“服务:+servRefs.length”);
    boolean assign=servRefs[0]。isAssignableTo(context.getBundle(),IScenarioService.class.getName());
    LOGGER.info(“分配:”+Assign);
    scenarioService=(IScenarioService)context.getService(servRefs[0]);
    }
    }
    捕获(无效语法异常e)
    {
    LOGGER.error(例如getMessage());
    e、 printStackTrace();
    返回false;
    }
    
我的日志显示找到了1个服务,该服务“可分配”,但在线
scenarioService=(IScenarioService)context.getService(servRefs[0])我明白了

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

我尝试通过Blueprint注入服务,访问上面的代码,更改pom的maven bundle插件中的导入/导出关系,以及将所有接口存储在bundle“A”中并导出相关包。。。。都没有用

有人能给我一个答案让我摆脱痛苦吗?
谢谢。

我假设问题在于提供服务的捆绑包和使用服务的捆绑包看到的是IScenarioService类的不同实例。这通常是由于将接口嵌入两个捆绑包中,或者有两个捆绑包提供接口

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

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

例如,请参见。模型包包含服务接口,持久性包包含服务提供者,ui包包含服务使用者

正如您在代码中看到的,maven bundle插件只在父级中设置,并且在各个bundle中几乎不需要额外的OSGi设置


因此,正如您所见,如果您做得正确,提供和使用服务是非常简单的。

太棒了,感谢您花时间如此快速地做出响应。现在,我已经将嵌入式jar本身转换成了一个包,并导出了interfaces包,该包由两个相应的包(服务提供者和服务用户)导入—这现在可以按预期工作。对于任何其他用户,请注意,我还向pom捆绑包配置中添加了“无”行,这有助于解决部署服务提供商捆绑包时的依赖性问题-不确定这是否确实是应该如何使用的,但节省了很多时间-不确定obrRepository NONE是否真的解决了此问题。它只告诉maven bundle插件不要将bundle元数据保存在maven repo中。你确定这个问题没有被其他东西解决吗?谢谢Christian;你说得对,删除此线路并重新部署仍然有效。谢谢