如何将多个OSGi捆绑包与BND/Maven-BND-plugin合并? [英] How can I merge multiple OSGi bundles with BND / Maven-BND-plugin?
问题描述
我在应用程序中使用了一些现成的OSGi软件包,并希望将它们与尚不兼容OSGi的其他软件包重新打包到一个新的软件包中.
I'm using some off-the-shelf OSGi bundles in my application and would like to repackage them together with additional packages that are not yet OSGi compatible into a new bundle.
最重要的例子是EclipseLink,它可以作为多个OSGi捆绑软件提供,其中大多数是可选的,具体取决于您想要做什么.我想选择与我相关的那些捆绑软件,添加数据库驱动程序(例如MySQl JDBC连接器),然后将它们重新打包到一个易于部署的新捆绑软件中.
Case in point is EclipseLink, which is available as several OSGi bundles, most of which are optional, depending on what you want to do. I want to pick those bundles that are relevant for me, add database drivers (for example the MySQl JDBC connector) and repackage them into a new bundle that is easier to deploy.
我正在使用Apache Felix的maven-bundle-plugin.我建立了一个没有源代码的新Maven项目,添加了四个eclipselink和mysql连接器作为依赖项,并尝试了以下操作:
I'm using the maven-bundle-plugin from Apache Felix. I set up a new Maven project without source code, added the four eclipselink and the mysql connector as dependencies and tried the following:
- 使用
<Embed-Dependency>
和<Embed-Transitive>
指令将所有依赖项包含在一个包中.问题:插件重写清单时,需要eclipselink捆绑包中的可选依赖项(例如,javax.mail.internet).原始捆绑包在清单中包含"resolution = optional",因此可以很好地工作. - 使用插件的
manifest
目标和jar-with-dependencies
程序集,但这给了我基本相同的结果,只是需要更多的工作. - 使用了插件的
bundleall
目标,这不是我想要的目标,因为它再次创建了单独的包.更糟糕的是,因为现在这些捆绑包内部没有依赖项.
- use the
<Embed-Dependency>
and<Embed-Transitive>
instructions to include all dependencies in one bundle. Problem: Optional dependencies from the eclipselink bundles (for example, javax.mail.internet) become required as the plugin rewrites the manifest. The original bundles contain "resolution=optional" in the manifest and thus work well without. - use the
manifest
goal of the plugin and ajar-with-dependencies
assembly, but that gives me basically the same result, only with more work. - used the
bundleall
goal of the plugin, which is not quite what I want, because it creates separate bundles again. Even worse, because now these bundles don't have their dependencies inside.
我将在Struts 2中遇到类似的问题.我不会对此着迷,而只需要处理一大堆单独的第三方捆绑软件,但是如果我可以将它们打包得更整洁的话,我会真的很想我知道OSGi的重点是模块化,因此创建大型捆绑软件是一种失败,但是我认为,如果您的模块仍然紧密耦合,那么您最好将它们放到一个捆绑软件中.
I'm going to face similar issues with Struts 2. I'm not going to be obsessive about this, and just go with a whole bunch of separate third-party bundles, but if I can package them more neatly, I would really like to. I'm aware that a point of OSGi is modularity, so creating big bundles kind of defeats that, but I feel that if your modules are tightly coupled anyway, you might as well put them into a single bundle.
当然,我可以手动调整清单,但我绝对不愿意.
Of course, I could manually tweak the manifests, but I definitely don't want to.
推荐答案
正如omerkudat所说,这可能不是鼓励的好习惯,但是由于您的原因,这是您可以进行穷人合并的一种方式
As omerkudat says, this is probably not a good practice to encourage, but as you have your reasons, this is a way you could do a poor-man's merge.
假设您自己处理OSGi清单,则只需要在 package 阶段之前将所有捆绑包和jar中的类放入target/classes目录.
Assuming you are handling the OSGi manifest yourself, you only really need to get all the classes from the bundles and jars into the target/classes directory before the package phase.
您可以使用依赖插件的unpack-dependencies或unpack目标来执行此操作.如果要处理所有项目依赖项(或遵循特定命名模式或特定groupId的那些依赖项),则我要使用unpack-dependencies;如果要对要解压缩的工件进行精确控制,请使用unpack目标.冗长的POM的费用).在示例中,我将假定打开包装.每次解压缩都会输出到项目的outputDirectory(即目标/类).
You can do this with either of the dependency plugin's unpack-dependencies or unpack goals. I'd use the unpack-dependencies if you want to process all the project dependencies (or those following a certain naming patter or in a certain groupId) and the unpack goal if you want to have fine control over the artifacts to be unpacked (at the expense of a verbose POM). I'll assume unpack in my example. Each unpack is output to the project's outputDirectory (i.e. target/classes).
请注意,这将按照每个包的下载顺序覆盖每个程序包中的重复工件,因此清单将相互干扰.为了确保正确管理您的工件,我会将解压缩目标绑定到早期阶段,以便将您的src/main/resources复制到解压缩的内容之上,而不被覆盖.在此阶段下面的示例中, generate-resources ,因此将在本地编译后发生.如果您需要覆盖任何类,请使用较早的阶段来解压依赖项,例如 generate-sources
Note this will overwrite duplicate artifacts from each package in the order they're downloaded, so the manifests will be clobbering each other. To ensure your artifacts are managed correctly, I would bind the unpack goal to an early phase so that your src/main/resources are copied on top of the unpacked contents and not overwritten. In the sample below this phase is generate-resources, so it will happen after your local compile. If you need to overwrite any of the classes, use an earlier phase to unpack the dependencies such as generate-sources
下面的示例将junit-3.8.1和commons-io 1.4(只是我声明的前两个依赖项)的内容解压缩到目标/类中,然后再将项目的资源复制到其中.请注意,这些版本是在我的依赖项部分中定义的.如果尚未将bundle/jar声明为依赖项,则还需要在artifactItem中声明版本.
My sample below unpacks the contents of junit-3.8.1 and commons-io 1.4 (just the first two dependencies I had declarations for) into target/classes before the project's resources are copied there. Note that the versions are defined in my dependencies section. If you haven't got the bundles/jars declared as dependencies you'll need to declare the version in the artifactItem as well.
<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>
这篇关于如何将多个OSGi捆绑包与BND/Maven-BND-plugin合并?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!