Maven 2 如何将多个OSGi捆绑包与BND/Maven BND插件合并?

Maven 2 如何将多个OSGi捆绑包与BND/Maven BND插件合并?,maven-2,osgi,Maven 2,Osgi,我在应用程序中使用了一些现成的OSGi捆绑包,希望将它们与其他尚未兼容OSGi的包一起重新打包到新的捆绑包中 EclipseLink就是一个很好的例子,它作为几个OSGi捆绑包提供,其中大多数是可选的,具体取决于您想要做什么。我想挑选那些与我相关的包,添加数据库驱动程序(例如MySQl JDBC连接器),并将它们重新打包到一个更易于部署的新包中 我正在使用ApacheFelix中的maven bundle插件。我在没有源代码的情况下建立了一个新的Maven项目,添加了四个eclipselink和

我在应用程序中使用了一些现成的OSGi捆绑包,希望将它们与其他尚未兼容OSGi的包一起重新打包到新的捆绑包中

EclipseLink就是一个很好的例子,它作为几个OSGi捆绑包提供,其中大多数是可选的,具体取决于您想要做什么。我想挑选那些与我相关的包,添加数据库驱动程序(例如MySQl JDBC连接器),并将它们重新打包到一个更易于部署的新包中

我正在使用ApacheFelix中的maven bundle插件。我在没有源代码的情况下建立了一个新的Maven项目,添加了四个eclipselink和mysql连接器作为依赖项,并尝试了以下操作:

  • 使用
    说明将所有依赖项包含在一个捆绑包中。问题:当插件重写清单时,eclipselink包(例如javax.mail.internet)中的可选依赖项成为必需的。最初的bundle在清单中包含“resolution=optional”,因此在没有任何限制的情况下工作良好
  • 使用插件的
    manifest
    目标和一个带有依赖项的
    jar
    程序集,但这给了我基本相同的结果,只是需要更多的工作
  • 使用了插件的
    bundleall
    目标,这不是我想要的,因为它再次创建了单独的bundle。更糟糕的是,因为现在这些包中没有依赖项
我将在Struts2中面临类似的问题。我不会对这件事着迷,只需要使用一大堆单独的第三方包,但如果我能把它们打包得更整齐,我真的很想这样做。我知道OSGi的一个要点是模块化,所以创建大的捆绑包有点失败,但我觉得如果你的模块是紧密耦合的,你最好把它们放在一个捆绑包中


当然,我可以手动调整清单,但我绝对不想这样做。

正如omerkudat所说,这可能不是一个鼓励的好做法,但你有你的理由,这是一种可以进行穷人合并的方法

假设您自己处理OSGi清单,您只需要在打包阶段之前将所有类从bundle和jar中获取到target/classes目录

您可以使用依赖插件的解包依赖项或解包目标来实现这一点。如果您想处理所有项目依赖项(或遵循特定命名模式或特定groupId的项目依赖项),我会使用解包依赖项;如果您想对要解包的工件进行精细控制(以牺牲冗长的POM为代价),我会使用解包目标。在我的例子中,我将假设解包。每个解包都输出到项目的outputDirectory(即目标/类)

注意,这将按下载顺序覆盖每个包中的重复工件,因此清单将相互碰撞。为了确保您的工件得到正确管理,我将把解包目标绑定到早期阶段,以便您的src/main/resources被复制到解包内容之上,而不是被覆盖。在下面的示例中,此阶段是生成资源,因此它将在本地编译之后发生。如果需要覆盖任何类,请使用早期阶段解压依赖项,例如生成源

下面的示例将junit-3.8.1和commons io 1.4的内容(只是我声明的前两个依赖项)解压到目标/类中,然后再将项目的资源复制到目标/类中。请注意,这些版本是在“我的依赖项”部分中定义的。如果尚未将bundle/jar声明为依赖项,那么还需要在artifactItem中声明版本

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>unpack</id>
      <phase>generate-resources</phase>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <overWrite>false</overWrite>
            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
          </artifactItem>
          <artifactItem>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <overWrite>false</overWrite>
            <outputDirectory>${project.build.outputDirectory}</outputDirectory>
          </artifactItem>
        </artifactItems>
        <overWriteReleases>false</overWriteReleases>
        <overWriteSnapshots>true</overWriteSnapshots>
      </configuration>
    </execution>
  </executions>
</plugin>

org.apache.maven.plugins
maven依赖插件
打开
产生资源
打开
朱尼特
朱尼特
假的
${project.build.outputDirectory}
公地io
公地io
假的
${project.build.outputDirectory}
假的
真的

为了澄清这一点,您想将一组OSGi捆绑包和其他JAR的类、资源和清单内容合并为一个?您还需要从非OSGi JAR中公开类型吗?这不违背OSGi的一般原则吗?为什么不将非bundle jar(同样,使用bnd和maven)作为适当的bundle依赖项而不是嵌入式依赖项使用呢。基本上,你把所有东西都转换成一个捆绑包。@Rich Seller:是的,没错。实际上,我需要公开的包比原来的包少得多,而且我通常只需要非OSGi jar中的一个包。例如,如果我将eclipselink和我的db驱动程序打包成一个包,那么实际上只需要导出org.eclipse.persistence.jpa,其他一切都将发生在包中。@omerkudat:我知道,正如我在上面所写的那样。然而,即使您正在使用OSGi使特定项目中的所有内容都模块化,您也可能希望用一些模块化来换取更紧凑、更少混乱的包装。如果您不打算更改从eclipselink使用的功能集,那么就不需要拥有所有单独的捆绑包。将它们放在一个单独的模块中,然后更恰当地反映应用程序的实际模块性,因此更容易理解和维护。嗯,好的,这可能会起作用。谢谢不太漂亮,但我想这正是我想要的。如果需要捆绑所有依赖项,可以使用解包依赖项目标()。这涉及到更少丑陋的配置,但它仍然是一个黑客