stempler / bnd-platform

Build OSGi bundles and Eclipse Update Sites from existing JARs, e.g. from Maven repositories (Plugin for Gradle)
Apache License 2.0
79 stars 30 forks source link

Merging one bundle, keeping other bundle separate #40

Closed qqilihq closed 7 years ago

qqilihq commented 7 years ago

Hi again,

I have a configuration which contains two dependencies, A and B. Each of them has a further tree of transitive dependencies behind it.

Due to OSGi issues I need to create a merged bundle which contains all the transitive dependencies of A. However, I do not want to add any dependencies from B into the merged bundle.

Unfortunately, I’ve found no way for a working merge configuration so far. Using the match filter I can only filter based on the current artifact ID or group, but not based on the “root” dependency. Adding A via bundle property to the merge configuration doesn’t work as well.

I tried separating A and B to two distinct features and simply doing a match { true }. But the merge would also merge dependencies present in the other feature (I thought, features would create a concept of an “isolated scope“ which is obviously not the case).

Simply listing all transitive dependencies of A in the match block would work, but it just seems ugly and I’ll run into issues when changing versions later.

Is there any nicer approach?

My explanation is probably rather abstract. Please let me know if it’s too hard to understand and I’ll happily construct a working example.

stempler commented 7 years ago

Generally the merge right now just checks all artifacts available if they should be included, based on the condition you provide in the closure.

The feature instruction serves only for the purpose to define which bundles should be included. It does not have any other effect.

In match you have the artifact, but you don't have any information there about what depends on this artifact. So if that information is not added there, I don't see an obvious way to handle that there with the current API.

One way to solve this would be to support this where the actual selection which artifacts are merged takes place. The configuration for the merge could probably be extended to add an option to include dependencies for a bundle.

Another way could be to do some preprocessing beforehand. Including all dependencies to a bundle also in one Jar sounds very much like what the Shadow Jar plugin would do. There you also have the option to rename packages which could help avoiding conflicts if you have these dependencies included somewhere else as well. So here would be the approach to create the Jar in another task and add the already merged Jar instead. If you let the bundles task depend on that task, it is ensured that the merged Jar is created early enough.

qqilihq commented 7 years ago

Thank you once more for your very helpful feedback, Simon!

I had a look at the Shadow plugin, which looked helpful at first glance. But unfortunately it currently does not support creating source bundles (at least out of the box), as highlighted in this issue. And having the sources at hand was one of the many reasons which made me switch from my own (half baked) bundling solution to bnd-platform.

What I did at the end, was splitting up my bnd-platform gradle project into three sub projects:

In the root’s build.grade I’ve defined a task to execute all the steps conveniently:

task create {
  dependsOn ':projectA:bundles'
  dependsOn ':projectB:bundles'
  dependsOn ':updatesite:updateSite'
}

This seems to work very fine so far, and I can entirely rely on the (awesome) bnd-platform plugin! In case of any improvement suggestions feel free to let me know!