apache / netbeans-mavenutils-nbm-maven-plugin

Apache NetBeans Maven Utils parent pom
https://netbeans.apache.org/
Apache License 2.0
13 stars 27 forks source link

nbm-maven-plugin doesn't manage specification version in the same way than Netbeans for OSGi dependencies #178

Closed YannLeCorse closed 2 months ago

YannLeCorse commented 2 months ago

How to reproduce

I created a sample netbeans application and a sample module based on Maven. On the module, I simply added the following dependency

    <dependency>
      <groupId>org.apache.servicemix.bundles</groupId>
      <artifactId>org.apache.servicemix.bundles.spring-context</artifactId>
      <version>5.3.28_1</version>
    </dependency>

This is an OSGi artefacts where the Manifest declares Bundle-Version: 5.3.28.1. Version format is important for the issue. Then compiled and ran the suite but as you can see on the following screenshot, it's not able to start. Screenshot 2024-07-11 at 18 35 29

Sample project

nbm-issue-sample-project-module.zip

Issue

When the nbm-maven-plugin generates the manifest of the module, it uses the Maven version of dependencies. With the dependency above, it creates something like

OpenIDE-Module-Module-Dependencies: org.netbeans.api.annotations.common/
 1 > 1.49, org.apache.servicemix.bundles.spring_context > 5.3.28.1

When the Netbeans application starts, Netbeans reads the Manifest of the OSGi dependency and considers only 3 numbers for the specification version (5.3.28). This happens here Then it tries to compare it with the requested version (5.3.28.1). As the requested version doesn't match the specification version generated from the OSGi manifest, the module could not be loaded.

IMO, the issue is coming from the nbm-maven-plugin because it generates a manifest that can't be managed properly with the current Netbeans specification version logic. Thus I think we could address it here to ensure that the produced manifest is in correct shape for Netbeans.

How I'd like to address it

The plugin already has a AdaptNbVersion class to process the version and format it. I'd like to enhance this class to add the following method adapted from Netbeans code and use it at the end of the current adaptVersion process to ensure we always produce a major.minor.micro version format in the generated Manifest

    private static String computeSpecificationVersion(String v) {
        int pos = -1;
        for (int i = 0; i < 3; i++) {
            pos = v.indexOf('.', pos + 1);
            if (pos == -1) {
                return v;
            }
        }
        return v.substring(0, pos);
    }

If needed, we can make that optional by adding a property on the goal but from my understanding as soon as we have a dependency version with more than 3 numbers, it will fail at startup so I'd have enforce this and not expose a new property.

If the approach is acceptable from your perspective, I'll create/submit the PR so please let me know your throughs.

Cheers, Yann