jamesward / osgi-version-maven-plugin

1 stars 2 forks source link

Create whole manifest instead of only osgi version #3

Closed Sandared closed 6 years ago

Sandared commented 6 years ago

As mentioned in #2 it is probably more sensible to create the whole osgi manifest information within a plugin. I've added this functionality and cleaned up the code a little bit.

The plugin test ist currently failing, but I don't know why (don't know enough about maven). Maybe you can have a look at this?

If this plugins works as intended then the only thing to add to the POM is

<plugin>
    <groupId>biz.aQute.bnd</groupId>
    <artifactId>bnd-maven-plugin</artifactId>
    <configuration>
        <bnd>
        <![CDATA[
            ${manifest.osgi}
        ]]>
       </bnd>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>bnd-process</goal>
            </goals>
        </execution>
    </executions>
</plugin>
jamesward commented 6 years ago

Instead of going this route, it might be cleaner to use org.apache.felix:maven-bundle-plugin but I'm not sure how it deals with maven deps. https://blog.stackleader.com/osgi/2016/05/27/comparing-maven-plugins-for-osgi.html

WDYT?

Sandared commented 6 years ago

I think that would make almost no difference to us. We do have to calculate the Require-/Provide-Capability header anyway. ( long explanation at the end) We also still need to translate the version of Maven into an OSGi compatible format, I think.

I personally would prefer the bnd-maven-plugin, because 1) it is developed by the guys who also develop bnd itself, which is used by both plugins under the hood. 2) it generates plain old jars and not bundles, which needs to be configured extra in the maven-bundle-plugin as I understand it. 3) I don't know how to influence the Manifest generation in the maven-bundle-plugin to include our generated Provide-/Require-Capability

But this is just my personal preference ;)

Regarding dependencies: The way dependencies are defined in OSGi is different from the way they are defined in Maven.

In OSGi a bundle A imports packages from other bundles. As those packages could be provided by different other bundles (e.g., bundle B or C), A is not tightly coupled to the specific implementation of C or B, which therefore could be exchanged.

In Maven a bundle has a dependency to another bundle and is therefore tightly coupled to the implementations defined by the dependencies section in the pom.

Because of this I think none of the plugins translates Maven dependencies into OSGi dependencies, so we still need to come up with our own mechanism to translate the maven dependencies defined by webjars bundles into something a OSGi resolver can understand.

The OSGi resolver works by taking a set of required bundles (those you would like to run in your application) and then calculating a set of bundles that you need to include in order to have a working application. This is done via the defined required and provided capabilites of each bundle as defined by the Manifest.

Therefore, we define for each webjars bundle a capability with value = and use those in the Provide-/Require-Capability headers to define dependencies. The dependencies defined in Maven are translated into this format, so that the resolver automatically resolves these dependencies whenever a webjars bundle is part of a set of initial bundles to be resolved.

Sandared commented 6 years ago

@jamesward : Which way would you prefer? Or which way is better for webjars?

zhsc commented 6 years ago

I'll add my 2 cents. The bnd-maven-plugin is developed by the authors of bnd, the tool which underlies both options. The maven-bundle-plugin is possibly more used but only due to historical reasons since originally created by the felix developers to bridge the gap (my view of the history). I believe the first will probably be more frequently maintained if that helps your decision. I've used both just fine.

Regarding the C/D model I think this is the correct way to go. Here's some more info if you're not familiar: https://bnd.bndtools.org/chapters/220-contracts.html https://blog.osgi.org/2015/12/using-requirements-and-capabilities.html?m=1

I think the main thing to define would be the contract format. That would be the namespace (i.e. webjars.resource?) and probably a version attribute.

Then people will be able to declare a requires-capability in their projects and resolve the required bundle.

People could get by if the had to just directly depend on an artifact, but this will make this more future proof.

As long as there's some way to retrieve the resources (ideally via some service implementing an interface) things should work just fine.

zhsc commented 6 years ago

It seems one of the main objectives is to auto generate the "requires" directives in this project. Are there that many dependencies for a given webjar that simply listing them is too cumbersome?

You might be able to include your generated content with an <_include> tag. I believe it takes a file name however. http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html#using-an-existing-manifestmf-file

And I stand regarding the bnd-maven-plugin I stand corrected as it appears to be sunset https://github.com/bndtools/bnd/issues/629

Sandared commented 6 years ago

Regarding sunset of bnd-maven-plugin: Maybe we should ask the maintainers, as the last comment on this issue is 4 years old? If they still plan to stop working on the bnd-maven-plugin then we should switch to the maven-bundle-plugin.

Regarding Requirements: I think we should not use Version as type for the version, because then it would be treated as a semantic version by the resolver and I doubt that any of the JavaScript libraries adhere to such a strict versioning scheme. The current contract looks like this:

A requirement for such a resource could then be expressed by annotating a package (or class) with a @Requirement annotation. As all webjars by then should have defined their dependencies a resolver would be able to find all transitive dependencies starting from the one that is directly required by the package/class.

Regarding manually listing requirements: I think that most webjars do not have that many dependencies, but there are many webjars out there, so you still would have to add the requirements for each webjar that defines dependencies. This process is errorprone (after all we're just humans ;) ) and also adds an additional hurdle for people who just want to contribute a new webjar (at least for me the syntax of osgi requirements was not that intuitive at first sight)

Sandared commented 6 years ago

One more thing regarding sunset of the bnd-maven-plugin: I don't think they waant to stop working on this plugin.

1) the referenced issue is closed 2) The official tutorials for OSGi newbies have been reworked over the last year and now all are based upon the maven plugin.

zhsc commented 6 years ago

You're right on all points. The sunset issue appears to have just been a temporary frustration at the time. The plugin has been being actively maintained. https://github.com/bndtools/bnd/blob/master/maven/bnd-maven-plugin

So it sounds like this issue is just waiting for a blessing.

For the record if you did have to go the maven-bundle-plugin route you could probably generate a temp file in target and include via the <_include> directive. But what you have seems like its working fine.

Only other hack I can think of is maybe some bnd macro magic but that would be a stretch and I have no basis for its feasibility at this point.

Anyways, thanks for the work on this. Sorry for any confusion I might have created.

Sandared commented 6 years ago

@jamesward do you need anything else so that we could advance on this topic?

Sandared commented 6 years ago

@jamesward I've fixed the errors of my previous pull request and this plugin now should automatically generate all the necessary osgi information from the information available in maven.

jamesward commented 6 years ago

Thanks! I've deployed this. So let's give it a try!

Sandared commented 6 years ago

Is there anything else we have to do now? e.g., PRs with an updated pom for each webjar? Or will this be done automatically?

jamesward commented 6 years ago

Can you send a PR to the WebJars we are testing with?

Sandared commented 6 years ago

That would be polymer, but the most current version on the webjars website seems not to be this repository but a bower github webjar. I don't know how I can send a PR for such a webjar. Can you kindly point me to the right repository?

jamesward commented 6 years ago

I thought we were doing some testing with jquery or something?

Sandared commented 6 years ago

Originally I wanted to help the guys at Vaadin to solve their OSGi problems as they rely on webjars and webjars weren't OSGi bundles. They need at least Polymer to be an OSGi bundle. Therefore, I wanted to test this on Polymer :) But we also can start with JQuery if that's better for you

WDYT?

Sandared commented 6 years ago

@jamesward do have any preferences regarding the repositories to test with the new plugin?

Sandared commented 6 years ago

@jamesward would you prefer a pull request for jquery? Or would the polymer lib be ok for you? IT would be nice to make progress on this topic :)

jamesward commented 6 years ago

Sorry for the delay! I'll respond on #4.