在普通的java中拆分包

时间:2009-01-02 07:44:14

标签: java osgi packages

OSGi在拆分包时遇到问题,即同一个包但托管在多个包中。

是否有任何边缘情况,拆分包可能会在普通java(没有OSGi)中造成问题?

好奇。

5 个答案:

答案 0 :(得分:14)

拆分包来自

拆分包(在OSGi中)在使用清单标头Require-Bundle时发生(我相信,在Eclipse的清单中)。 Require-Bundle命名用于搜索类的其他包(如果包不是Import)。搜索在捆绑包自己的类路径被搜索之前发生。这允许从多个包(可能是不同的jar)的导出中加载单个包的类。

OSGi规范(4.1)第3.13节描述了Require-Bundle并且有一长串(意外)使用此标题的结果(不应该弃用此标题吗?),其中一部分专门用于拆分包。其中一些后果是奇怪的(而不是特定于OSGi),但如果您理解一件事,大多数都会被避免:

  • 如果 (在包中)由多个捆绑包提供,那么您就遇到了麻烦。

如果包装件是不相交的,那么一切都应该没问题,除非您可能没有可见类,并且如果从“错误”部分查看,包可见性成员可能看起来是私有的拆分包。

[当然这太简单了 - 可以安装多个版本的软件包 - 但从应用程序的角度来看任何时候来自软件包的所有类都应来自单个模块。

'标准Java'

会发生什么

在标准Java中,没有花哨的类加载器,你有一个类路径,并且要加载的类的jar(和目录)的搜索顺序是固定的和明确定义的:你得到的就是你得到的。 (但是,我们放弃了可管理的模块化。)

当然,您可以使用拆分包 - 实际上它很常见 - 这表明模块化程度很低。症状可能是模糊的编译/构建时错误,但是在多个类实现的情况下(一个在一个类路径中覆盖其余的),它通常会产生模糊的运行时行为,因为语义略有不同。

如果您 幸运 ,您最终会查看错误的代码 - 而不会意识到这一点 - 并且问自己“但是怎么可能那个< / em>?“”如果您 不幸 ,您正在查看正确的代码并询问完全相同的事情 - 因为其他因素会产生意想不到的答案。< / p>

这与旧的数据库格言并不完全不同:“如果你在两个地方录制同一条信息,很快它就不会再相同了”。我们的问题是“很快”通常不会很快。

答案 1 :(得分:5)

对于OSGi,不同包中的包不同,不管它们的名称如何,因为每个包都使用自己的类加载器。确保封装捆绑包不是问题,而是一个特征。

所以在普通的Java中,这通常不是问题,直到你开始使用一些使用类加载器的框架。这通常是组件加载时的情况。

答案 2 :(得分:3)

在罐子上拆分包装可能不是一个好主意。我建议密封罐子里的所有包装(把"Sealed: true"放在清单的主要部分)。密封包装不能在罐子之间分开。

对于OSGi,具有相同包名但具有不同类加载器的类被视为它们位于不同的包中。

答案 3 :(得分:3)

如果您在同一个包中有类,而某些类在签名的JAR中,而其他类不在。

,则会出现令人讨厌的运行时错误。

答案 4 :(得分:0)

你问的是因为有问题的包是你的,而不是第三方代码吗?

一个简单的例子是将服务和持久层作为单独的OSGi包的Web应用程序。持久性接口必须由两个bundle共享。

如果我正确地解释了您的问题,那么解决方案是创建一个包含共享接口的密封JAR并使其成为两个捆绑包的一部分吗?

我不是故意试图劫持线程。我要求澄清以及那些可能在OSGi上做得比我更多的人的更好的见解。