我已经断断续续地使用 ServiceMix 几年了,但仍然未能成功地在我的包之间共享服务实现 - 由于使用了代理实现,它总是会导致 ClassCastException。
我有两个 bundle 和一个嵌入式 jar。
- 嵌入式 jar 包含我的服务类实现的接口(interface)。
- 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 cannot be cast to xx.x.xx.IScenarioService
我尝试通过 Blueprint 注入(inject)服务,按照上面的代码进行访问,更改 pom 的 maven-bundle-plugin 中的导入/导出关系,以及将所有接口(interface)存储在 Bundle 'A' 中并导出相关的包....都无济于事。
有人可以提供答案让我摆脱痛苦吗? 谢谢。
最佳答案
我认为问题在于提供服务的包和使用该服务的包看到 IScenarioService 类的不同实例。这通常是由于将接口(interface)嵌入到两个 bundle 中或有两个 bundle 提供接口(interface)而导致的。
避免这种情况的最简单方法是将接口(interface)包放在导出该包的第三个包中,并在服务提供者和服务使用者包中导入该包。
当您使用默认值时,maven 捆绑插件会自动执行此操作。
例如,请参阅 this tutorial 。模型包包含服务接口(interface),持久性包包含服务提供者,ui 包包含服务使用者。
正如您在代码中看到的,maven 包插件仅在父包中设置,并且几乎不需要在各个包中进行额外的 OSGi 设置。
如您所见,如果操作正确,提供和使用服务会非常简单。
关于java - 如何在不出现 ClassCastException 的情况下在另一个 OSGi 包中公开一个 OSGi 包中的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44195984/