我试图了解OSGI包中Bundle-Classpath的预期用例.
以下是我的理解,请帮助我理解这是否正确.
假设我正在创建一个OSGI捆绑包,该捆绑包将部署在其他捆绑包的生态系统中.我正在处理的捆绑包需要一些其他捆绑包,但它们不会在这个生态系统中加载/导出,而且我无法控制生态系统的输出.在这种情况下,我可以将这些包放在某个目录(比如'lib')中,这些目录成为我的捆绑包的一部分.这些包也应该从Bundle-Classpath引用,因此可以加载它们.
Nei*_*ett 35
Bundle-ClassPath 用于在我们的bundle中包含依赖项,以便我们的bundle可以独立部署.
我们来举个例子吧.假设我的包中的代码使用了库,例如Google Guava.打包我有两种选择:
只需使用我自己的代码创建我的包.该bundle现在将具有Import-Package声明对Guava的依赖的语句,并且任何想要将我的bundle部署到他的应用程序中的人也必须部署Guava.
或者,我可以在我的包中包含番石榴的副本,并从我的Bundle-ClassPath.凡我部署包可以部署只是我的包,而不必担心从哪里获取番石榴.实际上,我的bundle中存在Guava是一个实现细节,而部署者甚至不需要知道我正在使用它.
这两种选择之间的选择是权衡.选项2的优势在于我的捆绑包更易于部署,因为它是独立的 - 它所需的一切都在其中.另一方面,我的捆绑包比它需要的要大得多,如果很多其他捆绑包也嵌入了他们自己的番石榴副本,这可能会成为一个问题.
选项2的一个更严重的问题是库的所有依赖关系现在也成为我的依赖关系.实际上,Guava是一个罕见的Java库示例,它没有自己的依赖...但许多其他Java库拖入了一个巨大的传递依赖树.如果你使用这种方法,比如Hibernate,那么你自己的bundle也会有那么大的依赖集.这变得非常难看,很快.
所以,你应该小心不要过度使用Bundle-ClassPath/ Embed-Dependency.您应该只考虑使用它,如果依赖项是(a)小,没有传递依赖项,并且(b)您的bundle使用库作为内部实现细节,即它不是您的公共API的一部分.
UPDATE
我忘了回答关于出口的第二个问题.答案是否定的,你放在你身上的任何"捆绑"的出口Bundle-ClassPath都不会成为你自己捆绑的出口.事实上,我们提出的JAR Bundle-ClassPath根本不被视为捆绑,它们只是JAR.
您可以选择导出来自JAR内的包,Bundle-ClassPath但必须在您自己的包的MANIFEST.MF中执行此操作.
该标头最常见的用例是外部库的打包。假设您有一些库foo.jar,并且想要在包中使用它的类。
你把罐子放进你的包里,就像这样,
/
com/company/Activator.class
foo.jar
META-INF/MANIFEST.MF
Run Code Online (Sandbox Code Playgroud)
在您的清单中,您现在可以使用
Bundle-ClassPath: foo.jar,.
Run Code Online (Sandbox Code Playgroud)
请记住在类路径中包含.,否则您将无法在包中找到这些类。
当类位于 上时Bundle-ClassPath,您可以像任何其他类一样使用它们:在代码中使用它们,或导出它们。