2012-02-15 193 views
7

我现在开始使用OSGi,iPOJO和iPOJO注解,并尝试构建一个简单的组件以在Felix中部署。不幸的是,我陷入了各种需要几小时才能解决的问题,或者在浪费时间之后我甚至无法解决的各种问题,如下所示:Maven构建OSGi时出现的问题,包括依赖关系

我想使用我们使用Maven构建的OSGi包中的现有库。该图书馆目前不是“OSGI-ified”,我们在中期内不打算这样做。正因为如此,我想包括这个库及其所有的捆绑依赖,使用...:

<Embed-Dependency>*</Embed-Dependency> 
<Embed-Transitive>true</Embed-Transitive> 

什么我现在,是OSGi的组件以下pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>foo</groupId> 
    <artifactId>samplecomponent</artifactId> 
    <packaging>bundle</packaging> 
    <version>0.0.1-SNAPSHOT</version> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <compilerArgument>-Xlint:all</compilerArgument> 
        <showWarnings>true</showWarnings> 
        <source>1.6</source> 
        <target>1.6</target> 
        <compilerArguments> 
         <encoding>UTF-8</encoding> 
        </compilerArguments> 
        <showDeprecation>true</showDeprecation> 
        <verbose>true</verbose> 
        <encoding>UTF-8</encoding> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.felix</groupId> 
       <artifactId>maven-bundle-plugin</artifactId> 
       <extensions>true</extensions> 
       <version>2.3.6</version> 
       <configuration> 
        <instructions> 
         <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> 
         <Embed-Dependency>*</Embed-Dependency> 
         <Embed-Transitive>true</Embed-Transitive> 
         <Embed-Directory>lib</Embed-Directory> 
         <Export-Package>*</Export-Package> 
         <_exportcontents>*</_exportcontents> 
        </instructions> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.felix</groupId> 
       <artifactId>maven-ipojo-plugin</artifactId> 
       <version>1.6.0</version> 
       <executions> 
        <execution> 
         <goals> 
          <goal>ipojo-bundle</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
    <dependencies> 
     <dependency> 
      <groupId>org.apache.felix</groupId> 
      <artifactId>org.apache.felix.ipojo.annotations</artifactId> 
      <version>1.8.0</version> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>foo</groupId> 
      <artifactId>mylibrary</artifactId> 
      <version>1.2.3</version> 
      <scope>compile</scope> 
     </dependency> 
    </dependencies> 
</project> 

束jar文件是建立没有任何问题,但部署和Apache的菲利克斯开始包的时候,我得到以下错误:

g! install file:/…/samplecomponent-0.0.1-SNAPSHOT.jar 
Bundle ID: 8 
g! start 8 
org.osgi.framework.BundleException: Unresolved constraint in bundle samplecomponent [8]: Unable to resolve 8.0: missing requirement [8.0] osgi.wiring.package; (osgi.wiring.package=com.sun.jdmk.comm) 

我已经设置了日志级别到最高verbos不幸的是,没有更多的信息。当我删除mylibrary时,该软件包将毫无问题地启动。

任何建议表示赞赏!

回答

9

显然,该库使用com.sun.jdmk.comm,它并未从框架包中公开。您可以检查this question,如果你真的需要它,或者投入额外的指示,从进口排除,

<Import-Package>!com.sun.jdmk.comm, *</Import-Package> 
+3

谢谢你,这是一般的好指针。但是,在添加排除之后,弹出了更多未解决的依赖关系。我现在所做的是将相关性设置为“可选”: ' *; resolution:= optional' 现在我按预期工作:) – qqilihq 2012-02-15 13:18:32

+0

嗯,好看到你的问题已经解决了,但是'resolution:= optional'只能在遇到严重问题时使用:这样做会破坏OSGi解析机制,因为你将_every_ import标记为可选项。我更喜欢'!com.sun。*,*'之类的东西。 – 2012-02-15 13:27:40

+0

好的,我将在未来记住这一点,感谢您的警告。但在上面的例子中,问题是,新的未解决的依赖关系出现在各种不同的命名空间中,造成一个巨大的排除列表。 – qqilihq 2012-02-15 13:32:56

4

如果你结束了一个巨大的排除列表,你应该把它看作一个标志的东西不适合你的构建过程和包。

如果是我,我会做的第一件事是打开你的包并查看它包含的类,以及它导出的包。我怀疑你有一个非常大的包,这意味着你的包的依赖将会非常广泛。这意味着你失去了OSGi的很多模块化优势,并且它也会导致很多实际问题。

任何时候你声明一个包是可选的,你会说'我很高兴接受这个包中类的ClassDefNotFoundExceptions。'对于你的代码,你可能知道一个包是否真的是可选的,但要猜测第三方使用的包是可选的,这是相当棘手的。当然,这就是为什么预捆绑的罐子更方便,但我意识到这对你没什么帮助。 :)

通过嵌入第三方库,你在做的是捆绑它,但以一种不可重复使用的方式。 (另一个区别是,它将与嵌入包共享一个类加载器,例如,如果第三方库试图通过反射加载你的类,那么它可以使事情变得更好)。由于你在依赖方面存在问题,我倾向于加入一个包装第三方jar的构建步骤,以便您可以清楚地看到哪些类和依赖关系与您的代码相关,以及哪些属于这个额外的jar。

我会看的另一件事是你的出口包= *子句。这将导出类路径中的每个包,这意味着所有这些包都内置到您的jar中。你也可以得到他们所有的包装进口。你可怜的软件包变成了一个完整的应用程序,而不是你期望的精益OSGi模块。你应该限制你的出口到最低限度(你想保持你的内部私人,你肯定不想分享其他人的内脏)。

-

企业OSGi的行动:http://www.manning.com/cummins

+0

感谢您的澄清。我已经将“出口包裹”缩小到必要的范围。我没有完全理解的是你的建议“[...]加入一个包装第三方jar的构建步骤,这样你就可以清楚地看到哪些类和依赖关系与你的代码相关,以及哪些属于这个额外的jar。 “ - 你能详细解释一下吗? – qqilihq 2012-02-15 17:15:50

+0

有几种方法可以做到这一点,但大多数使用maven bundle插件在封面bnd下使用的相同机制。 您可以下载bnd作为命令行工具,然后使用可选的bnd文件调用'bnd wrap [yourjar]',以改进包名称,导入和导出等内容。或者,你可以使用maven来做到这一点(谷歌'maven捆绑包的目标')。 这些应该都会给你带来OSGi元数据的jar版本,很快就会给你带来很大的麻烦。然后你可以看看里面的内容,确认你只从jar中拖出了类,然后检查包导入是否合理。 – 2012-02-15 19:01:07

+0

霍莉,对于迟到的回复感到抱歉,并感谢您的提示。非常感激! – qqilihq 2012-03-06 16:49:27