Bnd-maven-plugin missing features compared to Felix maven-bundle-plugin

Based on discussion starting here FELIX-6708 upgrade bnd to 7.0.0 by paulrutter · Pull Request #322 · apache/felix-dev · GitHub . But since a closed PR is not the best place for this discussion, I propose to continue it here.

My goal is to determine the diff between the two plugins and if it makes sense to add some pieces to bnd-maven-plugin or to improve bnd’s documentation to describe some of the examples belows.

It started like this:

maven-bundle-plugin still has some features not supported by bnd-maven-plugin

I think most noteable is <Embed-Dependency> .

(one can potentially try to work around this by a combination of copy-dependecy and bnd instructions but thats really cumbersome if more than one jar is involved)

Then bnd-jar can only work when extension is on (and then mangles with default maven executions) instead of using it as a standalone execution, one can use bnd-process (if it not would be confused by the existing jar) with additional jar executions but again thats quite cumbersome and can give surprising results.

Last but not least, even though its a bit a style question, the usage of XML elements to represent the Instructions instead of an embedded CDATA or dedicated bnd.bnd file is often more “natural” to maven/non-osgi users.

<Embed-Dependency> is trivially simple in bnd-maven-plugin

bnd/maven-plugins/bnd-maven-plugin/src/it/test-wrapper-bundle/bnd/wrapper.bnd at b2deb7f91312a4d37f0504d8cfd904847ca028a2 · bndtools/bnd · GitHub

The embedding can take many forms.

In the case showed, the “maven dependency” osgi.annotation-*.jar is embedded into the lib/ directory (i.e. lib:=true) AND is appended to the Bundle-ClassPath header (which is created for you automatically with a base of . if not already specified so as not to break the bundle’s normal class loading structure).

You could embed in a flattened way using (i.e. the classes and packages are directly beside your own):

-includeresource: @osgi.annotation-*.jar

and so on… there are lots of possible things you can do like extracting certain files and whatnot!

is trivially simple in bnd-maven-plugin

one would think so, but if you

  1. don’t know it by name
  2. don’t check in the jar into your code repository

it instantly become incredibly hard. As you mentioned here

Sadly, there is no way to specify transitive inclusion natively in bnd

Also includeresource can not filter for scopes (as far as I know) and you have to know the name of the artifact as described here.

So yes that’s all doable but far from convenient to the not so experienced users.

Also please keep in mind this important portion of my answer:

but that’s really cumbersome if more than one jar is involved

so all these incredible easy example always ever seem to cover exactly one jar where it in fact becomes quite easy.

So to convince people that bnd-maven-plugin is a full replacement, I think the best would be to add docs that cover the examples mentioned here:

<!-- embed all compile and runtime scope dependencies -->
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>

<!-- embed any dependencies with artifactId junit and scope runtime -->
<Embed-Dependency>junit;scope=runtime</Embed-Dependency>

<!-- inline all non-pom dependencies, except those with scope runtime -->
<Embed-Dependency>*;scope=!runtime;type=!pom;inline=true</Embed-Dependency>

<!-- embed all compile and runtime scope dependencies, except those with artifactIds in the given list -->
<Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=!cli|lang|runtime|tidy|jsch</Embed-Dependency>

<!-- inline contents of selected folders from all dependencies -->
<Embed-Dependency>*;inline=images/**|icons/**</Embed-Dependency>

Fair, but these are incorrect assumptions:

don’t know it by name

You can use a regex which gets all dependencies? matching is a regex across the names of all artifacts… so just match all!

don’t check in the jar into your code repository

You don’t need to care where the jar is, only that maven will ultimately already have gotten it for you!

The rest may be arguably true, but this is widely used in very large projects with MANY jars (please, if you dare, look at this repo and search for -includeresource).

And it is using… maven-bundle-plugin :wink:

Don’t get me wrong its all possible for sure, it was just asked why people using it and I gave some examples, you should not assume that every maven user that wants to wrap a small (or medium) jar can afford to dive into the details of bnd instruction magic, those people only search for a fast way to archive their goal without much hassle and the plugin is offering that for them.

So if these one-liner examples above can be transformed into a one-liner bnd instruction (or better maven configuration option) it is fine and probably there is just a lack of let people know, if I look here:

bnd/maven-plugins/bnd-maven-plugin at master · bndtools/bnd · GitHub

I don’t find any good hint to archive things similar to felix-maven-plugin, (e.g. migration guide) nor how to archive the embedding in a similar way.

… for the record the repo does NOT use the maven-bundle-plugin (it’s a ant & gradle build.)

Just because a saved dependencies’ pom contains it does not mean it’s used (don’t ask why dependencies are stored in git…)

Had a quick look at Felix’s DependencyEmbedder which is used by <Embed-Dependency>

It seems that it is a tool to generate a bnd -includeresource instruction string.

The difference to -includeresource is, that this thing has Maven-knowledge - which bnd does not (I mean things like ‘scope’ which exist in the maven world). So I think it is quite well suited to stay in the maven world.

That being said, we could think about if bnd-maven-plugin should also have such a DependencyEmbedder option which resuses something like Felix’ DependencyEmbedder under the hood.
But in the end it is something like syntactical sugar - but if it makes things more convenient and mentally easier to digest, than it is a good thing.

Update: maybe syntactical sugar is not the best term: Maybe the syntax of Felix’ <Embed-Dependency> is less cryptic and more verbose / explicit / more readable. So it is also a little bit matter of taste. I personally find Felix’ syntax also a bit more easier to grasp since it uses clear words like ‘inline=true’ instead of the '@' which bnd -includeresource uses.

On that note, I want to outline a comment from bnd manual which mentions Felix maven-bundle-plugin:

I think this also highlights a key-difference:

  • bnd expects the user to be very explicit and select exactly the stuff you need
  • while Felix’ EmbeddedDependency on the other hand allows for selecting more broadly and include transitive dependencies (via scope etc) which is convenient. But this convenience comes with the danger mentioned in the hint in the bnd manual screenshot.

How does Felix maven-bundle-plugin handle the case where you use <Embed-Dependency> and also -includeresource in a plain-bnd section? Is this possible?
I am just thinking about cases where <Embed-Dependecy> does not support certain bnd features (e.g. the duplicate handling coming in 7.1.0)

I feel so old …

The OSGi philosophy is to have lots of small cohesive uncoupled components collaborating through services. Maven, well, is more “just get my classpath filled with every possible JAR any JAR that those JARs might potentially possibly need. And then some.”

Clearly the OSGi philosophy did not make it into mainstream despite all our efforts so trying to preach to the heathens is not so useful anymore :slight_smile: If they think they need this, lets go for it.