Good way to “wrap” jars for OSGi with Maven

2020-06-04 11:32发布

问题:

I was looking at the PAX tools on OPS4J for example: this one and I thought I'd found a nice way to:

  • Specify an artifact
  • Create an assembled jar (jar that contains all dependencies) from that jar and its transitive dependencies
  • Wrap it with BND to create an OSGi bundle

It turns out, that I was wrong - it doesn't appear that the PAX stuff does this. (RTFM, right? :) )

But this got me wondering: is there something out there that does what I'm asking?

I've thought maybe I could do this by creating a simple POM and using the maven-bundle-plugin but this seems like it might be a bit cumbersome for what I'm asking.

NOTE: I get that embedding and assembling jar's is not really "the OSGi way" - so I wouldn't do this unless I really felt it useful. For example - Spring.

Thanks in advance.

回答1:

You have to maintain a local POM to get this done. There's not a utility that will take in a library/jar and spit out the appropriate OSGi MANIFEST in a jar. ServiceMix, along with Spring, have a lot of things already bundled up that you can use as examples. Two such examples I suggest looking at are:

  • commons-io - simple library wrapper
  • OpenJPA - wraps the main jar and brings in the dependencies with it


回答2:

I wrote a maven archetype that will help you wrap a jar as an OSGI bundle.

Let's say you want to wrap commons-collections version 3.2.1

First get the archetype and install it

git clone git://github.com/HallwayTech/maven-wrap-jar-archetype.git 
cd maven-wrap-jar-archetype
maven install

Then use the archetype to start your project.

mvn archetype:create \
  -DarchetypeGroupId=com.hallwaytech.osgi \
  -DarchetypeArtifactId=wrap-jar \
  -DarchetypeVersion=1.0-SNAPSHOT \
  -DgroupId=commons-collections \
  -DartifactId=commons-collections \
  -Dversion=3.2.1

cd commons-collections

mvn install

To deploy to a Apache Sling inside of Felix run:

mvn install -Pdeploy


回答3:

We do something similar to what you are describing. For example, we have an internal version of Apache QPid. It comes as 6 jars (client, core, common, backports, etc) which you would rarely use individually. We have one POM with BND which takes all the jars, and makes one uber-osgi-jar from them.

Steps:

  1. Declare your dependencies (we have the jars, so we declared them as system deps.)
  2. Import build plugin maven-bundle-plugin (2.1.0)
  3. Set correct instructions for export, private and import packages
  4. Execution of 'wrap' goal at 'package' phase


回答4:

I tried The accepted answer and Erik's answer. Erik's suggestion was simple and worked right out the box. Although, it seemed to produce a huge MANIFEST in my case, and then I recalled the p2-maven-plugin. This last method works very well in a large number of cases. If the artifact you need is already bundle, or its dependencies are bundles it simply puts them into the repo it builds. If not, it will run maven-bundle-plugin with some default settings (or you can configure the settings you need). Very cool!

I especially like that it grabs the transitive dependencies and takes care of those too. If you don't need the repo, but are just after the wrapped bundle, it is a simple matter to go cherry pick it out of target/repository/plugins folder.



标签: java maven osgi