根据bnd工作空间模型简介,存储库定义了一组精确的依赖项,不支持传递依赖项,因为它们往往会导致糟糕的OSGi系统。
当这是真的时,有人能提供更详细的解释吗(非常感谢使用具体的用例)?我想这主要与清单中正确的导入包列表有关。应如何处理可传递的依赖关系?有没有办法提供所有必需的进口产品?
这是否意味着只有maven的捆绑包开发(使用bnd-maven插件或maven捆绑包插件)更容易出错,因为maven确实支持可传递的依赖关系?在这种情况下,应如何处理可传递的依赖关系?
谢谢!
在OSGi中,捆绑包的创建和应用程序的组装是两件非常不同的事情。当使用maven创建捆绑包时,当然要使用可传递的依赖关系。maven捆绑插件或bnd-maven插件的结果是jar Manifest中的条目。它们定义了导入或导出包之类的内容。此结果不包含可传递的依赖项。这些bundle既可以用于工作空间模型,也可以用于maven模型。
应用程序集是一个不同的过程。在那里,您构建了一个如此庞大的存储库,其中列出了要安装的可能捆绑包。在工作区模型中,您列出了没有可传递依赖项的每个捆绑包。在基于maven的应用程序集中,您可以使用pom的依赖项来定义存储库。在那里使用了可传递的依赖关系。
传递依赖关系并不总是好的原因是捆绑包的依赖关系通常不是您希望在应用程序中使用的依赖关系。因此,maven模型有可能将有问题的捆绑包添加到存储库中。然后,这些依赖关系可能会减慢到要使用的实际捆绑包的解析速度,甚至导致无法工作的解析捆绑包。幸运的是,您可以通过使用通常的maven排除来排除一些可传递的依赖项来解决这个问题。
根据我个人的经验,传递捆绑包通常对应用程序组装非常有用,因为您不必手动列出所有依赖项。这些有问题的案子不太好解决。因此,我不同意不应该利用传递依赖关系。
主要原因是OSGi是可重用组件系统的规范。如果你试图用可传递的依赖项来做这件事,你会发现你在组装时遇到了问题:
- 版本冲突–组件A使用X的版本1,组件B使用X的版2。在Maven等可传递系统中,这些冲突通常会逐渐减少,但定时炸弹随时可能爆炸
- 环境依赖性–一些组件依赖于Windows,另一些则依赖于Linux。很难调和这些分歧
- 版本兼容性–通常组件可以一起工作,但它们的可传递依赖关系使其无法工作
为了解决这个问题,OSGi发明了服务模型。服务模型允许组件依赖API。一旦您依赖于API,您就不再有可传递的依赖关系,因为可传递依赖关系几乎都是关于实现依赖关系的。当然,对API有依赖性,但这变得更模糊了,因为API的消费者和API的提供者都依赖于此。这从根本上改变了依赖模型,使其变得更好,但很少有人能理解这一点。
也就是说,在服务模型中,责任在于服务API。您可以根据API进行编译,并且可以根据API编写大量测试用例。但是,您的组件不应该依赖于特定的实现。组件第一次看到实现应该是在运行时。
当然,这在开发的早期阶段就失去了一些便利。在像Maven这样的可传递模型中,应该开箱即用地编译,而在bnd中,您需要提前考虑您和组件的依赖关系。这很不方便,也让Maven用户很恼火,但要求组件在不同的环境中可重复使用。Maven倾向于将运行时锁定在通常不兼容的配置中,在OSGi中,您不希望运行时有任何不必要的限制来最大限度地提高组件的可重用性。
对于习惯于传递依赖关系的短期便利性的开发人员来说,对开发人员施加这种限制(没有实现依赖关系)通常太多了。然而,接受这种模型的开发人员很快就会发现,它在开发周期的后期开辟了一个可能性的前景,并减少了大量的维护。甚至我有时也会想跳过这种间接级别,但不知何故,即使是稍微复杂一点,我也会恢复,因为该模型在宏观级别上有很多优势。
我参与过许多复杂的系统,在几乎所有的情况下,当你杀死传递依赖警报器时,很多复杂性都会消失。