OSGI 包中 Bundle-Classpath 的预期用例是啥
Posted
技术标签:
【中文标题】OSGI 包中 Bundle-Classpath 的预期用例是啥【英文标题】:What is the intended use case for Bundle-Classpath in OSGI bundlesOSGI 包中 Bundle-Classpath 的预期用例是什么 【发布时间】:2013-05-31 19:10:46 【问题描述】:我正在尝试了解 OSGI 包中 Bundle-Classpath 的预期用例。
这是我的理解,如果正确,请帮助我理解。
假设我正在创建一个 OSGI 包,该包将部署在其他包的生态系统中。我正在处理的捆绑包需要一些其他捆绑包,但它们没有在这个生态系统中加载/导出,我无法控制生态系统导出的内容。在这种情况下,我可以将这些包放在某个目录(比如“lib”)中,该目录将成为我的包的一部分。这些包也应该从 Bundle-Classpath 中引用,以便可以加载它们。
这是 Bundle-Classpath 的正确用例吗? 这些额外的包是否也会加载到 OSGI 容器中,并且由它们导出的包是否可用于其他包?【问题讨论】:
【参考方案1】:Bundle-ClassPath
旨在将依赖项包含在我们的包中,以便我们的包可以独立部署。
让我们举个例子。假设我的包中的代码使用了一个库,例如谷歌番石榴。我有两种打包打包方式的选择:
只需创建我的包,其中只有我自己的代码。该包现在将具有声明对 Guava 的依赖关系的 Import-Package
语句,任何想要将我的包部署到他的应用程序中的人也必须部署 Guava。
或者,我可以在我的包中包含 Guava 的副本,并从我的 Bundle-ClassPath
中引用它。部署我的包的任何人都可以只部署我的包,而无需担心从哪里获取 Guava。事实上,我的 bundle 中 Guava 的存在只是一个实现细节,部署者甚至不需要知道我在使用它。
这两个选项之间的选择是一种权衡。选项 2 的优点是我的包更容易部署,因为它是独立的——它需要的一切都在其中。另一方面,我的包比它需要的要大得多,如果许多其他包也嵌入了他们自己的 Guava 副本,这可能会成为一个问题。
选项 2 的一个更严重的问题是库的所有依赖项现在也都变成了 my 依赖项。实际上,Guava 是一个罕见的没有自身依赖的 Java 库示例……但许多其他 Java 库拖入了一个巨大的传递依赖树。如果您将这种方法与 Hibernate 一起使用,那么您自己的 bundle 也将具有那么大的依赖集。这变得非常丑陋,非常快。
所以,你应该小心不要过度使用Bundle-ClassPath
/Embed-Dependency
。仅当依赖项 (a) 很小且没有传递依赖项,并且 (b) 您的包使用该库作为内部实现细节时,您才应该考虑使用它,即它不是您的公共 API 的一部分。
更新
我忘了回答你关于出口的第二个问题。答案是否定的,你放在Bundle-ClassPath
上的任何“包”的导出都不会成为你自己包的导出。事实上,我们放在Bundle-ClassPath
上的 JAR 根本不被视为捆绑包,它们只是 JAR。
您可以选择导出来自 Bundle-ClassPath
上 JAR 中的包,但您必须在自己的包的 MANIFEST.MF 中执行此操作。
【讨论】:
非常感谢!只是我正在寻找的解释:-) 谢谢!写的很棒。我想推荐一篇中等文章。 :) 谢谢,在被困在一个问题上几个小时后,这救了我!【参考方案2】:此标头最常见的用例是外部库的打包。假设您有一些库 foo.jar
,并希望在您的包中使用它的类。
你像这样把罐子放进你的包里,
/
com/company/Activator.class
foo.jar
META-INF/MANIFEST.MF
在你的清单中,你现在可以使用
Bundle-ClassPath: foo.jar,.
记得在类路径中包含.
,否则您将无法在包中找到这些类。
当类在Bundle-ClassPath
上时,您可以像使用任何其他类一样使用它们:在您的代码中使用它们,或导出它们。
【讨论】:
当我将一个 jar(非 osgi)放在 Bundle-Classpath 上时,我是否必须将它导入的类包含到我的 Import-Package 语句中? 否:这些类的处理方式与您的包中的任何其他类完全相同。 谢谢,那我想一定是 Maven 捆绑插件迫使我导入 jar 使用的类 嗯,不确定。尝试使用生成的包的实际布局、清单和您使用的 Maven 语句来更新您的问题。 看起来 Maven Bundle 插件确实需要导入 jar 中的类,即使它不是 OSGI jar。我将深入挖掘并更新我的问题......谢谢!【参考方案3】:我觉得你可能有点离题了。
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
、src2
和src3
定义为与捆绑类路径有关。这意味着您必须在清单文件中添加以下行:
Bundle-ClassPath: src,src2,src3
【讨论】:
以上是关于OSGI 包中 Bundle-Classpath 的预期用例是啥的主要内容,如果未能解决你的问题,请参考以下文章
OSGi 包中的 Websphere 8.5 + CXF。是不是可以?
如何使用 Maven 将第 3 方 OSGi 捆绑包添加到部署包中?