【发布时间】:2012-11-10 22:27:15
【问题描述】:
我熟悉Import-Package 和Export-Package,但这对我来说是新的。它有什么作用?
【问题讨论】:
我熟悉Import-Package 和Export-Package,但这对我来说是新的。它有什么作用?
【问题讨论】:
在 OSGi 容器中运行时它什么也不做。事实上,它甚至在 OSGi 规范中都没有提到(我检查了 R4)。
但是,它可以在.bnd 文件中指定以供 bnd 在构建时使用。如果是这样,它可用于确定捆绑包中的内容。
当 bnd 构建一个包时,它会自动确定哪些类需要进入包中。导出的包中的所有类都包括在内,并且它们(传递地)依赖的所有类也包括在内。这意味着如果一个类似乎没有被使用,那么它将不会包含在包中。但是,您可以使用 Private-Package 指令来告诉 bnd 将包的内容包含在包中,即使它似乎未使用。如果没有指定 Private-Package 指令,则由 bnd 自动生成。
Private-Package 的文档如下:
私人包
包含的方法与Export-Package 头文件相同,唯一不同的是,这些包没有被导出。此标头将被复制到清单中。如果未通过导出和私有包标头选择包,则导出优先。
Private-Package=com.*
【讨论】:
实际上 Private-Package 不仅仅是不导出包。如果 Private-Package 中指定的包没有在您自己的项目中定义并且没有在 Import-Package 中导入,那么它们会自动内联到您的 jar 中。所以这是一种包含非 OSGi 依赖项的简单方法。请注意,尽管内联很容易导致类路径问题。
【讨论】:
如果您知道什么是静态链接,那么您就了解 Private-Package。否则请继续阅读。
Private-Package 是 bnd 告诉您必须在 jar 中但未导出的包的方式。它不是一个 OSGi 标头,而是一个 bnd '指令'。
该指令定义了必须包含在 JAR 中的类路径(使用通配符)中的包。 bnd 的独特之处在于它根据规范填充 JAR,而不是像大多数构建工具那样填充某个目录。原因是除非“设计”模块并仔细考虑它们的布局,否则它们很少能提供模块化的好处。
通常 Private-Package 指定包含不应与其他包共享的类的包,即实现类。尽管通常它们来自使用 bnd 的相应项目,但从类路径上的任何其他 JAR 中获取它们是完全可以接受的。
一个用例是一个带有 utils 的库。将 util 库打包成一个包通常会对依赖关系造成严重破坏,因为 utils 往往依赖于许多不相关的东西;您使用一种微小的方法,突然间您拖入了 30Mb 的依赖项。 bnd 本身大量使用这个模型和 aQute.lib* 包,这个库中的包永远不应该被导出。这是捆绑包大小和“下载互联网”之间的权衡。 Eclipse 和 Apache Felix 的世界之间的差异是显而易见的。 Apache Felix 包通常是独立的,不需要各种支持和实用程序包,而 Eclipse 的包往往需要大量的管道包。我认为这种差异主要是由于 Eclipse 的 PDE 导致无法包含来自其他项目的包,除非您复制源代码,这当然是一个很大的禁忌。
在 C 世界中,他们有一种叫做静态链接的东西。链接程序后,将从库中检索任何未解决的问题并将其添加到目标中。在一定程度上 Private-Package 是同一个想法。实际上有一个标头 Conditional-Package 静态链接指定的包和它们传递依赖的任何东西(只要它们属于模式)。
最后 bnd 显示未在清单中的 Private-Package 标头中导出的扩展包。毕竟,清单应该描述内容......
如果您是作者,您可以使用 -removeheaders: Private-Package 删除标题(或在 maven 中使用 <_removeheaders>Private-Package
【讨论】: