Osgi 如何处理来自Bundle类路径上JAR的导入包条目?

Osgi 如何处理来自Bundle类路径上JAR的导入包条目?,osgi,osgi-bundle,maven-bundle-plugin,Osgi,Osgi Bundle,Maven Bundle Plugin,我在包类路径上放了几个罐子。下一行显示了my pom.xml中的条目,它使用Felix插件为bundle创建manigest.mf <Bundle-ClassPath>.,lib/com.springsource.org.h2-1.0.71.jar,lib/com.springsource.org.apache.lucene-2.3.2.jar,lib/com.springsource.org.apache.lucene.search-2.3.2.jar</Bundle-Cla

我在包类路径上放了几个罐子。下一行显示了my pom.xml中的条目,它使用Felix插件为bundle创建manigest.mf

<Bundle-ClassPath>.,lib/com.springsource.org.h2-1.0.71.jar,lib/com.springsource.org.apache.lucene-2.3.2.jar,lib/com.springsource.org.apache.lucene.search-2.3.2.jar</Bundle-ClassPath>
所有这些错误都来自com.springsource.org.h2-1.0.71.jar,所有这些包都导入到该jar的清单中

我无法理解:

  • 如果这些包已经在com.springsource.org.h2-1.0.71.jar的MANIFEST>MF中导入,为什么Maven bundle插件会抱怨
  • 为什么问题只来自com.springsource.org.h2-1.0.71.jar?我试着删除那个特定的jar,构建过程很顺利,尽管com.springsource.org.apache.lucene.search-2.3.2.jar的MANIFEST.MF中还有几个导入包条目
关于第二点,我做了一些调查,我觉得有一种模式。com.springsource.org.apache.lucene.search-2.3.2.jar在其清单中指定的所有导入都由com.springsource.org.apache.lucene-2.3.2.jar满足,这也在Bundle类路径上指定

错误消息中未列出com.springsource.org.h2-1.0.71.jar中com.springsource.org.apache.lucene-2.3.2.jar(位于捆绑包类路径上)满足的依赖项,但是,捆绑包类路径上jar不满足的依赖项将在错误消息中列出

不太清楚发生了什么。关于包类路径上指定的jar文件,有什么规则?其清单的导入(即使在导入包中指定)元素是否必须在主项目的pom中列出?或者这是Maven bundle插件正在强制执行的吗?如果是后一种情况,有没有办法摆脱强制执行

关于包类路径上指定的jar文件的规则

maven bundle plugin(mbp)扫描bundle类路径上列出的文件,以确定所需的导入 每个指定的jar。因此,mbp将在main(您的主捆绑包)manifest.mf中添加所需的导入。 这意味着包应该由外部包导出。如果在外部找不到所需的包 然后,捆绑包将不会启动

您有两个解决方案可以使用应用程序所需的第三方JAR

  • 准备每个第三方jar的OSGi包。您可能会发现已经为创建了osgi捆绑包 spring存储库中的spring JAR和其他开源项目。只需完美地搜索它。你会找到的

  • 使用Bundle类路径: 这样,您就必须将您的第三方依赖项(以及“所有”它们的可传递依赖项)放在您的bundle中,并在bundle类路径头中指定每个jar。在这种情况下,mbp将分析bundle类路径jar,并试图弄乱导入包头。只需将自定义头包含在pom.xml中,即可避免这种情况。如果选择自定义导入包,请小心将其他(外部)捆绑包中所需的包正确地包含在导入包中


  • 拇指规则:如果你的应用程序在你的包类路径中发现了什么,那么它就不会去导入包。

    当你通过嵌入依赖项标签嵌入任何jar时,maven包插件也会分析该jar,并将引用的包添加到主机包导入包列表中。大多数情况下,此类软件包是可选的,具体取决于所使用的功能。例如,在您的用例中,H2 jar依赖于Lucene,这是用于特定功能的ServletAPI。如果您的使用场景不需要这些功能,那么您可以将这些包标记为可选的

    
    org.apache.felix
    maven捆绑插件
    2.3.5
    真的
    没有一个
    ${project.artifactId}
    ..
    氢
    org.osgi.service.jdbc.*;
    org.apache.lucene.*;
    javax.transaction.*;分辨率:=可选,
    *
    
    在上面的配置中,我们将这些包标记为可选的。主要问题是根据您的使用情况确定软件包列表

    一种快速而肮脏的方法是将所有导入标记为可选导入应作为最后手段使用。因为一些有效的导入将被标记为可选,OSGi fwk将无法检查它们

    
    *;分辨率:=可选
    

    还请注意,H2 jar是一个有效的OSGi包,因此您可以直接部署它。

    将包标记为可选包是危险的,除非使用这些包的代码确实设计为将这些包视为可选包。换句话说,如果代码最终尝试使用来自这样一个包的代码,您将得到一个异常。如果您真的不使用该代码,您还可以完全禁止导入,这样就省去了解析程序查找该包的麻烦。@MarcelOffermans我完全同意盲目地将包标记为可选是危险的。问题是,在包装第三方jar时,用户往往不知道哪些包是真正可选的。我通常采用的另一种方法是将此类包添加到动态导入列表中。但是,maven bundle插件不会扩展DynamicImport包指令的通配符,因此列出列表并不直接。插件不会扩展DynamicImport包的通配符,因为标头本身支持通配符,因此扩展它们是错误的。
    Unresolved references to [com.sun.tools.javac, javax.naming, javax.naming.spi, javax.servlet, javax.servlet.http, javax.sql, javax.transaction.xa]