【问题标题】:How can I merge multiple OSGi bundles with BND / Maven-BND-plugin?如何将多个 OSGi 捆绑包与 BND / Maven-BND-plugin 合并?
【发布时间】:2010-11-19 00:19:51
【问题描述】:

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

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

我正在使用 Apache Felix 的 maven-bundle-plugin。我建立了一个没有源代码的新Maven项目,添加了四个eclipselink和mysql连接器作为依赖项并尝试了以下内容:

  • 使用<Embed-Dependency><Embed-Transitive> 指令将所有依赖项包含在一个包中。问题:当插件重写清单时,需要来自 eclipselink 包的可选依赖项(例如 javax.mail.internet)。原始捆绑包在清单中包含“resolution=optional”,因此没有它也能正常工作。
  • 使用插件的manifest 目标和jar-with-dependencies 程序集,但这给了我基本相同的结果,只是需要更多的工作。
  • 使用了插件的bundleall 目标,这不是我想要的,因为它再次创建了单独的包。更糟糕的是,因为现在这些包中没有它们的依赖项。

我将面临 Struts 2 的类似问题。我不会对此过于执着,只是使用一大堆单独的第三方捆绑包,但如果我可以更整齐地打包它们,我真的很想。我知道 OSGi 的一个重点是模块化,因此创建大包会破坏这一点,但我觉得如果你的模块无论如何都是紧密耦合的,你不妨将它们放在一个包中。

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

【问题讨论】:

  • 澄清一下,您想将一组 OSGi 包和其他 jar 的类、资源和清单内容合并为一个吗?您是否还需要公开非 OSGi jar 中的类型?
  • 这不是违背OSGi的一般原则吗?为什么不 OSGify 非捆绑 jars(再次使用 bnd 和 maven)并将它们用作适当的捆绑依赖项而不是嵌入式依赖项。基本上,您将所有内容都转换为一个捆绑包。
  • @Rich Seller:是的,没错。实际上,与原始包相比,我需要公开的内容要少得多,而且我通常只需要来自非 OSGi jar 的一个包。例如,如果我将 eclipselink 和我的 db 驱动程序打包到一个包中,那实际上只需要导出 org.eclipse.persistence.jpa,其他一切都将在包中发生。
  • @omerkudat:我知道这一点,正如我在上面已经写过的。然而,即使您使用 OSGi 将所有内容模块化,在特定项目中,您也可能希望用一些模块化来换取更紧凑和更少混乱的包装。如果您不打算从 eclipselink 更改您正在使用的功能集,则无需拥有所有单独的捆绑包。将它们放在一个单独的中会更恰当地反映您的应用程序的实际模块化,因此更容易理解和维护。

标签: maven-2 osgi


【解决方案1】:

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

假设您自己处理 OSGi 清单,您只需要在 package 阶段之前将包和 jar 中的所有类放入 target/classes 目录。

您可以使用依赖插件的 unpack-dependencies 或 unpack 目标来执行此操作。如果您想处理所有项目依赖项(或遵循特定命名模式或特定 groupId 的项目依赖项),我将使用 unpack-dependencies;如果您想对要解包的工件进行精细控制(在冗长的 POM 的开销)。我将假设在我的示例中解包。每个解包都输出到项目的 outputDirectory(即目标/类)。

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

下面的示例将 junit-3.8.1 和 commons-io 1.4 的内容(只是我声明的前两个依赖项)解压缩到目标/类中,然后将项目的资源复制到目标/类中。请注意,版本是在我的依赖项部分中定义的。如果您没有将 bundles/jars 声明为依赖项,您还需要在 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>

【讨论】:

  • 嗯,好的,这可以工作。谢谢。不是很漂亮,但我想这就是我想要的。
  • 如果您需要捆绑所有依赖项,您可以使用 unpack-dependencies 目标 (maven.apache.org/plugins/maven-dependency-plugin/examples/…)。这涉及不那么丑陋的配置,但它仍然是一个 hack
猜你喜欢
  • 2011-03-06
  • 2020-05-11
  • 2012-08-31
  • 1970-01-01
  • 2013-01-03
  • 2017-03-02
  • 2016-10-03
  • 2016-09-21
  • 2020-03-02
相关资源
最近更新 更多