如何处理来自Bundle-Classpath上的jar的Import-Package条目?

时间:2013-06-05 09:29:54

标签: osgi osgi-bundle maven-bundle-plugin

我在Bundle-Classpath上放了几个罐子。下面的行显示了我的pom.xml中的条目,该条目使用Felix插件为包创建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>

这些jar包含导入包的类,但从我所看到的,它们都有一个MANIFEST.MF,它有自己的(准确的)Import-Package语句列表。

但是,当我构建我的项目(使用Maven和bundle插件)时,它会报告错误,因为它无法解析对某些类的引用。特别是错误是:

Unresolved references to [com.sun.tools.javac, javax.naming, javax.naming.spi, javax.servlet, javax.servlet.http, javax.sql, javax.transaction.xa]

所有这些错误都来自com.springsource.org.h2-1.0.71.jar,所有这些包都是在那个jar的清单中导入的。

我无法理解:

  • 为什么Maven捆绑插件会抱怨,如果这些包已经在coms.pringsource.org.h2-1.0.71.jar的MANIFEST&gt; MF中导入
  • 为什么问题只来自com.springsource.org.h2-1.0.71.jar?我尝试删除那个特定的jar并且构建顺利进行,即使com.springsource.org.apache.lucene.search-2.3.2.jar在它的MANIFEST.MF中还有几个Import-Package条目?

关于第二点,我做了一些调查,我觉得有一种模式。 com.springsource.org.apache.lucene-2.3.2.jar对com.springsource.org.apache.lucene.search-2.3.2.jar在其清单中指定的所有导入都满意,这也是指定的在Bundle-Classpath上。

com.springsource.org.h2-1.0.71.jar的依赖关系由com.springsource.org.apache.lucene-2.3.2.jar(在Bundle-Classpath上)满足,是但是,未在错误消息中列出,错误消息中列出了Bundle-Classpath上的jar不满足的那些依赖项。

不太确定发生了什么。有关在Bundle-Classpath中指定的jar文件的规则是什么?他们的清单中的导入(即使它们在Import-Package中指定)是否必须列在主项目的pom中?或者这是Maven捆绑插件正在执行的东西?如果是后者,是否有办法摆脱强制执行?

2 个答案:

答案 0 :(得分:5)

当您通过Embed-Dependency标记嵌入任何jar时,maven-bundle-plugin也会分析该jar并将引用的包添加到主机包Import-Package列表中。大多数此类包是可选的,具体取决于所使用的功能。例如,在您的用例中,H2 jar依赖于Lucene,Servlet API用于某些功能。如果您的使用场景不需要这些功能,那么您可以将这些包标记为可选

<plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.3.5</version>
        <extensions>true</extensions>
        <configuration>
          <obrRepository>NONE</obrRepository>
          <instructions>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            ..
            <Embed-Dependency>
              h2
            </Embed-Dependency>
            <Import-Package>
              org.osgi.service.jdbc.*;
              org.apache.lucene.*;
              javax.transaction.*;resolution:=optional,
              *
            </Import-Package>
          </instructions>
        </configuration>
      </plugin>

在上面的配置中,我们将这些包标记为可选。主要问题是根据您的使用情况确定包裹清单

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

        <Import-Package>
          *;resolution:=optional
        </Import-Package>

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

答案 1 :(得分:2)

  

有关在Bundle-Classpath上指定的jar文件的规则吗?

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

您有两种解决方案可以使用您的应用程序所需的第三方jar。

  1. 准备每个第三方jar的OSGi包。您可能会发现已经为其创建了osgi包 Spring存储库here中的spring jar和其他开源项目。只需完全搜索它。你会发现它。

  2. 使用Bundle-classpath: 有了这个,你必须将你的第三方依赖项(和“所有”它们的传递依赖项)放在你的bundle中,并在Bundle-ClassPath头文件中指定每个jar。在这种情况下,mbp将分析bundle classpath jar并尝试弄乱你的import-package头。您可以通过在pom.xml中包含自定义标头来避免这种情况。如果您选择自定义导入程序包,请小心在导入程序包中包含其他(外部)程序包中所需的程序包。

  3. Thumb规则:如果您的应用在bundle-classpath中找到了某些内容,那么它就不会用于import-package。