【发布时间】:2010-09-29 04:57:48
【问题描述】:
OSGi 存在拆分包的问题,即同一个包但托管在多个包中。
在纯 java(没有 OSGi)中是否存在拆分包可能会造成问题的边缘情况?
只是好奇。
【问题讨论】:
OSGi 存在拆分包的问题,即同一个包但托管在多个包中。
在纯 java(没有 OSGi)中是否存在拆分包可能会造成问题的边缘情况?
只是好奇。
【问题讨论】:
对于不同包中的 OSGi 包是不同的,不管它们的名字是什么,因为每个包都使用自己的类加载器。确保捆绑包的封装不是问题,而是一个特性。
所以在纯 Java 中这通常不是问题,直到您开始使用一些使用类加载器的框架。这通常是加载组件时的情况。
【讨论】:
跨 jar 拆分包可能不是一个好主意。我建议密封罐子中的所有包(将"Sealed: true" 放在清单的主要部分)。密封的包装不能在罐子之间分开。
对于 OSGi,具有相同包名但类加载器不同的类被视为位于不同的包中。
【讨论】:
你问是因为有问题的包是你的,而不是第三方代码?
一个简单的例子是一个 web 应用程序,它具有作为单独的 OSGi 包的服务和持久层。持久性接口必须由两个包共享。
如果我正确解释了您的问题,解决方案是创建一个包含共享接口的密封 JAR 并使其成为两个捆绑包的一部分吗?
我并不是要尝试劫持线程。我要求那些迄今为止可能比我在 OSGi 方面做得更多的人进行澄清并提供更好的见解。
【讨论】:
如果您在同一个包中有类,而有些类在签名的 JAR 中,而另一些则不在,则会出现严重的运行时错误。
【讨论】:
拆分包(在 OSGi 中)在使用清单头 Require-Bundle 时发生(我相信,在 Eclipse 的清单中)。 Require-Bundle 命名其他用于搜索类的包(如果包不是Imported)。搜索发生在搜索捆绑包自己的类路径之前。这允许从多个包(可能是不同的jar)的导出中加载单个包的类。
OSGi 规范 (4.1) 的第 3.13 节描述了Require-Bundle,并有一长串使用此标头的(意外)后果(是否应弃用此标头?),其中一节专门用于拆分包。其中一些后果是奇怪的(而且是特定于 OSGi 的),但如果你了解一件事,大多数后果是可以避免的:
如果包片段是不相交的,那么一切都应该很好,除了你可能没有到处都有类 visible 并且如果从“错误”部分查看包可见性成员可能看起来是私有的拆分包。
[当然这太简单了——可以安装多个版本的包——但是从应用程序的角度来看在任何时候一个包中的所有类都应该来自一个模块。]
在标准 Java 中,没有花哨的类加载器,您有一个类路径,并且为要加载的类搜索 jar(和目录)的顺序是固定且明确定义的:所得到的就是所得到的。 (但是,我们放弃了可管理的模块化。)
当然,您可以拆分包(实际上这很常见),这表明模块性较差。症状可能是模糊的编译/构建时错误,但在多个类实现的情况下(一个覆盖单个类路径中的其余部分),由于语义略有不同,它通常会产生模糊的运行时行为.
如果你是幸运,你最终会在没有意识到的情况下查看错误的代码并问自己“但是这怎么可能那样?" 这与古老的数据库格言并不完全不同:“如果您在两个地方记录相同的信息,很快它就不再一样了”。我们的问题是“很快”通常不够快。
如果您不走运,您正在查看正确的代码并提出完全相同的问题——因为其他东西会产生意想不到的答案。 p>
【讨论】: