19

我试图了解 OSGI 包中 Bundle-Classpath 的预期用例。

这是我的理解,请帮助我理解这是否正确。

假设我正在创建一个 OSGI 包,它将部署在其他包的生态系统中。我正在处理的捆绑包需要一些其他捆绑包,但它们不会在这个生态系统中加载/导出,我无法控制生态系统导出的内容。在这种情况下,我可以将这些包放在某个目录(比如“lib”)中,该目录将成为我的包的一部分。这些包也应该从 Bundle-Classpath 中引用,以便可以加载它们。

  • 这是 Bundle-Classpath 的正确用例吗?
  • 这些额外的包是否也会加载到 OSGI 容器中,并且由它们导出的包是否可用于其他包?
4

3 回答 3

43

Bundle-ClassPath旨在将依赖项包含在我们的包中,以便我们的包可以独立部署。

让我们举个例子。假设我的包中的代码使用了一个库,例如 Google Guava。我有两种打包我的捆绑包的选择:

  1. 只需创建我的包,其中只有我自己的代码。该包现在将具有Import-Package声明对 Guava 的依赖关系的语句,任何想要将我的包部署到他的应用程序中的人也必须部署 Guava。

  2. 或者,我可以在我的包中包含 Guava 的副本,并从我的Bundle-ClassPath. 部署我的包的人可以部署我的包,而无需担心从哪里获取 Guava。事实上,我的 bundle 中 Guava 的存在是一个实现细节,部署者甚至不需要知道我正在使用它。

这两个选项之间的选择是一种权衡。选项 2 的优点是我的包更容易部署,因为它是独立的——它需要的一切都在其中。另一方面,我的包比它需要的大得多,如果许多其他包也嵌入了他们自己的番石榴副本,这可能会成为一个问题。

选项 2 的一个更严重的问题是库的所有依赖项现在也成为我的依赖项。实际上,Guava 是一个罕见的没有自身依赖的 Java 库示例……但许多其他 Java 库拖入了一个巨大的传递依赖树。如果您将这种方法与 Hibernate 一起使用,那么您自己的 bundle 也将具有那么大的依赖集。这变得非常难看,很快。

所以,你应该小心不要过度使用Bundle-ClassPath/ Embed-Dependency。只有在依赖项很小且没有传递依赖项的情况下,您才应该考虑使用它,并且 (b) 您的包使用该库作为内部实现细节,即它不是您的公共 API 的一部分。

更新

我忘了回答你关于出口的第二个问题。答案是否定的,您放置的任何“捆绑包”的出口Bundle-ClassPath都不会成为您自己捆绑包的出口。事实上,我们放置的 JARBundle-ClassPath根本不被视为捆绑包,它们只是 JAR。

您可以选择导出来自您的 JAR 中的包,Bundle-ClassPath但您必须在您自己的包的 MANIFEST.MF 中执行此操作。

于 2013-06-05T11:43:59.867 回答
4

此标头最常见的用例是外部库的打包。假设您有一些 library foo.jar,并且想在您的包中使用它的类。

你像这样把罐子放进你的包裹里,

/
  com/company/Activator.class
  foo.jar
  META-INF/MANIFEST.MF

在您的清单中,您现在可以使用

Bundle-ClassPath: foo.jar,.

请记住.在类路径中包含 ,否则您将无法在包中找到类。

当类在 上时Bundle-ClassPath,您可以像使用任何其他类一样使用它们:在您的代码中使用它们,或导出它们。

于 2013-06-05T09:45:51.423 回答
2

我想你可能有点离题了。

Bundle-Classpath 是一个有序的、以逗号分隔的相对捆绑 JAR 文件位置列表,用于搜索类和资源请求。

这意味着当某个包类需要同一个包中的另一个类时,将搜索包含包的整个包类路径以找到该类。

来自OSGI in Action

让我们考虑一个具体的案例。想象一个具有以下结构的包(JAR 文件):

src/a/A.class
src2/b/B.class
src3/c/C.class

如果您想要a.A,b.B并且c.C彼此可用,则必须定义src,src2src3与捆绑类路径有关。这意味着您必须在清单文件中添加以下行:

Bundle-ClassPath: src,src2,src3
于 2013-06-05T08:30:06.913 回答