4

When debugging, why a service from my bundle was not imported by other bundles, I've noticed, I've declared wrong version of commons-io (1.4 instead of 2.4). However, after invoking mvn clean and then mnv install I've noticed, that the old version is still referred! Additionally, the version of org.apache.httpcomponents is not declared!

My effective POM looks like following:

....

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.3</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.4</version>
  <scope>compile</scope>
</dependency>

...

    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-bundle-plugin</artifactId>
      <version>3.3.0</version>
      <extensions>true</extensions>
      <executions>
        <execution>
          <id>bundle-manifest</id>
          <phase>process-classes</phase>
          <goals>
            <goal>manifest</goal>
          </goals>
          <configuration>
            <manifestLocation>META-INF</manifestLocation>
            <instructions>
              <_noee>true</_noee>
              <_removeheaders>Import-Service,Export-Service</_removeheaders>
            </instructions>
          </configuration>
        </execution>
      </executions>
      <configuration>
        <manifestLocation>META-INF</manifestLocation>
        <instructions>
          <_noee>true</_noee>
          <_removeheaders>Import-Service,Export-Service</_removeheaders>
        </instructions>
      </configuration>
    </plugin>

What I see in MANIFEST.MF is:

Import-Package: .....................,org.apache.com mons.io;version="[1.4,2)",org.apache.http,org.apache.http.client,org.ap ache.http.client.methods,org.apache.http.entity,org.apache.http.impl.cl ient,org.osgi.service.blueprint;version="[1.0.0,2.0.0)",........

Now the behaviour of maven-bundle-plugin seems random to me. Sometimes the version is placed in manifest, sometimes not, sometimes the packages from the same bundle are placed in Import-Package section, sometimes not... And now the old package version is placed, as if it was cached somewhere...

Is there any method to force maven-bundle-plugin to correctly resolve package versions from maven dependencies? I don't want to write versions manually because it's what we are using Maven for...

A probably important note: The class that uses those imports is declared in Blueprint descriptor, and it is how the maven-bundle-plugin finds out the package in the first line, it looks like the plugin has some issues with Blueprint support...

9ilsdx 9rvj 0lo
  • 7,955
  • 10
  • 38
  • 77

1 Answers1

2

The maven bundle plugin uses some rules to create the Import-Package statements.

  • It will only create imports for the packages that are actually used
  • It will look into blueprint and create imports for some of the definitions there. For example if you declare a bean class= then it will import the package
  • If you export a package then the maven-bundle-plugin will also create an import for it. This allows OSGi to choose the best import. This is a good thing for the stability of your system.
  • The versions for imports are taken from the Export-Package statements of the bundles you refer in maven. If the maven dependency is not a bundle then it will take the version from the maven version

In your case the import for org.apache.commons.io is still in the [1.4,2) range as the commons-io 2.4 bundle exports this package with version 1.4.9999. I guess this is done to make commons-io 2.4 compatible with bundles that were compiled against commons-io 1.4.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • Wow, it looks like there is a big mess here. Actually the httpcomponents that I have as dependency are no bundle artifacts, so I compile against them, but import httpcomponents-osgi in feature descriptor. It seems also that I was debugging against false thing because I wanted to check why my service is not imported by other bundle, but it seems that the service is imported, only the karaf console doesn't show that. – 9ilsdx 9rvj 0lo Aug 24 '17 at 07:57
  • Yes .. If possible you should use the OSGi bundle as a dependency as it will create the correct imports. When I add dependencies for an OSGi project I always take a look into the Manifest of the dependency. It often saves you from some surprises. In blueprint you also need to be careful when refactoring as the blueprint xml is normally not refactored. So I often had the effect that my old package name was still imported and it took I while to find the reason :-) – Christian Schneider Aug 24 '17 at 08:06